diff options
author | 2017-10-23 19:02:31 +0200 | |
---|---|---|
committer | 2017-10-24 10:39:30 +0200 | |
commit | dbff8b81bec72dd0f8a2fef825128e5f33c650d0 (patch) | |
tree | 68ba03941dfb5647a567848252b9f98033395b54 | |
parent | e287d4bf333e412033c8f484018cc431100eeee6 (diff) |
Propagate skylark flags to WORKSPACE and repo rules
RELNOTES: Skylark semantics flags now affect WORKSPACE files and repository rules.
PiperOrigin-RevId: 173130286
12 files changed, 111 insertions, 15 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/repository/skylark/SkylarkRepositoryFunction.java b/src/main/java/com/google/devtools/build/lib/bazel/repository/skylark/SkylarkRepositoryFunction.java index 6f708863fd..027d901611 100644 --- a/src/main/java/com/google/devtools/build/lib/bazel/repository/skylark/SkylarkRepositoryFunction.java +++ b/src/main/java/com/google/devtools/build/lib/bazel/repository/skylark/SkylarkRepositoryFunction.java @@ -22,10 +22,12 @@ import com.google.devtools.build.lib.bazel.repository.downloader.HttpDownloader; import com.google.devtools.build.lib.packages.Rule; import com.google.devtools.build.lib.rules.repository.RepositoryDirectoryValue; import com.google.devtools.build.lib.rules.repository.RepositoryFunction; +import com.google.devtools.build.lib.skyframe.PrecomputedValue; import com.google.devtools.build.lib.syntax.BaseFunction; import com.google.devtools.build.lib.syntax.EvalException; import com.google.devtools.build.lib.syntax.Mutability; import com.google.devtools.build.lib.syntax.Runtime; +import com.google.devtools.build.lib.syntax.SkylarkSemantics; import com.google.devtools.build.lib.vfs.FileSystemUtils; import com.google.devtools.build.lib.vfs.Path; import com.google.devtools.build.skyframe.SkyFunction.Environment; @@ -54,11 +56,14 @@ public class SkylarkRepositoryFunction extends RepositoryFunction { if (declareEnvironmentDependencies(markerData, env, getEnviron(rule)) == null) { return null; } + SkylarkSemantics skylarkSemantics = PrecomputedValue.SKYLARK_SEMANTICS.get(env); + if (skylarkSemantics == null) { + return null; + } try (Mutability mutability = Mutability.create("skylark repository")) { - // This Skylark environment ignores command line flags. com.google.devtools.build.lib.syntax.Environment buildEnv = com.google.devtools.build.lib.syntax.Environment.builder(mutability) - .useDefaultSemantics() + .setSemantics(skylarkSemantics) .setEventHandler(env.getListener()) .build(); SkylarkRepositoryContext skylarkRepositoryContext = diff --git a/src/main/java/com/google/devtools/build/lib/packages/WorkspaceFactory.java b/src/main/java/com/google/devtools/build/lib/packages/WorkspaceFactory.java index 0a9d68bff5..88ef31b5dc 100644 --- a/src/main/java/com/google/devtools/build/lib/packages/WorkspaceFactory.java +++ b/src/main/java/com/google/devtools/build/lib/packages/WorkspaceFactory.java @@ -48,6 +48,7 @@ import com.google.devtools.build.lib.syntax.ParserInputSource; import com.google.devtools.build.lib.syntax.Runtime; import com.google.devtools.build.lib.syntax.Runtime.NoneType; import com.google.devtools.build.lib.syntax.SkylarkList; +import com.google.devtools.build.lib.syntax.SkylarkSemantics; import com.google.devtools.build.lib.syntax.SkylarkSignatureProcessor; import com.google.devtools.build.lib.vfs.Path; import java.io.File; @@ -141,15 +142,19 @@ public class WorkspaceFactory { } /** - * Parses the given WORKSPACE file without resolving skylark imports. + * Parses the given WORKSPACE file without resolving Skylark imports, using the default Skylark + * semantics. */ public void parse(ParserInputSource source) throws BuildFileContainsErrorsException, InterruptedException { - parse(source, null); + parse(source, SkylarkSemantics.DEFAULT_SEMANTICS, null); } @VisibleForTesting - public void parse(ParserInputSource source, @Nullable StoredEventHandler localReporter) + public void parse( + ParserInputSource source, + SkylarkSemantics skylarkSemantics, + @Nullable StoredEventHandler localReporter) throws BuildFileContainsErrorsException, InterruptedException { // This method is split in 2 so WorkspaceFileFunction can call the two parts separately and // do the Skylark load imports in between. We can't load skylark imports from @@ -163,7 +168,7 @@ public class WorkspaceFactory { throw new BuildFileContainsErrorsException( Label.EXTERNAL_PACKAGE_IDENTIFIER, "Failed to parse " + source.getPath()); } - execute(buildFileAST, null, localReporter); + execute(buildFileAST, null, skylarkSemantics, localReporter); } @@ -171,15 +176,21 @@ public class WorkspaceFactory { * Actually runs through the AST, calling the functions in the WORKSPACE file and adding rules * to the //external package. */ - public void execute(BuildFileAST ast, Map<String, Extension> importedExtensions) + public void execute( + BuildFileAST ast, + Map<String, Extension> importedExtensions, + SkylarkSemantics skylarkSemantics) throws InterruptedException { Preconditions.checkNotNull(ast); Preconditions.checkNotNull(importedExtensions); - execute(ast, importedExtensions, new StoredEventHandler()); + execute(ast, importedExtensions, skylarkSemantics, new StoredEventHandler()); } - private void execute(BuildFileAST ast, @Nullable Map<String, Extension> importedExtensions, + private void execute( + BuildFileAST ast, + @Nullable Map<String, Extension> importedExtensions, + SkylarkSemantics skylarkSemantics, StoredEventHandler localReporter) throws InterruptedException { if (importedExtensions != null) { @@ -191,8 +202,7 @@ public class WorkspaceFactory { } Environment workspaceEnv = Environment.builder(mutability) - // Note that this Skylark environment ignores command line flags. - .useDefaultSemantics() + .setSemantics(skylarkSemantics) .setGlobals(BazelLibrary.GLOBALS) .setEventHandler(localReporter) .setImportedExtensions(importMap) diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/WorkspaceFileFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/WorkspaceFileFunction.java index 71f2c98ff6..3f0f3f8ec2 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/WorkspaceFileFunction.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/WorkspaceFileFunction.java @@ -27,6 +27,7 @@ import com.google.devtools.build.lib.skyframe.WorkspaceFileValue.WorkspaceFileKe import com.google.devtools.build.lib.syntax.BuildFileAST; import com.google.devtools.build.lib.syntax.Environment.Extension; import com.google.devtools.build.lib.syntax.Mutability; +import com.google.devtools.build.lib.syntax.SkylarkSemantics; import com.google.devtools.build.lib.vfs.Path; import com.google.devtools.build.lib.vfs.RootedPath; import com.google.devtools.build.skyframe.SkyFunction; @@ -66,6 +67,10 @@ public class WorkspaceFileFunction implements SkyFunction { if (workspaceASTValue == null) { return null; } + SkylarkSemantics skylarkSemantics = PrecomputedValue.SKYLARK_SEMANTICS.get(env); + if (skylarkSemantics == null) { + return null; + } Path repoWorkspace = workspaceRoot.getRoot().getRelative(workspaceRoot.getRelativePath()); Package.Builder builder = packageFactory.newExternalPackageBuilder( @@ -112,7 +117,7 @@ public class WorkspaceFileFunction implements SkyFunction { if (importResult == null) { return null; } - parser.execute(ast, importResult.importMap); + parser.execute(ast, importResult.importMap, skylarkSemantics); } catch (NoSuchPackageException e) { throw new WorkspaceFileFunctionException(e, Transience.PERSISTENT); } catch (NameConflictException e) { diff --git a/src/test/java/com/google/devtools/build/lib/packages/WorkspaceFactoryTest.java b/src/test/java/com/google/devtools/build/lib/packages/WorkspaceFactoryTest.java index 59455eca3a..e92d3af074 100644 --- a/src/test/java/com/google/devtools/build/lib/packages/WorkspaceFactoryTest.java +++ b/src/test/java/com/google/devtools/build/lib/packages/WorkspaceFactoryTest.java @@ -24,6 +24,7 @@ import com.google.devtools.build.lib.events.StoredEventHandler; import com.google.devtools.build.lib.packages.Package.Builder; import com.google.devtools.build.lib.syntax.Mutability; import com.google.devtools.build.lib.syntax.ParserInputSource; +import com.google.devtools.build.lib.syntax.SkylarkSemantics; import com.google.devtools.build.lib.testutil.Scratch; import com.google.devtools.build.lib.testutil.TestRuleClassProvider; import com.google.devtools.build.lib.vfs.Path; @@ -149,7 +150,10 @@ public class WorkspaceFactoryTest { root); Exception exception = null; try { - factory.parse(ParserInputSource.create(workspaceFilePath), eventHandler); + factory.parse( + ParserInputSource.create(workspaceFilePath), + SkylarkSemantics.DEFAULT_SEMANTICS, + eventHandler); } catch (BuildFileContainsErrorsException e) { exception = e; } catch (IOException | InterruptedException e) { diff --git a/src/test/java/com/google/devtools/build/lib/rules/repository/RepositoryDelegatorTest.java b/src/test/java/com/google/devtools/build/lib/rules/repository/RepositoryDelegatorTest.java index 57e517e4d2..6bf0519cb8 100644 --- a/src/test/java/com/google/devtools/build/lib/rules/repository/RepositoryDelegatorTest.java +++ b/src/test/java/com/google/devtools/build/lib/rules/repository/RepositoryDelegatorTest.java @@ -37,6 +37,7 @@ import com.google.devtools.build.lib.skyframe.PrecomputedValue; import com.google.devtools.build.lib.skyframe.SkyFunctions; import com.google.devtools.build.lib.skyframe.WorkspaceASTFunction; import com.google.devtools.build.lib.skyframe.WorkspaceFileFunction; +import com.google.devtools.build.lib.syntax.SkylarkSemantics; import com.google.devtools.build.lib.testutil.FoundationTestCase; import com.google.devtools.build.lib.testutil.TestConstants; import com.google.devtools.build.lib.testutil.TestRuleClassProvider; @@ -125,6 +126,7 @@ public class RepositoryDelegatorTest extends FoundationTestCase { .put(RepositoryName.createFromValidStrippedName("foo"), overrideDirectory.asFragment()) .build()); PrecomputedValue.PATH_PACKAGE_LOCATOR.set(differencer, pkgLocator.get()); + PrecomputedValue.SKYLARK_SEMANTICS.set(differencer, SkylarkSemantics.DEFAULT_SEMANTICS); } @Test diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/ContainingPackageLookupFunctionTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/ContainingPackageLookupFunctionTest.java index 3c662db805..19b0c95224 100644 --- a/src/test/java/com/google/devtools/build/lib/skyframe/ContainingPackageLookupFunctionTest.java +++ b/src/test/java/com/google/devtools/build/lib/skyframe/ContainingPackageLookupFunctionTest.java @@ -37,6 +37,7 @@ import com.google.devtools.build.lib.rules.repository.RepositoryLoaderFunction; import com.google.devtools.build.lib.skyframe.ExternalFilesHelper.ExternalFileAction; import com.google.devtools.build.lib.skyframe.PackageLookupFunction.CrossRepositoryLabelViolationStrategy; import com.google.devtools.build.lib.skyframe.PackageLookupValue.BuildFileName; +import com.google.devtools.build.lib.syntax.SkylarkSemantics; import com.google.devtools.build.lib.testutil.FoundationTestCase; import com.google.devtools.build.lib.util.io.TimestampGranularityMonitor; import com.google.devtools.build.lib.vfs.PathFragment; @@ -137,9 +138,10 @@ public class ContainingPackageLookupFunctionTest extends FoundationTestCase { evaluator = new InMemoryMemoizingEvaluator(skyFunctions, differencer); driver = new SequentialBuildDriver(evaluator); PrecomputedValue.BUILD_ID.set(differencer, UUID.randomUUID()); - PrecomputedValue.PATH_PACKAGE_LOCATOR.set(differencer, pkgLocator.get()); PrecomputedValue.BLACKLISTED_PACKAGE_PREFIXES_FILE.set(differencer, PathFragment.EMPTY_FRAGMENT); + PrecomputedValue.PATH_PACKAGE_LOCATOR.set(differencer, pkgLocator.get()); + PrecomputedValue.SKYLARK_SEMANTICS.set(differencer, SkylarkSemantics.DEFAULT_SEMANTICS); RepositoryDelegatorFunction.REPOSITORY_OVERRIDES.set( differencer, ImmutableMap.<RepositoryName, PathFragment>of()); } diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/FileFunctionTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/FileFunctionTest.java index 93bb5aeccc..846e6d3476 100644 --- a/src/test/java/com/google/devtools/build/lib/skyframe/FileFunctionTest.java +++ b/src/test/java/com/google/devtools/build/lib/skyframe/FileFunctionTest.java @@ -42,6 +42,7 @@ import com.google.devtools.build.lib.rules.repository.RepositoryDelegatorFunctio import com.google.devtools.build.lib.skyframe.ExternalFilesHelper.ExternalFileAction; import com.google.devtools.build.lib.skyframe.PackageLookupFunction.CrossRepositoryLabelViolationStrategy; import com.google.devtools.build.lib.skyframe.PackageLookupValue.BuildFileName; +import com.google.devtools.build.lib.syntax.SkylarkSemantics; import com.google.devtools.build.lib.testutil.ManualClock; import com.google.devtools.build.lib.testutil.TestConstants; import com.google.devtools.build.lib.testutil.TestRuleClassProvider; @@ -169,6 +170,7 @@ public class FileFunctionTest { PrecomputedValue.PATH_PACKAGE_LOCATOR.set(differencer, pkgLocator); RepositoryDelegatorFunction.REPOSITORY_OVERRIDES.set( differencer, ImmutableMap.<RepositoryName, PathFragment>of()); + PrecomputedValue.SKYLARK_SEMANTICS.set(differencer, SkylarkSemantics.DEFAULT_SEMANTICS); return new SequentialBuildDriver(evaluator); } diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/LocalRepositoryLookupFunctionTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/LocalRepositoryLookupFunctionTest.java index ca81506a63..7c4e309d61 100644 --- a/src/test/java/com/google/devtools/build/lib/skyframe/LocalRepositoryLookupFunctionTest.java +++ b/src/test/java/com/google/devtools/build/lib/skyframe/LocalRepositoryLookupFunctionTest.java @@ -31,6 +31,7 @@ import com.google.devtools.build.lib.pkgcache.PathPackageLocator; import com.google.devtools.build.lib.skyframe.ExternalFilesHelper.ExternalFileAction; import com.google.devtools.build.lib.skyframe.PackageLookupFunction.CrossRepositoryLabelViolationStrategy; import com.google.devtools.build.lib.skyframe.PackageLookupValue.BuildFileName; +import com.google.devtools.build.lib.syntax.SkylarkSemantics; import com.google.devtools.build.lib.testutil.FoundationTestCase; import com.google.devtools.build.lib.util.io.TimestampGranularityMonitor; import com.google.devtools.build.lib.vfs.FileSystemUtils; @@ -114,6 +115,7 @@ public class LocalRepositoryLookupFunctionTest extends FoundationTestCase { evaluator = new InMemoryMemoizingEvaluator(skyFunctions, differencer); driver = new SequentialBuildDriver(evaluator); PrecomputedValue.PATH_PACKAGE_LOCATOR.set(differencer, pkgLocator.get()); + PrecomputedValue.SKYLARK_SEMANTICS.set(differencer, SkylarkSemantics.DEFAULT_SEMANTICS); } private SkyKey createKey(RootedPath directory) { diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/PackageLookupFunctionTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/PackageLookupFunctionTest.java index e24dca8c96..27eef90146 100644 --- a/src/test/java/com/google/devtools/build/lib/skyframe/PackageLookupFunctionTest.java +++ b/src/test/java/com/google/devtools/build/lib/skyframe/PackageLookupFunctionTest.java @@ -42,6 +42,7 @@ import com.google.devtools.build.lib.skyframe.PackageLookupFunction.CrossReposit import com.google.devtools.build.lib.skyframe.PackageLookupValue.BuildFileName; import com.google.devtools.build.lib.skyframe.PackageLookupValue.ErrorReason; import com.google.devtools.build.lib.skyframe.PackageLookupValue.IncorrectRepositoryReferencePackageLookupValue; +import com.google.devtools.build.lib.syntax.SkylarkSemantics; import com.google.devtools.build.lib.testutil.FoundationTestCase; import com.google.devtools.build.lib.util.io.TimestampGranularityMonitor; import com.google.devtools.build.lib.vfs.FileSystemUtils; @@ -148,9 +149,10 @@ public abstract class PackageLookupFunctionTest extends FoundationTestCase { evaluator = new InMemoryMemoizingEvaluator(skyFunctions, differencer); driver = new SequentialBuildDriver(evaluator); PrecomputedValue.BUILD_ID.set(differencer, UUID.randomUUID()); - PrecomputedValue.PATH_PACKAGE_LOCATOR.set(differencer, pkgLocator.get()); PrecomputedValue.BLACKLISTED_PACKAGE_PREFIXES_FILE.set( differencer, PathFragment.EMPTY_FRAGMENT); + PrecomputedValue.PATH_PACKAGE_LOCATOR.set(differencer, pkgLocator.get()); + PrecomputedValue.SKYLARK_SEMANTICS.set(differencer, SkylarkSemantics.DEFAULT_SEMANTICS); RepositoryDelegatorFunction.REPOSITORY_OVERRIDES.set( differencer, ImmutableMap.<RepositoryName, PathFragment>of()); } diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/WorkspaceFileFunctionTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/WorkspaceFileFunctionTest.java index 61a6e9865f..d5e37ce5e6 100644 --- a/src/test/java/com/google/devtools/build/lib/skyframe/WorkspaceFileFunctionTest.java +++ b/src/test/java/com/google/devtools/build/lib/skyframe/WorkspaceFileFunctionTest.java @@ -25,6 +25,7 @@ import com.google.devtools.build.lib.packages.Package; import com.google.devtools.build.lib.packages.PackageFactory; import com.google.devtools.build.lib.packages.PackageFactory.EnvironmentExtension; import com.google.devtools.build.lib.packages.Rule; +import com.google.devtools.build.lib.syntax.SkylarkSemantics; import com.google.devtools.build.lib.testutil.MoreAsserts; import com.google.devtools.build.lib.testutil.TestRuleClassProvider; import com.google.devtools.build.lib.vfs.Path; @@ -166,6 +167,19 @@ public class WorkspaceFileFunctionTest extends BuildViewTestCase { return astSkyFunc.compute(key, getEnv()); } }); + Mockito.when(env.getValue(Matchers.argThat(new SkyKeyMatchers(SkyFunctions.PRECOMPUTED)))) + .then( + new Answer<SkyValue>() { + @Override + public SkyValue answer(InvocationOnMock invocation) throws Throwable { + SkyKey key = (SkyKey) invocation.getArguments()[0]; + if (key.equals(PrecomputedValue.SKYLARK_SEMANTICS.getKeyForTesting())) { + return new PrecomputedValue(SkylarkSemantics.DEFAULT_SEMANTICS); + } else { + return null; + } + } + }); return env; } diff --git a/src/test/shell/bazel/skylark_repository_test.sh b/src/test/shell/bazel/skylark_repository_test.sh index c1d9608fea..72c08bb8cf 100755 --- a/src/test/shell/bazel/skylark_repository_test.sh +++ b/src/test/shell/bazel/skylark_repository_test.sh @@ -24,6 +24,8 @@ source "${CURRENT_DIR}/../integration_test_setup.sh" \ source "${CURRENT_DIR}/remote_helpers.sh" \ || { echo "remote_helpers.sh not found!" >&2; exit 1; } +SKYLARK_FLAG_MARKER="<== skylark flag test ==>" + # Basic test. function test_macro_local_repository() { create_new_workspace @@ -334,6 +336,26 @@ EOF cat > BUILD } +function test_skylark_flags_affect_repository_rule() { + setup_skylark_repository + + cat >test.bzl <<EOF +def _impl(repository_ctx): + print("In repo rule: ") + # Symlink so a repository is created + repository_ctx.symlink(repository_ctx.path("$repo2"), repository_ctx.path("")) + +repo = repository_rule(implementation=_impl, local=True) +EOF + + # Build with the special testing flag that appends a marker string to all + # print() calls. + bazel build @foo//:bar --internal_skylark_flag_test_canary >& $TEST_log \ + || fail "Expected build to succeed" + expect_log "In repo rule: $SKYLARK_FLAG_MARKER" \ + "Skylark flags are not propagating to repository rules" +} + function test_skylark_repository_which_and_execute() { setup_skylark_repository diff --git a/src/test/shell/bazel/workspace_test.sh b/src/test/shell/bazel/workspace_test.sh index 5b4b7de3db..bd0010564d 100755 --- a/src/test/shell/bazel/workspace_test.sh +++ b/src/test/shell/bazel/workspace_test.sh @@ -21,6 +21,8 @@ source "${CURRENT_DIR}/../integration_test_setup.sh" \ export JAVA_RUNFILES=$BAZEL_RUNFILES +SKYLARK_FLAG_MARKER="<== skylark flag test ==>" + function setup_repo() { mkdir -p $1 touch $1/WORKSPACE @@ -173,6 +175,30 @@ EOF [ ! -L bazel-x ] || fail "bazel-x should have been removed" } +function test_skylark_flags_affect_workspace() { + cat > WORKSPACE <<EOF +load("//:macro.bzl", "macro") +print("In workspace: ") +macro() +EOF + cat > macro.bzl <<EOF +def macro(): + print("In workspace macro: ") +EOF + cat > BUILD <<'EOF' +genrule(name = "x", cmd = "echo hi > $@", outs = ["x.out"], srcs = []) +EOF + + # Build with the special testing flag that appends a marker string to all + # print() calls. + bazel build //:x --internal_skylark_flag_test_canary &>"$TEST_log" \ + || fail "Expected build to succeed" + expect_log "In workspace: $SKYLARK_FLAG_MARKER" \ + "Skylark flags are not propagating to workspace evaluation" + expect_log "In workspace macro: $SKYLARK_FLAG_MARKER" \ + "Skylark flags are not propagating to workspace macro evaluation" +} + function test_workspace_name() { mkdir -p foo mkdir -p bar |