diff options
author | Damien Martin-Guillerez <dmarting@google.com> | 2016-03-31 20:18:10 +0000 |
---|---|---|
committer | Damien Martin-Guillerez <dmarting@google.com> | 2016-03-31 20:29:07 +0000 |
commit | c7009b3663f9fa2aebda94e0a6c189289b0514bb (patch) | |
tree | 56d183c4c9cbcefe4bf104b6cf0fce4985dcecb5 /src/main | |
parent | cdb49c5e8392132a868c6199e617951c0aa268e1 (diff) |
Support labels in new_{http,local}_repository's build_file attribute
Fixes #855.
--
MOS_MIGRATED_REVID=118711400
Diffstat (limited to 'src/main')
4 files changed, 59 insertions, 24 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/workspace/NewGitRepositoryRule.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/workspace/NewGitRepositoryRule.java index ae264bc248..5dcc27b18f 100644 --- a/src/main/java/com/google/devtools/build/lib/bazel/rules/workspace/NewGitRepositoryRule.java +++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/workspace/NewGitRepositoryRule.java @@ -56,9 +56,9 @@ public class NewGitRepositoryRule implements RuleDefinition { <p>Either build_file or build_file_content must be specified.</p> - <p>This path is relative to the build's workspace. The file does not need to be named - BUILD, but can be something like BUILD.new-repo-name to distinguish it - from the workspace's actual BUILD files.</p> + <p>This attribute is a label relative to the main workspace. The file does not need to be + named BUILD, but can be (something like BUILD.new-repo-name may work well for + distinguishing it from the repository's actual BUILD files.</p> <!-- #END_BLAZE_RULE.ATTRIBUTE --> */ .add(attr("build_file", STRING)) /* <!-- #BLAZE_RULE(new_git_repository).ATTRIBUTE(build_file_content) --> diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/workspace/NewHttpArchiveRule.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/workspace/NewHttpArchiveRule.java index 459f80527e..3913004b53 100644 --- a/src/main/java/com/google/devtools/build/lib/bazel/rules/workspace/NewHttpArchiveRule.java +++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/workspace/NewHttpArchiveRule.java @@ -53,9 +53,9 @@ public class NewHttpArchiveRule implements RuleDefinition { <p>Either build_file or build_file_content must be specified.</p> - <p>This path is relative to the build's workspace. The file does not need to be named - BUILD, but can be something like BUILD.new-repo-name to distinguish it - from the workspace's actual BUILD files.</p> + <p>This attribute is a label relative to the main workspace. The file does not need to be + named BUILD, but can be (something like BUILD.new-repo-name may work well for + distinguishing it from the repository's actual BUILD files.</p> <!-- #END_BLAZE_RULE.ATTRIBUTE --> */ .add(attr("build_file", STRING)) /* <!-- #BLAZE_RULE(new_http_archive).ATTRIBUTE(build_file_content) --> diff --git a/src/main/java/com/google/devtools/build/lib/rules/repository/NewLocalRepositoryRule.java b/src/main/java/com/google/devtools/build/lib/rules/repository/NewLocalRepositoryRule.java index baef7788e8..a83091edaf 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/repository/NewLocalRepositoryRule.java +++ b/src/main/java/com/google/devtools/build/lib/rules/repository/NewLocalRepositoryRule.java @@ -43,9 +43,9 @@ public class NewLocalRepositoryRule implements RuleDefinition { <p>Either build_file or build_file_content must be specified.</p> - <p>This path is relative to the build's workspace. The file does not need to be named - BUILD, but can be (something like BUILD.new-repo-name may work well for distinguishing it - from the repository's actual BUILD files.</p> + <p>This attribute is a label relative to the main workspace. The file does not need to be + named BUILD, but can be (something like BUILD.new-repo-name may work well for + distinguishing it from the repository's actual BUILD files.</p> <!-- #END_BLAZE_RULE.ATTRIBUTE --> */ .add(attr("build_file", STRING)) /* <!-- #BLAZE_RULE(new_local_repository).ATTRIBUTE(build_file_content) --> diff --git a/src/main/java/com/google/devtools/build/lib/rules/repository/NewRepositoryBuildFileHandler.java b/src/main/java/com/google/devtools/build/lib/rules/repository/NewRepositoryBuildFileHandler.java index 9518248772..456d80842f 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/repository/NewRepositoryBuildFileHandler.java +++ b/src/main/java/com/google/devtools/build/lib/rules/repository/NewRepositoryBuildFileHandler.java @@ -14,12 +14,16 @@ package com.google.devtools.build.lib.rules.repository; +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.packages.AggregatingAttributeMapper; import com.google.devtools.build.lib.packages.Rule; import com.google.devtools.build.lib.rules.repository.RepositoryFunction.RepositoryFunctionException; import com.google.devtools.build.lib.skyframe.FileSymlinkException; import com.google.devtools.build.lib.skyframe.FileValue; import com.google.devtools.build.lib.skyframe.InconsistentFilesystemException; +import com.google.devtools.build.lib.skyframe.PackageLookupValue; import com.google.devtools.build.lib.syntax.EvalException; import com.google.devtools.build.lib.syntax.Type; import com.google.devtools.build.lib.vfs.Path; @@ -113,22 +117,53 @@ public class NewRepositoryBuildFileHandler { private FileValue getBuildFileValue(Rule rule, Environment env) throws RepositoryFunctionException { AggregatingAttributeMapper mapper = AggregatingAttributeMapper.of(rule); - PathFragment buildFile = new PathFragment(mapper.get("build_file", Type.STRING)); - Path buildFileTarget = workspacePath.getRelative(buildFile); - if (!buildFileTarget.exists()) { - throw new RepositoryFunctionException( - new EvalException(rule.getLocation(), - String.format("In %s the 'build_file' attribute does not specify an existing file " - + "(%s does not exist)", rule, buildFileTarget)), - Transience.PERSISTENT); - } - + String buildFileAttribute = mapper.get("build_file", Type.STRING); RootedPath rootedBuild; - if (buildFile.isAbsolute()) { - rootedBuild = RootedPath.toRootedPath( - buildFileTarget.getParentDirectory(), new PathFragment(buildFileTarget.getBaseName())); + + if (LabelValidator.isAbsolute(buildFileAttribute)) { + try { + // Parse a label + Label label = Label.parseAbsolute(buildFileAttribute); + SkyKey pkgSkyKey = PackageLookupValue.key(label.getPackageIdentifier()); + PackageLookupValue pkgLookupValue = (PackageLookupValue) env.getValue(pkgSkyKey); + if (pkgLookupValue == null) { + return null; + } + if (!pkgLookupValue.packageExists()) { + throw new RepositoryFunctionException( + new EvalException(rule.getLocation(), + "Unable to load package for " + buildFileAttribute + ": not found."), + Transience.PERSISTENT); + } + + // And now for the file + Path packageRoot = pkgLookupValue.getRoot(); + rootedBuild = RootedPath.toRootedPath(packageRoot, label.toPathFragment()); + } catch (LabelSyntaxException ex) { + throw new RepositoryFunctionException( + new EvalException(rule.getLocation(), + String.format("In %s the 'build_file' attribute does not specify a valid label: %s", + rule, ex.getMessage())), + Transience.PERSISTENT); + } } else { - rootedBuild = RootedPath.toRootedPath(workspacePath, buildFile); + // TODO(dmarting): deprecate using a path for the build_file attribute. + PathFragment buildFile = new PathFragment(buildFileAttribute); + Path buildFileTarget = workspacePath.getRelative(buildFile); + if (!buildFileTarget.exists()) { + throw new RepositoryFunctionException( + new EvalException(rule.getLocation(), + String.format("In %s the 'build_file' attribute does not specify an existing file " + + "(%s does not exist)", rule, buildFileTarget)), + Transience.PERSISTENT); + } + + if (buildFile.isAbsolute()) { + rootedBuild = RootedPath.toRootedPath( + buildFileTarget.getParentDirectory(), new PathFragment(buildFileTarget.getBaseName())); + } else { + rootedBuild = RootedPath.toRootedPath(workspacePath, buildFile); + } } SkyKey buildFileKey = FileValue.key(rootedBuild); FileValue buildFileValue; @@ -146,7 +181,7 @@ public class NewRepositoryBuildFileHandler { } } catch (IOException | FileSymlinkException | InconsistentFilesystemException e) { throw new RepositoryFunctionException( - new IOException("Cannot lookup " + buildFile + ": " + e.getMessage()), + new IOException("Cannot lookup " + buildFileAttribute + ": " + e.getMessage()), Transience.TRANSIENT); } |