Take #2 of add repo mapping to bazel context. This is so that @SkylarkCallable methods (Label.relative in particular) can have access to the repository mapping from the context to properly convert labels. Initial submit broke rules_go in downstream: https://buildkite.com/bazel/bazel-at-head-plus-downstream/builds/725#35b48f7f-3e95-4322-a360-88c6dc7fb748, but unknown commit fixed it. RELNOTES: None PiperOrigin-RevId: 228573949
diff --git a/src/main/java/com/google/devtools/build/lib/BUILD b/src/main/java/com/google/devtools/build/lib/BUILD index 800aa08..6a0faef 100644 --- a/src/main/java/com/google/devtools/build/lib/BUILD +++ b/src/main/java/com/google/devtools/build/lib/BUILD
@@ -387,6 +387,7 @@ ], deps = [ ":skylarkinterface", + "//src/main/java/com/google/devtools/build/lib/cmdline:RepositoryName", "//third_party:guava", "//third_party:jsr305", ],
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/ConfiguredRuleClassProvider.java b/src/main/java/com/google/devtools/build/lib/analysis/ConfiguredRuleClassProvider.java index b24da5e..3b52ea2 100644 --- a/src/main/java/com/google/devtools/build/lib/analysis/ConfiguredRuleClassProvider.java +++ b/src/main/java/com/google/devtools/build/lib/analysis/ConfiguredRuleClassProvider.java
@@ -39,6 +39,7 @@ import com.google.devtools.build.lib.cmdline.Label; import com.google.devtools.build.lib.cmdline.LabelSyntaxException; import com.google.devtools.build.lib.cmdline.PackageIdentifier; +import com.google.devtools.build.lib.cmdline.RepositoryName; import com.google.devtools.build.lib.events.EventHandler; import com.google.devtools.build.lib.graph.Digraph; import com.google.devtools.build.lib.graph.Node; @@ -795,9 +796,10 @@ SkylarkSemantics skylarkSemantics, EventHandler eventHandler, String astFileContentHashCode, - Map<String, Extension> importMap) { + Map<String, Extension> importMap, + ImmutableMap<RepositoryName, RepositoryName> repoMapping) { BazelStarlarkContext context = - new BazelStarlarkContext(toolsRepository, configurationFragmentMap); + new BazelStarlarkContext(toolsRepository, configurationFragmentMap, repoMapping); Environment env = Environment.builder(mutability) .setGlobals(globals) @@ -818,14 +820,16 @@ SkylarkSemantics skylarkSemantics, EventHandler eventHandler, String astFileContentHashCode, - Map<String, Extension> importMap) { + Map<String, Extension> importMap, + ImmutableMap<RepositoryName, RepositoryName> repoMapping) { return createSkylarkRuleClassEnvironment( mutability, globals.withLabel(extensionLabel), skylarkSemantics, eventHandler, astFileContentHashCode, - importMap); + importMap, + repoMapping); } @Override
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/skylark/BazelStarlarkContext.java b/src/main/java/com/google/devtools/build/lib/analysis/skylark/BazelStarlarkContext.java index 7ebf761..682e433 100644 --- a/src/main/java/com/google/devtools/build/lib/analysis/skylark/BazelStarlarkContext.java +++ b/src/main/java/com/google/devtools/build/lib/analysis/skylark/BazelStarlarkContext.java
@@ -15,6 +15,7 @@ package com.google.devtools.build.lib.analysis.skylark; import com.google.common.collect.ImmutableMap; +import com.google.devtools.build.lib.cmdline.RepositoryName; import com.google.devtools.build.lib.skylarkinterface.StarlarkContext; import java.util.Objects; import javax.annotation.Nullable; @@ -23,21 +24,28 @@ public class BazelStarlarkContext implements StarlarkContext { private final String toolsRepository; @Nullable private final ImmutableMap<String, Class<?>> fragmentNameToClass; + private final ImmutableMap<RepositoryName, RepositoryName> repoMapping; /** - * @param toolsRepository the name of the tools repository, such as "bazel_tools" + * @param toolsRepository the name of the tools repository, such as "@bazel_tools" * @param fragmentNameToClass a map from configuration fragment name to configuration fragment * class, such as "apple" to AppleConfiguration.class + * @param repoMapping a map from RepositoryName to RepositoryName to be used for external + * repository renaming */ public BazelStarlarkContext( - String toolsRepository, ImmutableMap<String, Class<?>> fragmentNameToClass) { + String toolsRepository, + ImmutableMap<String, Class<?>> fragmentNameToClass, + ImmutableMap<RepositoryName, RepositoryName> repoMapping) { this.toolsRepository = toolsRepository; this.fragmentNameToClass = fragmentNameToClass; + this.repoMapping = repoMapping; } /** @param toolsRepository the name of the tools repository, such as "bazel_tools" */ - public BazelStarlarkContext(String toolsRepository) { - this(toolsRepository, null); + public BazelStarlarkContext( + String toolsRepository, ImmutableMap<RepositoryName, RepositoryName> repoMapping) { + this(toolsRepository, null, repoMapping); } @Override @@ -50,12 +58,13 @@ } BazelStarlarkContext that = (BazelStarlarkContext) obj; return Objects.equals(this.toolsRepository, that.toolsRepository) - && Objects.equals(this.fragmentNameToClass, that.fragmentNameToClass); + && Objects.equals(this.fragmentNameToClass, that.fragmentNameToClass) + && Objects.equals(this.repoMapping, that.repoMapping); } @Override public int hashCode() { - return Objects.hash(toolsRepository, fragmentNameToClass); + return Objects.hash(toolsRepository, fragmentNameToClass, repoMapping); } /** Returns the name of the tools repository, such as "bazel_tools". */ @@ -67,4 +76,13 @@ public ImmutableMap<String, Class<?>> getFragmentNameToClass() { return fragmentNameToClass; } + + /** + * Returns a map of {@code RepositoryName}s where the keys are repository names that are + * written in the BUILD files and the values are new repository names chosen by the main + * repository. + */ + public ImmutableMap<RepositoryName, RepositoryName> getRepoMapping() { + return repoMapping; + } }
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkRuleConfiguredTargetUtil.java b/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkRuleConfiguredTargetUtil.java index 1883eba..df064a1 100644 --- a/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkRuleConfiguredTargetUtil.java +++ b/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkRuleConfiguredTargetUtil.java
@@ -103,7 +103,9 @@ .setCallerLabel(ruleContext.getLabel()) .setSemantics(skylarkSemantics) .setEventHandler(ruleContext.getAnalysisEnvironment().getEventHandler()) - .setStarlarkContext(new BazelStarlarkContext(toolsRepository)) + .setStarlarkContext( + new BazelStarlarkContext( + toolsRepository, ruleContext.getTarget().getPackage().getRepositoryMapping())) .build(); // NB: loading phase functions are not available: this is analysis already, // so we do *not* setLoadingPhase().
diff --git a/src/main/java/com/google/devtools/build/lib/cmdline/BUILD b/src/main/java/com/google/devtools/build/lib/cmdline/BUILD index a648ed3..4790cf3 100644 --- a/src/main/java/com/google/devtools/build/lib/cmdline/BUILD +++ b/src/main/java/com/google/devtools/build/lib/cmdline/BUILD
@@ -18,6 +18,7 @@ visibility = ["//src:__subpackages__"], deps = [ "//src/main/java/com/google/devtools/build/lib:skylarkinterface", + "//src/main/java/com/google/devtools/build/lib:starlark_context", "//src/main/java/com/google/devtools/build/lib:util", "//src/main/java/com/google/devtools/build/lib/actions:commandline_item", "//src/main/java/com/google/devtools/build/lib/concurrent", @@ -28,3 +29,23 @@ "//third_party:jsr305", ], ) + +java_library( + name = "RepositoryName", + srcs = [ + "LabelConstants.java", + "LabelSyntaxException.java", + "LabelValidator.java", + "PackageIdentifier.java", + "RepositoryName.java", + ], + visibility = ["//src:__subpackages__"], + deps = [ + "//src/main/java/com/google/devtools/build/lib:skylarkinterface", + "//src/main/java/com/google/devtools/build/lib:util", + "//src/main/java/com/google/devtools/build/lib/concurrent", + "//src/main/java/com/google/devtools/build/lib/skyframe/serialization/autocodec:autocodec-annotation", + "//src/main/java/com/google/devtools/build/lib/vfs:pathfragment", + "//third_party:guava", + ], +)
diff --git a/src/main/java/com/google/devtools/build/lib/cmdline/Label.java b/src/main/java/com/google/devtools/build/lib/cmdline/Label.java index 454dfe8..b0151b1 100644 --- a/src/main/java/com/google/devtools/build/lib/cmdline/Label.java +++ b/src/main/java/com/google/devtools/build/lib/cmdline/Label.java
@@ -19,6 +19,7 @@ import com.google.common.collect.ImmutableSet; import com.google.common.collect.Interner; import com.google.devtools.build.lib.actions.CommandLineItem; +import com.google.devtools.build.lib.analysis.skylark.BazelStarlarkContext; import com.google.devtools.build.lib.cmdline.LabelValidator.BadLabelException; import com.google.devtools.build.lib.concurrent.BlazeInterners; import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable; @@ -30,6 +31,7 @@ import com.google.devtools.build.lib.skylarkinterface.SkylarkModuleCategory; import com.google.devtools.build.lib.skylarkinterface.SkylarkPrinter; import com.google.devtools.build.lib.skylarkinterface.SkylarkValue; +import com.google.devtools.build.lib.skylarkinterface.StarlarkContext; import com.google.devtools.build.lib.util.StringUtilities; import com.google.devtools.build.lib.vfs.PathFragment; import com.google.devtools.build.skyframe.SkyFunctionName; @@ -506,33 +508,40 @@ * @param relName the relative label name; must be non-empty. */ @SkylarkCallable( - name = "relative", - doc = - "Resolves a label that is either absolute (starts with <code>//</code>) or relative to the" - + " current package. If this label is in a remote repository, the argument will be " - + " resolved relative to that repository. If the argument contains a repository, it" - + " will be returned as-is. Reserved labels will also be returned as-is.<br>" - + "For example:<br>" - + "<pre class=language-python>\n" - + "Label(\"//foo/bar:baz\").relative(\":quux\") == Label(\"//foo/bar:quux\")\n" - + "Label(\"//foo/bar:baz\").relative(\"//wiz:quux\") == Label(\"//wiz:quux\")\n" - + "Label(\"@repo//foo/bar:baz\").relative(\"//wiz:quux\") == " - + "Label(\"@repo//wiz:quux\")\n" - + "Label(\"@repo//foo/bar:baz\").relative(\"//visibility:public\") == " - + "Label(\"//visibility:public\")\n" - + "Label(\"@repo//foo/bar:baz\").relative(\"@other//wiz:quux\") == " - + "Label(\"@other//wiz:quux\")\n" - + "</pre>", - parameters = { - @Param( - name = "relName", - type = String.class, - doc = "The label that will be resolved relative to this one." - ) - } - ) - public Label getRelative(String relName) throws LabelSyntaxException { - return getRelativeWithRemapping(relName, /* repositoryMapping= */ ImmutableMap.of()); + name = "relative", + doc = + "Resolves a label that is either absolute (starts with <code>//</code>) or relative to " + + "the current package. If this label is in a remote repository, the argument will " + + "be resolved relative to that repository. If the argument contains a repository " + + "name, the current label is ignored and the argument is returned as-is, except " + + "that the repository name is rewritten if it is in the current repository mapping. " + + "Reserved labels will also be returned as-is.<br>" + + "For example:<br>" + + "<pre class=language-python>\n" + + "Label(\"//foo/bar:baz\").relative(\":quux\") == Label(\"//foo/bar:quux\")\n" + + "Label(\"//foo/bar:baz\").relative(\"//wiz:quux\") == Label(\"//wiz:quux\")\n" + + "Label(\"@repo//foo/bar:baz\").relative(\"//wiz:quux\") == " + + "Label(\"@repo//wiz:quux\")\n" + + "Label(\"@repo//foo/bar:baz\").relative(\"//visibility:public\") == " + + "Label(\"//visibility:public\")\n" + + "Label(\"@repo//foo/bar:baz\").relative(\"@other//wiz:quux\") == " + + "Label(\"@other//wiz:quux\")\n" + + "</pre>" + + "<p>If the repository mapping passed in is <code>{'@other' : '@remapped'}</code>, " + + "then the following remapping will take place:<br>" + + "<pre class=language-python>\n" + + "Label(\"@repo//foo/bar:baz\").relative(\"@other//wiz:quux\") == " + + "Label(\"@remapped//wiz:quux\")", + parameters = { + @Param( + name = "relName", + type = String.class, + doc = "The label that will be resolved relative to this one.") + }, + useContext = true) + public Label getRelative(String relName, StarlarkContext context) throws LabelSyntaxException { + BazelStarlarkContext bazelStarlarkContext = (BazelStarlarkContext) context; + return getRelativeWithRemapping(relName, bazelStarlarkContext.getRepoMapping()); } /**
diff --git a/src/main/java/com/google/devtools/build/lib/packages/PackageFactory.java b/src/main/java/com/google/devtools/build/lib/packages/PackageFactory.java index a3b02ce..b501ac5 100644 --- a/src/main/java/com/google/devtools/build/lib/packages/PackageFactory.java +++ b/src/main/java/com/google/devtools/build/lib/packages/PackageFactory.java
@@ -1618,7 +1618,7 @@ try (Mutability mutability = Mutability.create("package %s", packageId)) { BazelStarlarkContext starlarkContext = - new BazelStarlarkContext(ruleClassProvider.getToolsRepository()); + new BazelStarlarkContext(ruleClassProvider.getToolsRepository(), repositoryMapping); Environment pkgEnv = Environment.builder(mutability) .setGlobals(BazelLibrary.GLOBALS)
diff --git a/src/main/java/com/google/devtools/build/lib/packages/RuleClassProvider.java b/src/main/java/com/google/devtools/build/lib/packages/RuleClassProvider.java index 302b05b..97b8722 100644 --- a/src/main/java/com/google/devtools/build/lib/packages/RuleClassProvider.java +++ b/src/main/java/com/google/devtools/build/lib/packages/RuleClassProvider.java
@@ -14,7 +14,9 @@ package com.google.devtools.build.lib.packages; +import com.google.common.collect.ImmutableMap; import com.google.devtools.build.lib.cmdline.Label; +import com.google.devtools.build.lib.cmdline.RepositoryName; import com.google.devtools.build.lib.events.EventHandler; import com.google.devtools.build.lib.syntax.Environment; import com.google.devtools.build.lib.syntax.Environment.Extension; @@ -44,15 +46,16 @@ Map<String, RuleClass> getRuleClassMap(); /** - * Returns a new Skylark Environment instance for rule creation. - * Implementations need to be thread safe. - * Be sure to close() the mutability before you return the results of said evaluation. + * Returns a new Skylark Environment instance for rule creation. Implementations need to be thread + * safe. Be sure to close() the mutability before you return the results of said evaluation. * * @param label the location of the rule. * @param mutability the Mutability for the current evaluation context * @param skylarkSemantics the semantics options that modify the interpreter * @param eventHandler the EventHandler for warnings, errors, etc. * @param astFileContentHashCode the hash code identifying this environment. + * @param importMap map from import string to Extension + * @param repoMapping map of RepositoryNames to be remapped * @return an Environment, in which to evaluate load time skylark forms. */ Environment createSkylarkRuleClassEnvironment( @@ -61,7 +64,8 @@ SkylarkSemantics skylarkSemantics, EventHandler eventHandler, @Nullable String astFileContentHashCode, - @Nullable Map<String, Extension> importMap); + @Nullable Map<String, Extension> importMap, + ImmutableMap<RepositoryName, RepositoryName> repoMapping); /** * Returns a map from aspect names to aspect factory objects.
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/ASTFileLookupFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/ASTFileLookupFunction.java index 2248c16..4e4a32b 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/ASTFileLookupFunction.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/ASTFileLookupFunction.java
@@ -14,6 +14,7 @@ package com.google.devtools.build.lib.skyframe; +import com.google.common.collect.ImmutableMap; import com.google.devtools.build.lib.actions.FileValue; import com.google.devtools.build.lib.actions.InconsistentFilesystemException; import com.google.devtools.build.lib.cmdline.Label; @@ -120,9 +121,10 @@ mutability, skylarkSemantics, env.getListener(), - // the two below don't matter for extracting the ValidationEnvironment: + // the three below don't matter for extracting the ValidationEnvironment: /*astFileContentHashCode=*/ null, - /*importMap=*/ null) + /*importMap=*/ null, + /*repoMapping=*/ ImmutableMap.of()) .setupDynamic(Runtime.PKG_NAME, Runtime.NONE) .setupDynamic(Runtime.REPOSITORY_NAME, Runtime.NONE); byte[] bytes = FileSystemUtils.readWithKnownFileSize(path, astFileSize);
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/SkylarkImportLookupFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/SkylarkImportLookupFunction.java index 6de65cf..c6d05e1 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/SkylarkImportLookupFunction.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/SkylarkImportLookupFunction.java
@@ -266,13 +266,16 @@ // Process the load statements in the file. ImmutableList<SkylarkImport> unRemappedImports = ast.getImports(); - ImmutableList<SkylarkImport> imports = - remapImports(unRemappedImports, workspaceChunk, workspacePath, fileLabel, env); - // We do a skykey lookup in remapImports that might not be completed yet so if it returns null - // we need to stop the current computation - if (imports == null) { + ImmutableMap<RepositoryName, RepositoryName> repositoryMapping = + getRepositoryMapping(workspaceChunk, workspacePath, fileLabel, env); + + if (repositoryMapping == null) { return null; } + + ImmutableList<SkylarkImport> imports = + remapImports(unRemappedImports, workspaceChunk, repositoryMapping); + ImmutableMap<String, Label> labelsForImports = getLabelsForLoadStatements(imports, fileLabel); ImmutableCollection<Label> importLabels = labelsForImports.values(); @@ -371,52 +374,30 @@ // #createExtension does not request values from the Environment. It may post events to the // Environment, but events do not matter when caching SkylarkImportLookupValues. Extension extension = - createExtension(ast, fileLabel, extensionsForImports, skylarkSemantics, env, inWorkspace); + createExtension( + ast, + fileLabel, + extensionsForImports, + skylarkSemantics, + env, + inWorkspace, + repositoryMapping); SkylarkImportLookupValue result = new SkylarkImportLookupValue( extension, new SkylarkFileDependency(fileLabel, fileDependencies.build())); return result; } - /** - * This method takes in a list of {@link SkylarkImport}s (load statements) as they appear in the - * BUILD, bzl, or WORKSPACE file they originated from and optionally remaps the load statements - * using the repository mappings provided in the WORKSPACE file. - * - * <p>If the {@link SkylarkImport}s originated from a WORKSPACE file, then the repository mappings - * are pulled from the previous {@link WorkspaceFileValue}. If they didn't originate from a - * WORKSPACE file then the repository mappings are pulled from the fully computed {@link - * RepositoryMappingValue}. - * - * <p>There is a chance that SkyValues requested are not yet computed and so SkyFunction callers - * of this method need to check if the return value is null and then return null themselves. - * - * @param unRemappedImports the list of load statements to be remapped - * @param workspaceChunk the workspaceChunk we are currently evaluating that this load statement - * originated from. WORKSPACE files are chunked at every non-consecutive load statement and - * evaluated separately. See {@link WorkspaceFileValue} for more information. - * @param workspacePath the path of the project's WORKSPACE file - * @param enclosingFileLabel the label of the file (bzl, WORKSPACE, BUILD) that this load - * statement appeared in - * @param env the Skyframe used to ask for additional SkyValues - * @return a list of remapped {@link SkylarkImport}s or null if any SkyValue requested wasn't - * fully computed yet - * @throws InterruptedException - */ - private ImmutableList<SkylarkImport> remapImports( - ImmutableList<SkylarkImport> unRemappedImports, - int workspaceChunk, - RootedPath workspacePath, - Label enclosingFileLabel, - Environment env) + private ImmutableMap<RepositoryName, RepositoryName> getRepositoryMapping( + int workspaceChunk, RootedPath workspacePath, Label enclosingFileLabel, Environment env) throws InterruptedException { // There is no previous workspace chunk if (workspaceChunk == 0) { - return unRemappedImports; + return ImmutableMap.of(); } - ImmutableMap<RepositoryName, RepositoryName> repositoryMapping; + ImmutableMap<RepositoryName, RepositoryName> repositoryMapping; // We are fully done with workspace evaluation so we should get the mappings from the // final RepositoryMappingValue if (workspaceChunk == -1) { @@ -439,6 +420,41 @@ .getOrDefault( enclosingFileLabel.getPackageIdentifier().getRepository(), ImmutableMap.of()); } + return repositoryMapping; + } + + /** + * This method takes in a list of {@link SkylarkImport}s (load statements) as they appear in the + * BUILD, bzl, or WORKSPACE file they originated from and optionally remaps the load statements + * using the repository mappings provided in the WORKSPACE file. + * + * <p>If the {@link SkylarkImport}s originated from a WORKSPACE file, then the repository mappings + * are pulled from the previous {@link WorkspaceFileValue}. If they didn't originate from a + * WORKSPACE file then the repository mappings are pulled from the fully computed {@link + * RepositoryMappingValue}. + * + * <p>There is a chance that SkyValues requested are not yet computed and so SkyFunction callers + * of this method need to check if the return value is null and then return null themselves. + * + * @param unRemappedImports the list of load statements to be remapped + * @param workspaceChunk the workspaceChunk we are currently evaluating that this load statement + * originated from. WORKSPACE files are chunked at every non-consecutive load statement and + * evaluated separately. See {@link WorkspaceFileValue} for more information. + * @param repositoryMapping map from original repository names to new repository names given + * by the main repository + * @return a list of remapped {@link SkylarkImport}s or null if any SkyValue requested wasn't + * fully computed yet + * @throws InterruptedException + */ + private ImmutableList<SkylarkImport> remapImports( + ImmutableList<SkylarkImport> unRemappedImports, + int workspaceChunk, + ImmutableMap<RepositoryName, RepositoryName> repositoryMapping) { + + // There is no previous workspace chunk + if (workspaceChunk == 0) { + return unRemappedImports; + } ImmutableList.Builder<SkylarkImport> builder = ImmutableList.builder(); for (SkylarkImport notRemappedImport : unRemappedImports) { @@ -475,16 +491,15 @@ (oldLabel, newLabel) -> oldLabel)); } - /** - * Creates the Extension to be imported. - */ + /** Creates the Extension to be imported. */ private Extension createExtension( BuildFileAST ast, Label extensionLabel, Map<String, Extension> importMap, SkylarkSemantics skylarkSemantics, Environment env, - boolean inWorkspace) + boolean inWorkspace, + ImmutableMap<RepositoryName, RepositoryName> repositoryMapping) throws SkylarkImportFailedException, InterruptedException { StoredEventHandler eventHandler = new StoredEventHandler(); // TODO(bazel-team): this method overestimates the changes which can affect the @@ -494,10 +509,14 @@ PathFragment extensionFile = extensionLabel.toPathFragment(); try (Mutability mutability = Mutability.create("importing %s", extensionFile)) { com.google.devtools.build.lib.syntax.Environment extensionEnv = - ruleClassProvider - .createSkylarkRuleClassEnvironment( - extensionLabel, mutability, skylarkSemantics, - eventHandler, ast.getContentHashCode(), importMap); + ruleClassProvider.createSkylarkRuleClassEnvironment( + extensionLabel, + mutability, + skylarkSemantics, + eventHandler, + ast.getContentHashCode(), + importMap, + repositoryMapping); extensionEnv.setupOverride("native", packageFactory.getNativeModule(inWorkspace)); execAndExport(ast, extensionLabel, eventHandler, extensionEnv);
diff --git a/src/main/java/com/google/devtools/build/skydoc/BUILD b/src/main/java/com/google/devtools/build/skydoc/BUILD index 869ea9b..c6e3688 100644 --- a/src/main/java/com/google/devtools/build/skydoc/BUILD +++ b/src/main/java/com/google/devtools/build/skydoc/BUILD
@@ -51,6 +51,7 @@ srcs = glob(["*.java"]), visibility = ["//src/test:__subpackages__"], deps = [ + "//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:skylark_semantics", "//src/main/java/com/google/devtools/build/lib:skylark_semantics_options",
diff --git a/src/main/java/com/google/devtools/build/skydoc/SkydocMain.java b/src/main/java/com/google/devtools/build/skydoc/SkydocMain.java index f298430..bb64b94 100644 --- a/src/main/java/com/google/devtools/build/skydoc/SkydocMain.java +++ b/src/main/java/com/google/devtools/build/skydoc/SkydocMain.java
@@ -19,6 +19,7 @@ import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; +import com.google.devtools.build.lib.analysis.skylark.BazelStarlarkContext; import com.google.devtools.build.lib.cmdline.Label; import com.google.devtools.build.lib.cmdline.LabelSyntaxException; import com.google.devtools.build.lib.events.EventHandler; @@ -384,7 +385,9 @@ Map<String, Extension> imports = new HashMap<>(); for (SkylarkImport anImport : buildFileAST.getImports()) { - Label relativeLabel = label.getRelative(anImport.getImportString()); + BazelStarlarkContext context = + new BazelStarlarkContext("", ImmutableMap.of(), ImmutableMap.of()); + Label relativeLabel = label.getRelative(anImport.getImportString(), context); try { Environment importEnv =
diff --git a/src/test/java/com/google/devtools/build/lib/cmdline/LabelTest.java b/src/test/java/com/google/devtools/build/lib/cmdline/LabelTest.java index ea74305..c5ad4da 100644 --- a/src/test/java/com/google/devtools/build/lib/cmdline/LabelTest.java +++ b/src/test/java/com/google/devtools/build/lib/cmdline/LabelTest.java
@@ -167,6 +167,32 @@ } @Test + public void testGetRelativeWithoutRemappingBaseLabel() throws Exception { + PackageIdentifier packageId = PackageIdentifier.create("@a", PathFragment.create("foo")); + Label base = Label.create(packageId, "bar"); + ImmutableMap<RepositoryName, RepositoryName> repoMapping = + ImmutableMap.of(RepositoryName.create("@a"), RepositoryName.create("@b")); + Label relative = base.getRelativeWithRemapping(":y", repoMapping); + + // getRelative should only remap repositories passed in the string arg and not + // make changes to existing Labels + Label actual = Label.parseAbsoluteUnchecked("@a//foo:y"); + assertThat(relative).isEqualTo(actual); + } + + @Test + public void testGetRelativeWithDifferentRepoAndRemapping() throws Exception { + PackageIdentifier packageId = PackageIdentifier.create("@repo", PathFragment.create("foo")); + Label base = Label.create(packageId, "bar"); + ImmutableMap<RepositoryName, RepositoryName> repoMapping = + ImmutableMap.of(RepositoryName.create("@a"), RepositoryName.create("@b")); + Label relative = base.getRelativeWithRemapping("@a//x:y", repoMapping); + + Label actual = Label.parseAbsoluteUnchecked("@b//x:y"); + assertThat(relative).isEqualTo(actual); + } + + @Test public void testGetRelativeWithRepoLocalAbsoluteLabel() throws Exception { PackageIdentifier packageId = PackageIdentifier.create("@repo", PathFragment.create("foo")); Label base = Label.create(packageId, "bar");
diff --git a/src/test/java/com/google/devtools/build/lib/skylark/util/SkylarkTestCase.java b/src/test/java/com/google/devtools/build/lib/skylark/util/SkylarkTestCase.java index 94043f5..e12e982 100644 --- a/src/test/java/com/google/devtools/build/lib/skylark/util/SkylarkTestCase.java +++ b/src/test/java/com/google/devtools/build/lib/skylark/util/SkylarkTestCase.java
@@ -68,7 +68,9 @@ return new EvaluationTestCase() { @Override public Environment newEnvironment() throws Exception { - BazelStarlarkContext context = new BazelStarlarkContext(TestConstants.TOOLS_REPOSITORY); + BazelStarlarkContext context = + new BazelStarlarkContext( + TestConstants.TOOLS_REPOSITORY, /*repoMapping=*/ ImmutableMap.of()); Environment env = Environment.builder(mutability) .setSemantics(semantics)
diff --git a/src/test/java/com/google/devtools/build/lib/syntax/util/EvaluationTestCase.java b/src/test/java/com/google/devtools/build/lib/syntax/util/EvaluationTestCase.java index f7f8ee8..4da0657 100644 --- a/src/test/java/com/google/devtools/build/lib/syntax/util/EvaluationTestCase.java +++ b/src/test/java/com/google/devtools/build/lib/syntax/util/EvaluationTestCase.java
@@ -64,7 +64,9 @@ * No PythonPreprocessing, mostly empty mutable Environment. */ public Environment newBuildEnvironment() { - BazelStarlarkContext context = new BazelStarlarkContext(TestConstants.TOOLS_REPOSITORY); + BazelStarlarkContext context = + new BazelStarlarkContext( + TestConstants.TOOLS_REPOSITORY, /* repoMapping= */ ImmutableMap.of()); Environment env = Environment.builder(mutability) .useDefaultSemantics()
diff --git a/src/test/shell/bazel/workspace_test.sh b/src/test/shell/bazel/workspace_test.sh index 43bf32e..59e4dff 100755 --- a/src/test/shell/bazel/workspace_test.sh +++ b/src/test/shell/bazel/workspace_test.sh
@@ -574,6 +574,40 @@ || fail "Expected srcs to contain '@b//:x.txt'" } +function test_remapping_with_label_relative() { + # create foo repository + mkdir foo + touch foo/WORKSPACE + cat >foo/foo.bzl <<EOF +x = Label("//blah:blah").relative("@a//:baz") +print(x) +EOF + cat >foo/BUILD <<EOF +load(":foo.bzl", "x") +genrule( + name = "bar", + outs = ["xyz"], + cmd = "touch \$(location xyz)", + visibility = ["//visibility:public"] +) +EOF + + # Main repo assigns @a to @b within @foo + mkdir -p main + cat >main/WORKSPACE <<EOF +workspace(name = "main") +local_repository(name = "foo", path="../foo", repo_mapping = {"@a" : "@b"}) +local_repository(name = "b", path="../b") +EOF + touch main/BUILD + + cd main + bazel build --experimental_enable_repo_mapping @foo//:bar \ + >& "$TEST_log" || fail "Expected build to succeed" + expect_log "@b//:baz" + expect_not_log "@a//:baz" +} + function test_workspace_addition_change_aspect() { mkdir -p repo_one mkdir -p repo_two