aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java
diff options
context:
space:
mode:
authorGravatar dannark <dannark@google.com>2018-06-12 09:28:45 -0700
committerGravatar Copybara-Service <copybara-piper@google.com>2018-06-12 09:30:48 -0700
commitf4b9ff40b8f1612571cc711560177af240d034d0 (patch)
tree2b2bf5415d7b4a0ab5db78d916cebfec0775f810 /src/main/java
parent1b94e64ee8a1d385e92a8d9f4c9a06e2d99c82bf (diff)
Remap repository names inside load statements in BUILD files if the repository name is remapped.
For example if main/WORKSPACE contains: local_repository( name = "a", path = "../a", repo_mapping = {"@x" : "@y"}, ) a/BUILD load("@x//:sample.bzl", "sample") Then the load in a/BUILD will be resolved as "@y//:sample.bzl" RELNOTES: None PiperOrigin-RevId: 200227431
Diffstat (limited to 'src/main/java')
-rw-r--r--src/main/java/com/google/devtools/build/lib/analysis/BuildView.java4
-rw-r--r--src/main/java/com/google/devtools/build/lib/cmdline/Label.java40
-rw-r--r--src/main/java/com/google/devtools/build/lib/packages/PackageFactory.java21
-rw-r--r--src/main/java/com/google/devtools/build/lib/skyframe/PackageFunction.java2
-rw-r--r--src/main/java/com/google/devtools/build/lib/skyframe/WorkspaceASTFunction.java15
-rw-r--r--src/main/java/com/google/devtools/build/lib/syntax/BuildFileAST.java60
-rw-r--r--src/main/java/com/google/devtools/build/lib/syntax/SkylarkImports.java27
7 files changed, 133 insertions, 36 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/BuildView.java b/src/main/java/com/google/devtools/build/lib/analysis/BuildView.java
index 2651e65d82..4e1d59e9e3 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/BuildView.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/BuildView.java
@@ -539,7 +539,9 @@ public class BuildView {
}
SkylarkImport skylarkImport;
try {
- skylarkImport = SkylarkImports.create(bzlFileLoadLikeString);
+ skylarkImport =
+ SkylarkImports.create(
+ bzlFileLoadLikeString, /* repositoryMapping= */ ImmutableMap.of());
} catch (SkylarkImportSyntaxException e) {
throw new ViewCreationFailedException(
String.format("Invalid aspect '%s': %s", aspect, e.getMessage()), e);
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 61805ca5ae..9d14e6d7d8 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
@@ -15,6 +15,7 @@ package com.google.devtools.build.lib.cmdline;
import com.google.common.base.Preconditions;
import com.google.common.collect.ComparisonChain;
+import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Interner;
import com.google.devtools.build.lib.actions.CommandLineItem;
@@ -115,8 +116,36 @@ public final class Label
*
* @param defaultToMain Treat labels in the default repository as being in the main one instead.
*/
+ @Deprecated
+ // TODO(dannark): Remove usages of this method, use other parseAbsolute() instead
public static Label parseAbsolute(String absName, boolean defaultToMain)
throws LabelSyntaxException {
+ return parseAbsolute(absName, defaultToMain, /* repositoryMapping= */ ImmutableMap.of());
+ }
+
+ /**
+ * Factory for Labels from absolute string form. e.g.
+ *
+ * <pre>
+ * //foo/bar
+ * //foo/bar:quux
+ * {@literal @}foo
+ * {@literal @}foo//bar
+ * {@literal @}foo//bar:baz
+ * </pre>
+ *
+ * <p>Labels that begin with a repository name may have the repository name remapped to a
+ * different name if it appears in {@code repositoryMapping}. This happens if the current
+ * repository being evaluated is external to the main repository and the main repository set the
+ * {@code repo_mapping} attribute when declaring this repository.
+ *
+ * @param defaultToMain Treat labels in the default repository as being in the main one instead.
+ */
+ public static Label parseAbsolute(
+ String absName,
+ boolean defaultToMain,
+ ImmutableMap<RepositoryName, RepositoryName> repositoryMapping)
+ throws LabelSyntaxException {
String repo = defaultToMain ? "@" : RepositoryName.DEFAULT_REPOSITORY;
int packageStartPos = absName.indexOf("//");
if (packageStartPos > 0) {
@@ -134,12 +163,21 @@ public final class Label
if (repo.isEmpty() && ABSOLUTE_PACKAGE_NAMES.contains(packageFragment)) {
repo = "@";
}
- return create(PackageIdentifier.create(repo, packageFragment), labelParts.getTargetName());
+ RepositoryName globalRepoName = getGlobalRepoName(repo, repositoryMapping);
+ return create(
+ PackageIdentifier.create(globalRepoName, packageFragment), labelParts.getTargetName());
} catch (BadLabelException e) {
throw new LabelSyntaxException(e.getMessage());
}
}
+ private static RepositoryName getGlobalRepoName(
+ String repo, ImmutableMap<RepositoryName, RepositoryName> repositoryMapping)
+ throws LabelSyntaxException {
+ RepositoryName repoName = RepositoryName.create(repo);
+ return repositoryMapping.getOrDefault(repoName, repoName);
+ }
+
/**
* Alternate factory method for Labels from absolute strings. This is a convenience method for
* cases when a Label needs to be initialized statically, so the declared exception is
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 d9da36f945..108a0cf426 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
@@ -1246,12 +1246,17 @@ public final class PackageFactory {
// Run the lexer and parser with a local reporter, so that errors from other threads do not
// show up below.
BuildFileAST buildFileAST =
- parseBuildFile(packageId, input, preludeStatements, localReporterForParsing);
+ parseBuildFile(
+ packageId,
+ input,
+ preludeStatements,
+ /* repositoryMapping= */ ImmutableMap.of(),
+ localReporterForParsing);
AstParseResult astParseResult =
new AstParseResult(buildFileAST, localReporterForParsing);
return createPackageFromAst(
workspaceName,
- /*repositoryMapping=*/ ImmutableMap.of(),
+ /* repositoryMapping= */ ImmutableMap.of(),
packageId,
buildFile,
astParseResult,
@@ -1266,10 +1271,12 @@ public final class PackageFactory {
PackageIdentifier packageId,
ParserInputSource in,
List<Statement> preludeStatements,
+ ImmutableMap<RepositoryName, RepositoryName> repositoryMapping,
ExtendedEventHandler eventHandler) {
// Logged messages are used as a testability hook tracing the parsing progress
logger.fine("Starting to parse " + packageId);
- BuildFileAST buildFileAST = BuildFileAST.parseBuildFile(in, preludeStatements, eventHandler);
+ BuildFileAST buildFileAST =
+ BuildFileAST.parseBuildFile(in, preludeStatements, repositoryMapping, eventHandler);
logger.fine("Finished parsing of " + packageId);
return buildFileAST;
}
@@ -1373,10 +1380,10 @@ public final class PackageFactory {
packageId,
buildFile,
input,
- /*preludeStatements=*/ ImmutableList.<Statement>of(),
- /*imports=*/ ImmutableMap.<String, Extension>of(),
- /*skylarkFileDependencies=*/ ImmutableList.<Label>of(),
- /*defaultVisibility=*/ ConstantRuleVisibility.PUBLIC,
+ /* preludeStatements= */ ImmutableList.<Statement>of(),
+ /* imports= */ ImmutableMap.<String, Extension>of(),
+ /* skylarkFileDependencies= */ ImmutableList.<Label>of(),
+ /* defaultVisibility= */ ConstantRuleVisibility.PUBLIC,
semantics,
globber)
.build();
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/PackageFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/PackageFunction.java
index 05189fb12c..ce4116cc57 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/PackageFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/PackageFunction.java
@@ -1220,7 +1220,7 @@ public class PackageFunction implements SkyFunction {
StoredEventHandler astParsingEventHandler = new StoredEventHandler();
BuildFileAST ast =
PackageFactory.parseBuildFile(
- packageId, input, preludeStatements, astParsingEventHandler);
+ packageId, input, preludeStatements, repositoryMapping, astParsingEventHandler);
astParseResult = new AstParseResult(ast, astParsingEventHandler);
astCache.put(packageId, astParseResult);
}
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/WorkspaceASTFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/WorkspaceASTFunction.java
index a8d14cae61..d2e7ce8741 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/WorkspaceASTFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/WorkspaceASTFunction.java
@@ -15,6 +15,7 @@
package com.google.devtools.build.lib.skyframe;
import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
import com.google.devtools.build.lib.actions.FileValue;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.packages.BuildFileContainsErrorsException;
@@ -73,6 +74,7 @@ public class WorkspaceASTFunction implements SkyFunction {
BuildFileAST.parseBuildFile(
ParserInputSource.create(bytes, repoWorkspace.asFragment()),
ast.getStatements(),
+ /* repositoryMapping= */ ImmutableMap.of(),
env.getListener());
if (ast.containsErrors()) {
throw new WorkspaceASTFunctionException(
@@ -81,11 +83,14 @@ public class WorkspaceASTFunction implements SkyFunction {
Transience.PERSISTENT);
}
}
- ast = BuildFileAST.parseBuildFile(
- ParserInputSource.create(ruleClassProvider.getDefaultWorkspaceSuffix(),
- PathFragment.create("/DEFAULT.WORKSPACE.SUFFIX")),
- ast.getStatements(),
- env.getListener());
+ ast =
+ BuildFileAST.parseBuildFile(
+ ParserInputSource.create(
+ ruleClassProvider.getDefaultWorkspaceSuffix(),
+ PathFragment.create("/DEFAULT.WORKSPACE.SUFFIX")),
+ ast.getStatements(),
+ /* repositoryMapping= */ ImmutableMap.of(),
+ env.getListener());
if (ast.containsErrors()) {
throw new WorkspaceASTFunctionException(
new BuildFileContainsErrorsException(
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/BuildFileAST.java b/src/main/java/com/google/devtools/build/lib/syntax/BuildFileAST.java
index ca6307fa8a..801013b207 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/BuildFileAST.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/BuildFileAST.java
@@ -16,7 +16,9 @@ package com.google.devtools.build.lib.syntax;
import com.google.common.base.Joiner;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
import com.google.common.hash.HashCode;
+import com.google.devtools.build.lib.cmdline.RepositoryName;
import com.google.devtools.build.lib.events.Event;
import com.google.devtools.build.lib.events.EventHandler;
import com.google.devtools.build.lib.events.Location;
@@ -68,6 +70,7 @@ public class BuildFileAST extends ASTNode {
List<Statement> preludeStatements,
ParseResult result,
String contentHashCode,
+ ImmutableMap<RepositoryName, RepositoryName> repositoryMapping,
EventHandler eventHandler) {
ImmutableList<Statement> statements =
ImmutableList.<Statement>builder()
@@ -77,7 +80,7 @@ public class BuildFileAST extends ASTNode {
boolean containsErrors = result.containsErrors;
Pair<Boolean, ImmutableList<SkylarkImport>> skylarkImports =
- fetchLoads(statements, eventHandler);
+ fetchLoads(statements, repositoryMapping, eventHandler);
containsErrors |= skylarkImports.first;
return new BuildFileAST(
statements,
@@ -99,7 +102,7 @@ public class BuildFileAST extends ASTNode {
if (stmt instanceof LoadStatement) {
String str = ((LoadStatement) stmt).getImport().getValue();
try {
- imports.add(SkylarkImports.create(str));
+ imports.add(SkylarkImports.create(str, /* repositoryMapping= */ ImmutableMap.of()));
} catch (SkylarkImportSyntaxException e) {
throw new IllegalStateException(
"Cannot create SkylarImport for '" + str + "'. This is an internal error.");
@@ -120,14 +123,16 @@ public class BuildFileAST extends ASTNode {
* imports that could be resolved.
*/
private static Pair<Boolean, ImmutableList<SkylarkImport>> fetchLoads(
- List<Statement> statements, EventHandler eventHandler) {
+ List<Statement> statements,
+ ImmutableMap<RepositoryName, RepositoryName> repositoryMapping,
+ EventHandler eventHandler) {
ImmutableList.Builder<SkylarkImport> imports = ImmutableList.builder();
boolean error = false;
for (Statement stmt : statements) {
if (stmt instanceof LoadStatement) {
String importString = ((LoadStatement) stmt).getImport().getValue();
try {
- imports.add(SkylarkImports.create(importString));
+ imports.add(SkylarkImports.create(importString, repositoryMapping));
} catch (SkylarkImportSyntaxException e) {
eventHandler.handle(Event.error(stmt.getLocation(), e.getMessage()));
error = true;
@@ -272,20 +277,28 @@ public class BuildFileAST extends ASTNode {
}
/**
- * Parse the specified build file, returning its AST. All errors during
- * scanning or parsing will be reported to the reporter.
+ * Parse the specified build file, returning its AST. All errors during scanning or parsing will
+ * be reported to the reporter.
*/
- public static BuildFileAST parseBuildFile(ParserInputSource input,
- List<Statement> preludeStatements,
- EventHandler eventHandler) {
+ public static BuildFileAST parseBuildFile(
+ ParserInputSource input,
+ List<Statement> preludeStatements,
+ ImmutableMap<RepositoryName, RepositoryName> repositoryMapping,
+ EventHandler eventHandler) {
Parser.ParseResult result = Parser.parseFile(input, eventHandler);
- return create(preludeStatements, result, /*contentHashCode=*/ null, eventHandler)
+ return create(
+ preludeStatements, result, /* contentHashCode= */ null, repositoryMapping, eventHandler)
.validateBuildFile(eventHandler);
}
public static BuildFileAST parseBuildFile(ParserInputSource input, EventHandler eventHandler) {
Parser.ParseResult result = Parser.parseFile(input, eventHandler);
- return create(ImmutableList.<Statement>of(), result, /*contentHashCode=*/ null, eventHandler)
+ return create(
+ /* preludeStatements= */ ImmutableList.<Statement>of(),
+ result,
+ /* contentHashCode= */ null,
+ /* repositoryMapping= */ ImmutableMap.of(),
+ eventHandler)
.validateBuildFile(eventHandler);
}
@@ -295,13 +308,21 @@ public class BuildFileAST extends ASTNode {
ParserInputSource input = ParserInputSource.create(bytes, path);
Parser.ParseResult result = Parser.parseFile(input, eventHandler);
return create(
- ImmutableList.of(), result,
- HashCode.fromBytes(digest).toString(), eventHandler);
+ /* preludeStatements= */ ImmutableList.of(),
+ result,
+ HashCode.fromBytes(digest).toString(),
+ /* repositoryMapping= */ ImmutableMap.of(),
+ eventHandler);
}
public static BuildFileAST parseSkylarkFile(ParserInputSource input, EventHandler eventHandler) {
Parser.ParseResult result = Parser.parseFile(input, eventHandler);
- return create(ImmutableList.<Statement>of(), result, /*contentHashCode=*/ null, eventHandler);
+ return create(
+ /* preludeStatements= */ ImmutableList.<Statement>of(),
+ result,
+ /* contentHashCode= */ null,
+ /* repositoryMapping= */ ImmutableMap.of(),
+ eventHandler);
}
/**
@@ -320,10 +341,10 @@ public class BuildFileAST extends ASTNode {
.addAll(result.statements)
.build(),
result.containsErrors,
- /*contentHashCode=*/null,
+ /* contentHashCode= */null,
result.location,
ImmutableList.copyOf(result.comments),
- /*imports=*/null);
+ /* imports= */null);
}
/**
@@ -356,7 +377,12 @@ public class BuildFileAST extends ASTNode {
String str = Joiner.on("\n").join(content);
ParserInputSource input = ParserInputSource.create(str, PathFragment.EMPTY_FRAGMENT);
Parser.ParseResult result = Parser.parseFile(input, eventHandler);
- return create(ImmutableList.of(), result, null, eventHandler);
+ return create(
+ /* preludeStatements= */ ImmutableList.of(),
+ result,
+ /* contentHashCode= */ null,
+ /* repositoryMapping= */ ImmutableMap.of(),
+ eventHandler);
}
public static BuildFileAST parseBuildString(EventHandler eventHandler, String... content) {
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/SkylarkImports.java b/src/main/java/com/google/devtools/build/lib/syntax/SkylarkImports.java
index 71f1bffc8d..6cedeed40a 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/SkylarkImports.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/SkylarkImports.java
@@ -14,10 +14,12 @@
package com.google.devtools.build.lib.syntax;
import com.google.common.annotations.VisibleForTesting;
+import com.google.common.collect.ImmutableMap;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.cmdline.LabelSyntaxException;
import com.google.devtools.build.lib.cmdline.LabelValidator;
import com.google.devtools.build.lib.cmdline.PackageIdentifier;
+import com.google.devtools.build.lib.cmdline.RepositoryName;
import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;
import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec.VisibleForSerialization;
import com.google.devtools.build.lib.vfs.PathFragment;
@@ -235,18 +237,35 @@ public class SkylarkImports {
/**
* Creates and syntactically validates a {@link SkylarkImports} instance from a string.
- * <p>
- * There four syntactic import variants: Absolute paths, relative paths, absolute labels, and
- * relative labels
+ *
+ * <p>There are four syntactic import variants: Absolute paths, relative paths, absolute labels,
+ * and relative labels
*
* @throws SkylarkImportSyntaxException if the string is not a valid Skylark import.
*/
public static SkylarkImport create(String importString) throws SkylarkImportSyntaxException {
+ return create(importString, /* repositoryMapping= */ ImmutableMap.of());
+ }
+
+ /**
+ * Creates and syntactically validates a {@link SkylarkImports} instance from a string.
+ *
+ * <p>There four syntactic import variants: Absolute paths, relative paths, absolute labels, and
+ * relative labels
+ *
+ * <p>Absolute labels will have the repository portion of the label remapped if it is present in
+ * {@code repositoryMapping}
+ *
+ * @throws SkylarkImportSyntaxException if the string is not a valid Skylark import.
+ */
+ public static SkylarkImport create(
+ String importString, ImmutableMap<RepositoryName, RepositoryName> repositoryMapping)
+ throws SkylarkImportSyntaxException {
if (importString.startsWith("//") || importString.startsWith("@")) {
// Absolute label.
Label importLabel;
try {
- importLabel = Label.parseAbsolute(importString, false);
+ importLabel = Label.parseAbsolute(importString, false, repositoryMapping);
} catch (LabelSyntaxException e) {
throw new SkylarkImportSyntaxException(INVALID_LABEL_PREFIX + e.getMessage());
}