From 6a8ddb7630ab5bf8446da2e4816b81557ff837c0 Mon Sep 17 00:00:00 2001 From: Googler <wyv@google.com> Date: Thu, 13 Oct 2022 09:55:07 -0700 Subject: [PATCH] Bzlmod: change main repo runfiles/execpath prefix to "_main" See code comment for more explanation. PiperOrigin-RevId: 480917215 Change-Id: I3a86d2bf45aeaa964cc8b101a6ecef0aab7238d7 --- .../google/devtools/build/lib/skyframe/BUILD | 3 ++ .../lib/skyframe/WorkspaceNameFunction.java | 19 +++++++++++++ .../skyframe/WorkspaceNameFunctionTest.java | 9 ++++++ src/test/shell/bazel/BUILD | 10 +++++-- src/test/shell/bazel/execroot_test.sh | 26 +++++++++++++++++ src/test/shell/bazel/runfiles_test.sh | 28 +++++++++++++++++++ 6 files changed, 93 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/BUILD b/src/main/java/com/google/devtools/build/lib/skyframe/BUILD index 583040e2a3c964..18c7e3f8d80085 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/BUILD +++ b/src/main/java/com/google/devtools/build/lib/skyframe/BUILD @@ -2898,11 +2898,14 @@ java_library( srcs = ["WorkspaceNameFunction.java"], deps = [ ":package_value", + ":precomputed_value", ":workspace_name_value", "//src/main/java/com/google/devtools/build/lib/cmdline", "//src/main/java/com/google/devtools/build/lib/packages", + "//src/main/java/com/google/devtools/build/lib/packages/semantics", "//src/main/java/com/google/devtools/build/skyframe", "//src/main/java/com/google/devtools/build/skyframe:skyframe-objects", + "//src/main/java/net/starlark/java/eval", "//third_party:jsr305", ], ) diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/WorkspaceNameFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/WorkspaceNameFunction.java index 27db9a71e89672..725d040f1540b6 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/WorkspaceNameFunction.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/WorkspaceNameFunction.java @@ -16,11 +16,13 @@ import com.google.devtools.build.lib.cmdline.LabelConstants; import com.google.devtools.build.lib.packages.BuildFileContainsErrorsException; import com.google.devtools.build.lib.packages.Package; +import com.google.devtools.build.lib.packages.semantics.BuildLanguageOptions; import com.google.devtools.build.skyframe.SkyFunction; import com.google.devtools.build.skyframe.SkyFunctionException; import com.google.devtools.build.skyframe.SkyKey; import com.google.devtools.build.skyframe.SkyValue; import javax.annotation.Nullable; +import net.starlark.java.eval.StarlarkSemantics; /** * {@link SkyFunction} for {@link WorkspaceNameValue}s. @@ -33,6 +35,23 @@ public class WorkspaceNameFunction implements SkyFunction { @Nullable public SkyValue compute(SkyKey skyKey, Environment env) throws InterruptedException, WorkspaceNameFunctionException { + StarlarkSemantics starlarkSemantics = PrecomputedValue.STARLARK_SEMANTICS.get(env); + if (starlarkSemantics == null) { + return null; + } + if (starlarkSemantics.getBool(BuildLanguageOptions.ENABLE_BZLMOD)) { + // When Bzlmod is enabled, we don't care what the "workspace name" specified in the WORKSPACE + // file is, and always use the static string "_main" instead. The workspace name returned by + // this SkyFunction is only used as the runfiles/execpath prefix for the main repo; for other + // repos, the canonical repo name is used. The canonical name of the main repo is the empty + // string, so we can't use that; instead, we just use a static string. + // + // "_main" was chosen because it's not a valid apparent repo name, which, coupled with the + // fact that no Bzlmod-generated canonical repo names are valid apparent repo names, means + // that a path passed to rlocation can go through repo mapping multiple times without any + // danger (i.e. going through repo mapping is idempotent). + return WorkspaceNameValue.withName("_main"); + } SkyKey externalPackageKey = PackageValue.key(LabelConstants.EXTERNAL_PACKAGE_IDENTIFIER); PackageValue externalPackageValue = (PackageValue) env.getValue(externalPackageKey); if (externalPackageValue == null) { diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/WorkspaceNameFunctionTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/WorkspaceNameFunctionTest.java index f4c60aea8c7a5c..04dcbc9f264f51 100644 --- a/src/test/java/com/google/devtools/build/lib/skyframe/WorkspaceNameFunctionTest.java +++ b/src/test/java/com/google/devtools/build/lib/skyframe/WorkspaceNameFunctionTest.java @@ -54,6 +54,15 @@ public void testNormal() throws Exception { .isEqualTo(WorkspaceNameValue.withName("good")); } + @Test + public void bzlmod() throws Exception { + setBuildLanguageOptions("--enable_bzlmod"); + scratch.overwriteFile("WORKSPACE", "workspace(name = 'good')"); + assertThatEvaluationResult(eval()) + .hasEntryThat(key) + .isEqualTo(WorkspaceNameValue.withName("_main")); + } + @Test public void testErrorInExternalPkg() throws Exception { reporter.removeHandler(failFastHandler); diff --git a/src/test/shell/bazel/BUILD b/src/test/shell/bazel/BUILD index 57b14aba2391b1..7fb9e679008127 100644 --- a/src/test/shell/bazel/BUILD +++ b/src/test/shell/bazel/BUILD @@ -832,7 +832,10 @@ sh_test( size = "medium", srcs = ["runfiles_test.sh"], data = [":test-deps"], - tags = ["no_windows"], + tags = [ + "no_windows", + "requires-network", + ], ) sh_test( @@ -1013,7 +1016,10 @@ sh_test( size = "medium", srcs = ["execroot_test.sh"], data = [":test-deps"], - tags = ["no_windows"], + tags = [ + "no_windows", + "requires-network", + ], ) sh_test( diff --git a/src/test/shell/bazel/execroot_test.sh b/src/test/shell/bazel/execroot_test.sh index 9c312e8635ba74..228718291476a7 100755 --- a/src/test/shell/bazel/execroot_test.sh +++ b/src/test/shell/bazel/execroot_test.sh @@ -44,6 +44,32 @@ EOF assert_contains "$(dirname $execroot)/${ws_name}/bazel-out" out } +function test_execroot_structure_with_bzlmod() { + cat > WORKSPACE <<EOF +workspace(name = "whatever_doesnt_matter") +EOF + cat > MODULE.bazel <<EOF +module(name="this_also_doesnt_matter") +EOF + + mkdir dir + cat > dir/BUILD <<'EOF' +genrule( + name = "use-srcs", + srcs = ["BUILD"], + cmd = "cp $< $@", + outs = ["used-srcs"], +) +EOF + + bazel build --enable_bzlmod -s //dir:use-srcs &> $TEST_log \ + || fail "expected success" + execroot="$(bazel info --enable_bzlmod execution_root)" + test -e "$execroot/../_main" + ls -l bazel-out | tee out + assert_contains "$(dirname $execroot)/_main/bazel-out" out +} + function test_sibling_repository_layout() { touch WORKSPACE diff --git a/src/test/shell/bazel/runfiles_test.sh b/src/test/shell/bazel/runfiles_test.sh index 99918ce0059a4a..04cfda90c80f7b 100755 --- a/src/test/shell/bazel/runfiles_test.sh +++ b/src/test/shell/bazel/runfiles_test.sh @@ -50,6 +50,34 @@ EOF [[ -x bazel-bin/foo/foo.runfiles/$name/foo/foo ]] || fail "No foo executable under $name" } +function test_runfiles_bzlmod() { + create_workspace_with_default_repos WORKSPACE "blorp_malorp" + cat > MODULE.bazel <<EOF +module(name="blep") +EOF + + mkdir foo + cat > foo/BUILD <<EOF +java_test( + name = "foo", + srcs = ["Noise.java"], + test_class = "Noise", +) +EOF + cat > foo/Noise.java <<EOF +public class Noise { + public static void main(String[] args) { + System.err.println(System.getenv("I'm a test.")); + } +} +EOF + + bazel build --enable_bzlmod //foo:foo >& $TEST_log || fail "Build failed" + [[ -d bazel-bin/foo/foo.runfiles/_main ]] || fail "_main runfiles directory not created" + [[ -d bazel-bin/foo/foo.runfiles/_main/foo ]] || fail "No foo subdirectory under _main" + [[ -x bazel-bin/foo/foo.runfiles/_main/foo/foo ]] || fail "No foo executable under _main" +} + function test_legacy_runfiles_change() { create_workspace_with_default_repos WORKSPACE foo cat >> WORKSPACE <<EOF