From dfcd5da86e2acfd42ca09c7f65e012465ab3e382 Mon Sep 17 00:00:00 2001 From: kchodorow Date: Wed, 19 Apr 2017 18:58:50 +0200 Subject: Add repository override option RELNOTES: Adds a --override_repository option that takes a repository name and path. This forces Bazel to use the directory at that path for the repository. Example usage: `--override_repository=foo=/home/user/gitroot/foo`. Fixes #1266 PiperOrigin-RevId: 153599291 --- .../build/lib/analysis/util/AnalysisTestCase.java | 5 + .../build/lib/analysis/util/BuildViewTestCase.java | 4 + .../lib/analysis/util/ConfigurationTestCase.java | 5 +- .../devtools/build/lib/bazel/repository/BUILD | 1 + .../bazel/repository/RepositoryOptionsTest.java | 70 ++++++++++ .../devtools/build/lib/rules/repository/BUILD | 2 + .../rules/repository/RepositoryDelegatorTest.java | 142 +++++++++++++++++++++ .../build/lib/skyframe/FileFunctionTest.java | 4 + .../lib/skyframe/PackageLookupFunctionTest.java | 3 + 9 files changed, 235 insertions(+), 1 deletion(-) create mode 100644 src/test/java/com/google/devtools/build/lib/bazel/repository/RepositoryOptionsTest.java create mode 100644 src/test/java/com/google/devtools/build/lib/rules/repository/RepositoryDelegatorTest.java (limited to 'src/test/java/com/google') diff --git a/src/test/java/com/google/devtools/build/lib/analysis/util/AnalysisTestCase.java b/src/test/java/com/google/devtools/build/lib/analysis/util/AnalysisTestCase.java index 032599f4e3..1cd568596b 100644 --- a/src/test/java/com/google/devtools/build/lib/analysis/util/AnalysisTestCase.java +++ b/src/test/java/com/google/devtools/build/lib/analysis/util/AnalysisTestCase.java @@ -38,6 +38,7 @@ import com.google.devtools.build.lib.analysis.config.ConfigurationFactory; import com.google.devtools.build.lib.buildtool.BuildRequest.BuildRequestOptions; import com.google.devtools.build.lib.cmdline.Label; import com.google.devtools.build.lib.cmdline.LabelSyntaxException; +import com.google.devtools.build.lib.cmdline.RepositoryName; import com.google.devtools.build.lib.exec.ExecutionOptions; import com.google.devtools.build.lib.flags.InvocationPolicyEnforcer; import com.google.devtools.build.lib.packages.PackageFactory; @@ -49,6 +50,7 @@ import com.google.devtools.build.lib.pkgcache.LoadingResult; import com.google.devtools.build.lib.pkgcache.PackageCacheOptions; import com.google.devtools.build.lib.pkgcache.PackageManager; import com.google.devtools.build.lib.pkgcache.PathPackageLocator; +import com.google.devtools.build.lib.rules.repository.RepositoryDelegatorFunction; import com.google.devtools.build.lib.skyframe.ConfiguredTargetKey; import com.google.devtools.build.lib.skyframe.DiffAwareness; import com.google.devtools.build.lib.skyframe.PackageLookupFunction.CrossRepositoryLabelViolationStrategy; @@ -192,6 +194,9 @@ public abstract class AnalysisTestCase extends FoundationTestCase { ImmutableMap.of(), ImmutableMap.of(), new TimestampGranularityMonitor(BlazeClock.instance())); + skyframeExecutor.injectExtraPrecomputedValues(ImmutableList.of(PrecomputedValue.injected( + RepositoryDelegatorFunction.REPOSITORY_OVERRIDES, + ImmutableMap.of()))); packageManager = skyframeExecutor.getPackageManager(); loadingPhaseRunner = skyframeExecutor.getLoadingPhaseRunner( pkgFactory.getRuleClassNames(), defaultFlags().contains(Flag.SKYFRAME_LOADING_PHASE)); diff --git a/src/test/java/com/google/devtools/build/lib/analysis/util/BuildViewTestCase.java b/src/test/java/com/google/devtools/build/lib/analysis/util/BuildViewTestCase.java index 140f99efb6..33ebdee37a 100644 --- a/src/test/java/com/google/devtools/build/lib/analysis/util/BuildViewTestCase.java +++ b/src/test/java/com/google/devtools/build/lib/analysis/util/BuildViewTestCase.java @@ -118,6 +118,7 @@ import com.google.devtools.build.lib.pkgcache.PackageCacheOptions; import com.google.devtools.build.lib.pkgcache.PackageManager; import com.google.devtools.build.lib.pkgcache.PathPackageLocator; import com.google.devtools.build.lib.rules.extra.ExtraAction; +import com.google.devtools.build.lib.rules.repository.RepositoryDelegatorFunction; import com.google.devtools.build.lib.rules.test.BaselineCoverageAction; import com.google.devtools.build.lib.rules.test.InstrumentedFilesProvider; import com.google.devtools.build.lib.skyframe.AspectValue; @@ -232,6 +233,9 @@ public abstract class BuildViewTestCase extends FoundationTestCase { analysisMock.getProductName(), CrossRepositoryLabelViolationStrategy.ERROR, ImmutableList.of(BuildFileName.BUILD_DOT_BAZEL, BuildFileName.BUILD)); + skyframeExecutor.injectExtraPrecomputedValues(ImmutableList.of(PrecomputedValue.injected( + RepositoryDelegatorFunction.REPOSITORY_OVERRIDES, + ImmutableMap.of()))); packageCacheOptions.defaultVisibility = ConstantRuleVisibility.PUBLIC; packageCacheOptions.showLoadingProgress = true; packageCacheOptions.globbingThreads = 7; diff --git a/src/test/java/com/google/devtools/build/lib/analysis/util/ConfigurationTestCase.java b/src/test/java/com/google/devtools/build/lib/analysis/util/ConfigurationTestCase.java index 490b642668..fbf170269d 100644 --- a/src/test/java/com/google/devtools/build/lib/analysis/util/ConfigurationTestCase.java +++ b/src/test/java/com/google/devtools/build/lib/analysis/util/ConfigurationTestCase.java @@ -36,6 +36,7 @@ import com.google.devtools.build.lib.packages.PackageFactory; import com.google.devtools.build.lib.packages.util.MockToolsConfig; import com.google.devtools.build.lib.pkgcache.PackageCacheOptions; import com.google.devtools.build.lib.pkgcache.PathPackageLocator; +import com.google.devtools.build.lib.rules.repository.RepositoryDelegatorFunction; import com.google.devtools.build.lib.skyframe.DiffAwareness; import com.google.devtools.build.lib.skyframe.PackageLookupFunction.CrossRepositoryLabelViolationStrategy; import com.google.devtools.build.lib.skyframe.PackageLookupValue.BuildFileName; @@ -116,7 +117,9 @@ public abstract class ConfigurationTestCase extends FoundationTestCase { analysisMock.getProductName(), CrossRepositoryLabelViolationStrategy.ERROR, ImmutableList.of(BuildFileName.BUILD_DOT_BAZEL, BuildFileName.BUILD)); - + skyframeExecutor.injectExtraPrecomputedValues(ImmutableList.of(PrecomputedValue.injected( + RepositoryDelegatorFunction.REPOSITORY_OVERRIDES, + ImmutableMap.of()))); PackageCacheOptions packageCacheOptions = Options.getDefaults(PackageCacheOptions.class); packageCacheOptions.showLoadingProgress = true; packageCacheOptions.globbingThreads = 7; diff --git a/src/test/java/com/google/devtools/build/lib/bazel/repository/BUILD b/src/test/java/com/google/devtools/build/lib/bazel/repository/BUILD index 96053933e5..d3c387dbec 100644 --- a/src/test/java/com/google/devtools/build/lib/bazel/repository/BUILD +++ b/src/test/java/com/google/devtools/build/lib/bazel/repository/BUILD @@ -29,6 +29,7 @@ java_test( "//src/main/java/com/google/devtools/build/lib/bazel/repository/downloader", "//src/main/java/com/google/devtools/build/lib/rules/cpp", "//src/main/java/com/google/devtools/build/skyframe", + "//src/main/java/com/google/devtools/common/options", "//src/test/java/com/google/devtools/build/lib:analysis_testutil", "//src/test/java/com/google/devtools/build/lib:foundations_testutil", "//src/test/java/com/google/devtools/build/lib:packages_testutil", diff --git a/src/test/java/com/google/devtools/build/lib/bazel/repository/RepositoryOptionsTest.java b/src/test/java/com/google/devtools/build/lib/bazel/repository/RepositoryOptionsTest.java new file mode 100644 index 0000000000..d70b6d8100 --- /dev/null +++ b/src/test/java/com/google/devtools/build/lib/bazel/repository/RepositoryOptionsTest.java @@ -0,0 +1,70 @@ +// Copyright 2017 The Bazel Authors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package com.google.devtools.build.lib.bazel.repository; + +import static com.google.common.truth.Truth.assertThat; + +import com.google.devtools.build.lib.bazel.repository.RepositoryOptions.RepositoryOverride; +import com.google.devtools.build.lib.bazel.repository.RepositoryOptions.RepositoryOverrideConverter; +import com.google.devtools.build.lib.cmdline.RepositoryName; +import com.google.devtools.build.lib.vfs.PathFragment; +import com.google.devtools.common.options.OptionsParsingException; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** + * Test for {@link RepositoryOptions}. + */ +@RunWith(JUnit4.class) +public class RepositoryOptionsTest { + + private final RepositoryOverrideConverter converter = new RepositoryOverrideConverter(); + + @Rule + public ExpectedException expectedException = ExpectedException.none(); + + @Test + public void testOverrideConverter() throws Exception { + RepositoryOverride actual = converter.convert("foo=/bar"); + assertThat(actual.repositoryName()) + .isEqualTo(RepositoryName.createFromValidStrippedName("foo")); + assertThat(actual.path()).isEqualTo(PathFragment.create("/bar")); + } + + @Test + public void testInvalidOverride() throws Exception { + expectedException.expect(OptionsParsingException.class); + expectedException.expectMessage( + "Repository overrides must be of the form 'repository-name=path'"); + converter.convert("foo"); + } + + @Test + public void testInvalidRepoOverride() throws Exception { + expectedException.expect(OptionsParsingException.class); + expectedException.expectMessage("Invalid repository name given to override"); + converter.convert("foo/bar=/baz"); + } + + @Test + public void testInvalidPathOverride() throws Exception { + expectedException.expect(OptionsParsingException.class); + expectedException.expectMessage("Repository override directory must be an absolute path"); + converter.convert("foo=bar"); + } +} diff --git a/src/test/java/com/google/devtools/build/lib/rules/repository/BUILD b/src/test/java/com/google/devtools/build/lib/rules/repository/BUILD index ed24a5081f..8d94ddba6c 100644 --- a/src/test/java/com/google/devtools/build/lib/rules/repository/BUILD +++ b/src/test/java/com/google/devtools/build/lib/rules/repository/BUILD @@ -19,6 +19,8 @@ java_test( "//src/main/java/com/google/devtools/build/lib:bazel-main", "//src/main/java/com/google/devtools/build/lib:bazel-repository", "//src/main/java/com/google/devtools/build/lib:build-base", + "//src/main/java/com/google/devtools/build/lib:events", + "//src/main/java/com/google/devtools/build/lib:io", "//src/main/java/com/google/devtools/build/lib:packages-internal", "//src/main/java/com/google/devtools/build/lib:runtime", "//src/main/java/com/google/devtools/build/lib:unix", 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 new file mode 100644 index 0000000000..f6955e5e2f --- /dev/null +++ b/src/test/java/com/google/devtools/build/lib/rules/repository/RepositoryDelegatorTest.java @@ -0,0 +1,142 @@ +// Copyright 2017 The Bazel Authors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package com.google.devtools.build.lib.rules.repository; + +import static com.google.common.truth.Truth.assertThat; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.google.devtools.build.lib.analysis.BlazeDirectories; +import com.google.devtools.build.lib.cmdline.RepositoryName; +import com.google.devtools.build.lib.events.StoredEventHandler; +import com.google.devtools.build.lib.pkgcache.PathPackageLocator; +import com.google.devtools.build.lib.skyframe.ExternalFilesHelper; +import com.google.devtools.build.lib.skyframe.ExternalFilesHelper.ExternalFileAction; +import com.google.devtools.build.lib.skyframe.ExternalPackageFunction; +import com.google.devtools.build.lib.skyframe.FileFunction; +import com.google.devtools.build.lib.skyframe.FileStateFunction; +import com.google.devtools.build.lib.skyframe.LocalRepositoryLookupFunction; +import com.google.devtools.build.lib.skyframe.PackageFunction; +import com.google.devtools.build.lib.skyframe.PackageLookupFunction; +import com.google.devtools.build.lib.skyframe.PackageLookupFunction.CrossRepositoryLabelViolationStrategy; +import com.google.devtools.build.lib.skyframe.PackageLookupValue.BuildFileName; +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.testutil.FoundationTestCase; +import com.google.devtools.build.lib.testutil.TestConstants; +import com.google.devtools.build.lib.testutil.TestRuleClassProvider; +import com.google.devtools.build.lib.util.io.TimestampGranularityMonitor; +import com.google.devtools.build.lib.vfs.Path; +import com.google.devtools.build.lib.vfs.PathFragment; +import com.google.devtools.build.skyframe.EvaluationResult; +import com.google.devtools.build.skyframe.InMemoryMemoizingEvaluator; +import com.google.devtools.build.skyframe.MemoizingEvaluator; +import com.google.devtools.build.skyframe.RecordingDifferencer; +import com.google.devtools.build.skyframe.SequentialBuildDriver; +import com.google.devtools.build.skyframe.SkyFunction; +import com.google.devtools.build.skyframe.SkyFunctionName; +import com.google.devtools.build.skyframe.SkyKey; +import com.google.devtools.build.skyframe.SkyValue; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicReference; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** + * Tests for {@link RepositoryDelegatorFunction} + */ +@RunWith(JUnit4.class) +public class RepositoryDelegatorTest extends FoundationTestCase { + private RepositoryDelegatorFunction delegatorFunction; + private Path overrideDirectory; + private SequentialBuildDriver driver; + + @Before + public void setupDelegator() throws Exception { + Path root = scratch.dir("/outputbase"); + delegatorFunction = new RepositoryDelegatorFunction( + ImmutableMap.of(), null, new AtomicBoolean(true)); + AtomicReference pkgLocator = new AtomicReference<>( + new PathPackageLocator(root, ImmutableList.of(root))); + BlazeDirectories directories = new BlazeDirectories(root, root, root, + TestConstants.PRODUCT_NAME); + ExternalFilesHelper externalFilesHelper = new ExternalFilesHelper( + pkgLocator, + ExternalFileAction.DEPEND_ON_EXTERNAL_PKG_FOR_EXTERNAL_REPO_PATHS, + directories); + RecordingDifferencer differencer = new RecordingDifferencer(); + MemoizingEvaluator evaluator = + new InMemoryMemoizingEvaluator( + ImmutableMap.builder() + .put( + SkyFunctions.FILE_STATE, + new FileStateFunction( + new AtomicReference(), externalFilesHelper)) + .put(SkyFunctions.FILE, new FileFunction(pkgLocator)) + .put(SkyFunctions.REPOSITORY_DIRECTORY, delegatorFunction) + .put( + SkyFunctions.PACKAGE, + new PackageFunction(null, null, null, null, null, null, null)) + .put( + SkyFunctions.PACKAGE_LOOKUP, + new PackageLookupFunction( + null, + CrossRepositoryLabelViolationStrategy.ERROR, + ImmutableList.of(BuildFileName.BUILD_DOT_BAZEL, BuildFileName.BUILD))) + .put( + SkyFunctions.WORKSPACE_AST, + new WorkspaceASTFunction(TestRuleClassProvider.getRuleClassProvider())) + .put( + SkyFunctions.WORKSPACE_FILE, + new WorkspaceFileFunction( + TestRuleClassProvider.getRuleClassProvider(), + TestConstants.PACKAGE_FACTORY_FACTORY_FOR_TESTING.create( + TestRuleClassProvider.getRuleClassProvider(), root.getFileSystem()), + directories)) + .put(SkyFunctions.LOCAL_REPOSITORY_LOOKUP, new LocalRepositoryLookupFunction()) + .put(SkyFunctions.EXTERNAL_PACKAGE, new ExternalPackageFunction()) + .build(), + differencer); + driver = new SequentialBuildDriver(evaluator); + overrideDirectory = scratch.dir("/foo"); + RepositoryDelegatorFunction.REPOSITORY_OVERRIDES.set( + differencer, + ImmutableMap.builder() + .put(RepositoryName.createFromValidStrippedName("foo"), overrideDirectory.asFragment()) + .build()); + PrecomputedValue.BLAZE_DIRECTORIES.set(differencer, directories); + PrecomputedValue.PATH_PACKAGE_LOCATOR.set(differencer, pkgLocator.get()); + } + + @Test + public void testOverride() throws Exception { + StoredEventHandler eventHandler = new StoredEventHandler(); + SkyKey key = RepositoryDirectoryValue.key(RepositoryName.createFromValidStrippedName("foo")); + EvaluationResult result = + driver.evaluate(ImmutableList.of(key), false, 8, eventHandler); + assertThat(result.hasError()).isFalse(); + RepositoryDirectoryValue repositoryDirectoryValue = (RepositoryDirectoryValue) result.get(key); + Path expectedPath = scratch.dir("/outputbase/external/foo"); + Path actualPath = repositoryDirectoryValue.getPath(); + assertThat(actualPath).isEqualTo(expectedPath); + assertThat(actualPath.isSymbolicLink()).isTrue(); + assertThat(actualPath.readSymbolicLink()).isEqualTo(overrideDirectory.asFragment()); + } + +} 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 68f0386bd6..f8253903d4 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 @@ -37,9 +37,11 @@ import com.google.common.testing.EqualsTester; import com.google.devtools.build.lib.analysis.BlazeDirectories; import com.google.devtools.build.lib.cmdline.Label; import com.google.devtools.build.lib.cmdline.PackageIdentifier; +import com.google.devtools.build.lib.cmdline.RepositoryName; import com.google.devtools.build.lib.events.NullEventHandler; import com.google.devtools.build.lib.events.StoredEventHandler; import com.google.devtools.build.lib.pkgcache.PathPackageLocator; +import com.google.devtools.build.lib.rules.repository.RepositoryDelegatorFunction; 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; @@ -165,6 +167,8 @@ public class FileFunctionTest { differencer); PrecomputedValue.BUILD_ID.set(differencer, UUID.randomUUID()); PrecomputedValue.PATH_PACKAGE_LOCATOR.set(differencer, pkgLocator); + RepositoryDelegatorFunction.REPOSITORY_OVERRIDES.set( + differencer, ImmutableMap.of()); return new SequentialBuildDriver(evaluator); } 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 6ad7725f4c..9fe08801d5 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 @@ -27,6 +27,7 @@ import com.google.common.testing.EqualsTester; import com.google.devtools.build.lib.analysis.BlazeDirectories; import com.google.devtools.build.lib.analysis.util.AnalysisMock; import com.google.devtools.build.lib.cmdline.PackageIdentifier; +import com.google.devtools.build.lib.cmdline.RepositoryName; import com.google.devtools.build.lib.events.NullEventHandler; import com.google.devtools.build.lib.packages.BuildFileNotFoundException; import com.google.devtools.build.lib.packages.PackageFactory; @@ -143,6 +144,8 @@ public abstract class PackageLookupFunctionTest extends FoundationTestCase { PrecomputedValue.BLACKLISTED_PACKAGE_PREFIXES_FILE.set( differencer, PathFragment.EMPTY_FRAGMENT); PrecomputedValue.BLAZE_DIRECTORIES.set(differencer, directories); + RepositoryDelegatorFunction.REPOSITORY_OVERRIDES.set( + differencer, ImmutableMap.of()); } protected PackageLookupValue lookupPackage(String packageName) throws InterruptedException { -- cgit v1.2.3