walk through the entire dep graph instead of just the root module

Adding support for `flag_alias` . Design https://docs.google.com/document/d/1yOvi4hVV7Ja32ocwVb4lsEUnijftk8nilXPncYm-BH8/edit?tab=t.0#heading=h.qn3unswby87l

Closes #27658.

PiperOrigin-RevId: 836843577
Change-Id: I83b22b3c7d4ff560821930389985ca061e8d11a2
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/InterimModule.java b/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/InterimModule.java
index 95d01f1..3abe48b 100644
--- a/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/InterimModule.java
+++ b/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/InterimModule.java
@@ -23,7 +23,6 @@
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
-import com.google.devtools.build.lib.cmdline.Label;
 import com.google.devtools.build.lib.cmdline.LabelSyntaxException;
 import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;
 import com.google.errorprone.annotations.CanIgnoreReturnValue;
@@ -157,8 +156,7 @@
     @CanIgnoreReturnValue
     public final Builder addFlagAlias(String nativeName, String starlarkLabel)
         throws LabelSyntaxException {
-      flagAliasesBuilder()
-          .put(nativeName, Label.parseCanonical(starlarkLabel).getUnambiguousCanonicalForm());
+      flagAliasesBuilder().put(nativeName, starlarkLabel);
       return this;
     }
 
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/ModuleFileGlobals.java b/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/ModuleFileGlobals.java
index 3d7d6db..7efc1de 100644
--- a/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/ModuleFileGlobals.java
+++ b/src/main/java/com/google/devtools/build/lib/bazel/bzlmod/ModuleFileGlobals.java
@@ -1203,8 +1203,11 @@
   public void flagAlias(String nativeName, String starlarkLabel, StarlarkThread thread)
       throws EvalException, LabelSyntaxException {
     ModuleThreadContext context = ModuleThreadContext.fromOrFail(thread, "flag_alias()");
+    String normalizedStarlarkLabel =
+        normalizeLabelString(context.getModuleBuilder(), starlarkLabel);
+
     // TODO: add input validation for stalark flag label
     context.setNonModuleCalled();
-    context.getModuleBuilder().addFlagAlias(nativeName, starlarkLabel);
+    context.getModuleBuilder().addFlagAlias(nativeName, normalizedStarlarkLabel);
   }
 }
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeExecutor.java b/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeExecutor.java
index 550e3ae..dd4021f 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeExecutor.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeExecutor.java
@@ -120,7 +120,6 @@
 import com.google.devtools.build.lib.analysis.producers.ConfiguredTargetAndDataProducer;
 import com.google.devtools.build.lib.analysis.starlark.StarlarkAttributeTransitionProvider;
 import com.google.devtools.build.lib.bazel.bzlmod.BazelDepGraphValue;
-import com.google.devtools.build.lib.bazel.bzlmod.ModuleKey;
 import com.google.devtools.build.lib.bazel.bzlmod.Version.ParseException;
 import com.google.devtools.build.lib.bazel.repository.RepoDefinitionFunction;
 import com.google.devtools.build.lib.bazel.repository.RepoDefinitionValue;
@@ -3297,12 +3296,7 @@
     EvaluationResult<BazelDepGraphValue> evalResult =
         evaluate(
             ImmutableList.of(BazelDepGraphValue.KEY), false, DEFAULT_THREAD_COUNT, eventHandler);
-    var bzlmodDepGraph = evalResult.get(BazelDepGraphValue.KEY).getDepGraph();
-    ImmutableMap<String, String> flagAliases = bzlmodDepGraph.get(ModuleKey.ROOT).getFlagAliases();
-    LinkedHashMap<String, String> aliasesMap = new LinkedHashMap<>();
-    if (flagAliases != null) {
-      aliasesMap.putAll(flagAliases);
-    }
+
     // TODO: b/453809359 - Remove special Python flag handling when Bazel 9+ can read Python flag
     // alias definitions straight fromrules_python's MODULE.bazel.
     com.google.devtools.build.lib.bazel.bzlmod.Version minBazelVersionForPythonAliases = null;
@@ -3316,16 +3310,27 @@
     } catch (ParseException e) {
       throw new IllegalStateException("Hard-coded rules_python version should always parse.", e);
     }
+
+    var bzlmodDepGraph = evalResult.get(BazelDepGraphValue.KEY).getDepGraph();
+    LinkedHashMap<String, String> aliasesMap = new LinkedHashMap<>();
     for (var module : bzlmodDepGraph.entrySet()) {
+      ImmutableMap<String, String> flagAliases = module.getValue().getFlagAliases();
+      aliasesMap.putAll(flagAliases);
+
       if (!module.getKey().name().equals("rules_python")) {
         continue;
       }
-      // Don't set flag aliases for old rules_python versions that start with "1.". But support
-      // aliases for versions like "0.0.0" which represent unreleased development repos.
-      if (module.getValue().getVersion().compareTo(minBazelVersionForPythonAliases) < 0
-          && module.getValue().getVersion().toString().startsWith("1.")) {
+
+      // Don't apply hard-coded aliases for python version < 1.6.100
+      // Don't apply hard-coded aliases for python version > 1.6.100 and rules_python uses
+      // MODULE.bazel aliases
+      boolean isAllowedVersion =
+          module.getValue().getVersion().compareTo(minBazelVersionForPythonAliases) > 0
+              || !module.getValue().getVersion().toString().startsWith("1.");
+      if (!isAllowedVersion || !module.getValue().getFlagAliases().isEmpty()) {
         continue;
       }
+
       if (ensurePyAliases) {
         // Add Python flags that haven't already been added by rules_python's MODULE.bazel.
         PY_FLAG_ALIASES.entrySet().stream()
@@ -3338,7 +3343,10 @@
             .filter(e -> !flagAliases.containsKey(e.getKey()))
             .forEach(e -> aliasesMap.put(e.getKey(), e.getValue()));
       }
+
+      return ImmutableMap.copyOf(aliasesMap);
     }
+
     return ImmutableMap.copyOf(aliasesMap);
   }
 
diff --git a/src/test/java/com/google/devtools/build/lib/bazel/bzlmod/ModuleFileFunctionTest.java b/src/test/java/com/google/devtools/build/lib/bazel/bzlmod/ModuleFileFunctionTest.java
index c898e90..4f361dc 100644
--- a/src/test/java/com/google/devtools/build/lib/bazel/bzlmod/ModuleFileFunctionTest.java
+++ b/src/test/java/com/google/devtools/build/lib/bazel/bzlmod/ModuleFileFunctionTest.java
@@ -233,8 +233,8 @@
                 .addToolchainsToRegister(ImmutableList.of("//my:toolchain", "//my:toolchain2"))
                 .addDep("bbb", createModuleKey("bbb", "1.0"))
                 .addDep("see", createModuleKey("ccc", "2.0"))
-                .addFlagAlias("native_flag1", "//my:starlark_label1")
-                .addFlagAlias("native_flag2", "//my:starlark_label2")
+                .addFlagAlias("native_flag1", "@aaa//my:starlark_label1")
+                .addFlagAlias("native_flag2", "@aaa//my:starlark_label2")
                 .addNodepDep(createModuleKey("ddd", "3.0"))
                 .build());
     assertThat(rootModuleFileValue.overrides())
diff --git a/src/test/shell/integration/starlark_configurations_external_workspaces_test.sh b/src/test/shell/integration/starlark_configurations_external_workspaces_test.sh
index 20b8453..416fed20e 100755
--- a/src/test/shell/integration/starlark_configurations_external_workspaces_test.sh
+++ b/src/test/shell/integration/starlark_configurations_external_workspaces_test.sh
@@ -258,13 +258,12 @@
   config_hash=$(cat cquery_output  | grep -o '([a-zA-Z0-9]\+)' | tr -d '()')
   # Get the configuration.
   bazel config $config_hash > "$TEST_log" 2>&1 || fail "Expected success"
-
   expect_log "//:my_flag: opt" "Expected Starlark flag to have user value"
   expect_log "compilation_mode: fastbuild" \
       "Expected native flag to have default value"
   # This is important because select() and transitions read --flag_alias to
   # correctly map aliases.
-  expect_log 'flag_alias: \[compilation_mode=@@//:my_flag, user_set=//:fake_flag\]' \
+  expect_log 'flag_alias: \[compilation_mode=@//:my_flag, user_set=//:fake_flag\]' \
       "Expected alias to be in --flag_alias option value list"
 }