From 653df8813dd74042e8e084eeae238a8b9f16a3ca Mon Sep 17 00:00:00 2001 From: Damien Martin-Guillerez Date: Wed, 17 Feb 2016 21:46:22 +0000 Subject: Introduce SkylarkRepositoryModule The SkylarkRepositoryModule declare the `repository_rule` function to Skylark to define new remote repository types (http://goo.gl/OZV3o0). The work is delagated to the `SkylarkRepositoryFunction` by the `RepositoryDelegatorFunction`. `SkylarkRepositoryContext` defines the `ctx` object passed to the `repository_rule` implementation function. This change also introduce a `SkylarkPath` and the necessary methods in `SkylarkRepositoryContext` to showcase the creation of a `local_repository` like repository. Issue #893: step 3 of the roadmap http://goo.gl/OZV3o0. -- MOS_MIGRATED_REVID=114895003 --- src/test/java/com/google/devtools/build/lib/BUILD | 5 +- .../build/lib/analysis/util/AnalysisMock.java | 3 +- .../skylark/SkylarkRepositoryIntegrationTest.java | 172 +++++++++++++++++++++ .../rules/repository/RepositoryFunctionTest.java | 2 +- src/test/shell/bazel/skylark_repository_test.sh | 33 ++++ 5 files changed, 212 insertions(+), 3 deletions(-) create mode 100644 src/test/java/com/google/devtools/build/lib/bazel/repository/skylark/SkylarkRepositoryIntegrationTest.java (limited to 'src/test') diff --git a/src/test/java/com/google/devtools/build/lib/BUILD b/src/test/java/com/google/devtools/build/lib/BUILD index 366fd6bd40..9a9f8caac7 100644 --- a/src/test/java/com/google/devtools/build/lib/BUILD +++ b/src/test/java/com/google/devtools/build/lib/BUILD @@ -1028,12 +1028,14 @@ java_test( java_test( name = "repository_test", srcs = glob([ - "bazel/repository/*.java", + "bazel/repository/**/*.java", ]), tags = ["rules"], test_class = "com.google.devtools.build.lib.AllTests", deps = [ + ":analysis_testutil", ":foundations_testutil", + ":packages_testutil", ":test_runner", ":testutil", "//src/main/java/com/google/devtools/build/lib:bazel-main", @@ -1042,6 +1044,7 @@ java_test( "//src/main/java/com/google/devtools/build/lib:collect", "//src/main/java/com/google/devtools/build/lib:inmemoryfs", "//src/main/java/com/google/devtools/build/lib:vfs", + "//src/main/java/com/google/devtools/build/skyframe", "//third_party:guava", "//third_party:guava-testlib", "//third_party:jsr305", diff --git a/src/test/java/com/google/devtools/build/lib/analysis/util/AnalysisMock.java b/src/test/java/com/google/devtools/build/lib/analysis/util/AnalysisMock.java index f75272e4d6..cfa5572506 100644 --- a/src/test/java/com/google/devtools/build/lib/analysis/util/AnalysisMock.java +++ b/src/test/java/com/google/devtools/build/lib/analysis/util/AnalysisMock.java @@ -88,7 +88,8 @@ public abstract class AnalysisMock { return ImmutableMap.of( SkyFunctions.REPOSITORY_DIRECTORY, - new RepositoryDelegatorFunction(directories, repositoryHandlers, new AtomicBoolean(true)), + new RepositoryDelegatorFunction( + directories, repositoryHandlers, null, new AtomicBoolean(true)), SkyFunctions.REPOSITORY, new RepositoryLoaderFunction()); } diff --git a/src/test/java/com/google/devtools/build/lib/bazel/repository/skylark/SkylarkRepositoryIntegrationTest.java b/src/test/java/com/google/devtools/build/lib/bazel/repository/skylark/SkylarkRepositoryIntegrationTest.java new file mode 100644 index 0000000000..36746adf28 --- /dev/null +++ b/src/test/java/com/google/devtools/build/lib/bazel/repository/skylark/SkylarkRepositoryIntegrationTest.java @@ -0,0 +1,172 @@ +// Copyright 2016 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.skylark; + +import static com.google.common.truth.Truth.assertThat; + +import com.google.common.collect.ImmutableMap; +import com.google.devtools.build.lib.analysis.BlazeDirectories; +import com.google.devtools.build.lib.analysis.ConfigurationCollectionFactory; +import com.google.devtools.build.lib.analysis.ConfiguredRuleClassProvider; +import com.google.devtools.build.lib.analysis.ConfiguredTarget; +import com.google.devtools.build.lib.analysis.config.ConfigurationFactory; +import com.google.devtools.build.lib.analysis.util.AnalysisMock; +import com.google.devtools.build.lib.analysis.util.BuildViewTestCase; +import com.google.devtools.build.lib.packages.util.MockCcSupport; +import com.google.devtools.build.lib.packages.util.MockToolsConfig; +import com.google.devtools.build.lib.rules.repository.LocalRepositoryFunction; +import com.google.devtools.build.lib.rules.repository.LocalRepositoryRule; +import com.google.devtools.build.lib.rules.repository.RepositoryDelegatorFunction; +import com.google.devtools.build.lib.rules.repository.RepositoryFunction; +import com.google.devtools.build.lib.rules.repository.RepositoryLoaderFunction; +import com.google.devtools.build.lib.skyframe.SkyFunctions; +import com.google.devtools.build.lib.testutil.TestRuleClassProvider; +import com.google.devtools.build.lib.vfs.Path; +import com.google.devtools.build.skyframe.SkyFunction; +import com.google.devtools.build.skyframe.SkyFunctionName; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +import java.io.IOException; +import java.util.Collection; +import java.util.concurrent.atomic.AtomicBoolean; + +/** + * Integration test for skylark repository not as heavyweight than shell integration tests. + */ +@RunWith(JUnit4.class) +public class SkylarkRepositoryIntegrationTest extends BuildViewTestCase { + + // The RuleClassProvider loaded with the SkylarkRepositoryModule + private ConfiguredRuleClassProvider ruleProvider = null; + // The Analysis mock injected with the SkylarkRepositoryFunction + private AnalysisMock analysisMock = null; + + /** + * Proxy to the real analysis mock to overwrite {@code #getSkyFunctions(BlazeDirectories)} to + * inject the SkylarkRepositoryFunction in the list of SkyFunctions. In Bazel, this function is + * injected by the corresponding @{code BlazeModule}. + */ + private static class CustomAnalysisMock extends AnalysisMock { + + private final AnalysisMock proxied; + + CustomAnalysisMock(AnalysisMock proxied) { + this.proxied = proxied; + } + + @Override + public ImmutableMap getSkyFunctions( + BlazeDirectories directories) { + // Add both the local repository and the skylark repository functions + RepositoryFunction localRepositoryFunction = new LocalRepositoryFunction(); + localRepositoryFunction.setDirectories(directories); + RepositoryFunction skylarkRepositoryFunction = new SkylarkRepositoryFunction(); + skylarkRepositoryFunction.setDirectories(directories); + ImmutableMap repositoryHandlers = + ImmutableMap.of(LocalRepositoryRule.NAME, localRepositoryFunction); + + return ImmutableMap.of( + SkyFunctions.REPOSITORY_DIRECTORY, + new RepositoryDelegatorFunction( + directories, repositoryHandlers, skylarkRepositoryFunction, new AtomicBoolean(true)), + SkyFunctions.REPOSITORY, + new RepositoryLoaderFunction()); + } + + @Override + public void setupMockClient(MockToolsConfig mockToolsConfig) throws IOException { + proxied.setupMockClient(mockToolsConfig); + } + + @Override + public void setupMockWorkspaceFiles(Path embeddedBinariesRoot) throws IOException { + proxied.setupMockWorkspaceFiles(embeddedBinariesRoot); + } + + @Override + public ConfigurationFactory createConfigurationFactory() { + return proxied.createConfigurationFactory(); + } + + @Override + public ConfigurationFactory createFullConfigurationFactory() { + return proxied.createFullConfigurationFactory(); + } + + @Override + public ConfigurationCollectionFactory createConfigurationCollectionFactory() { + return proxied.createConfigurationCollectionFactory(); + } + + @Override + public Collection getOptionOverrides() { + return proxied.getOptionOverrides(); + } + + @Override + public MockCcSupport ccSupport() { + return proxied.ccSupport(); + } + } + + @Override + protected AnalysisMock getAnalysisMock() { + if (analysisMock == null) { + analysisMock = new CustomAnalysisMock(super.getAnalysisMock()); + } + return analysisMock; + } + + @Override + protected ConfiguredRuleClassProvider getRuleClassProvider() { + // We inject the repository module in our test rule class provider. + if (ruleProvider == null) { + ConfiguredRuleClassProvider.Builder builder = new ConfiguredRuleClassProvider.Builder(); + TestRuleClassProvider.addStandardRules(builder); + builder.addSkylarkModule(SkylarkRepositoryModule.class); + ruleProvider = builder.build(); + } + return ruleProvider; + } + + @Test + public void testSkylarkLocalRepository() throws Exception { + // A simple test that recreates local_repository with Skylark. + scratch.file("/repo2/WORKSPACE"); + scratch.file("/repo2/bar.txt"); + scratch.file("/repo2/BUILD", "filegroup(name='bar', srcs=['bar.txt'], path='foo')"); + scratch.file( + "def.bzl", + "def _impl(ctx):", + " ctx.symlink(ctx.path(ctx.attr.path), ctx.path(''))", + "", + "repo = repository_rule(", + " implementation=_impl,", + " local=True,", + " attrs={'path': attr.string(mandatory=True)})"); + scratch.file(rootDirectory.getRelative("BUILD").getPathString()); + scratch.overwriteFile( + rootDirectory.getRelative("WORKSPACE").getPathString(), + "load('//:def.bzl', 'repo')", + "repo(name='foo', path='/repo2')"); + invalidatePackages(); + ConfiguredTarget target = getConfiguredTarget("@foo//:bar"); + Object path = target.getTarget().getAssociatedRule().getAttributeContainer().getAttr("path"); + assertThat(path).isEqualTo("foo"); + } +} diff --git a/src/test/java/com/google/devtools/build/lib/rules/repository/RepositoryFunctionTest.java b/src/test/java/com/google/devtools/build/lib/rules/repository/RepositoryFunctionTest.java index 84a17b2794..1b7cb5f68e 100644 --- a/src/test/java/com/google/devtools/build/lib/rules/repository/RepositoryFunctionTest.java +++ b/src/test/java/com/google/devtools/build/lib/rules/repository/RepositoryFunctionTest.java @@ -53,7 +53,7 @@ public class RepositoryFunctionTest extends BuildViewTestCase { } @Override - protected boolean isLocal() { + protected boolean isLocal(Rule rule) { return false; } diff --git a/src/test/shell/bazel/skylark_repository_test.sh b/src/test/shell/bazel/skylark_repository_test.sh index 7b8d6338ea..c84baf42a6 100755 --- a/src/test/shell/bazel/skylark_repository_test.sh +++ b/src/test/shell/bazel/skylark_repository_test.sh @@ -216,6 +216,39 @@ EOF expect_log "Tra-la!" } +function test_skylark_local_repository() { + create_new_workspace + repo2=$new_workspace_dir + + cat > BUILD <<'EOF' +genrule(name='bar', cmd='echo foo | tee $@', outs=['bar.txt']) +EOF + + cd ${WORKSPACE_DIR} + cat > WORKSPACE <test.bzl < BUILD + + bazel build @foo//:bar >& $TEST_log || fail "Failed to build" + expect_log "foo" + cat bazel-genfiles/external/foo/bar.txt >$TEST_log + expect_log "foo" +} + function tear_down() { true } -- cgit v1.2.3