From de655af4a7f7a3e340365fbd9f48815ff388d70b Mon Sep 17 00:00:00 2001 From: Alex Humesky Date: Fri, 12 Feb 2016 00:23:16 +0000 Subject: Adds a build_file_content attribute to new_git_repository, new_http_archive, and new_local_repository which allows the build file to be specified by a string directly in the rule rather than using a separate file. build_file and build_file_content are both optional, but one or the other must be specified. RELNOTES: build_file_content attribute added to new_git_repository, new_http_archive, and new_local_repository. -- MOS_MIGRATED_REVID=114490435 --- .../bazel/repository/NewGitRepositoryFunction.java | 15 +- .../bazel/repository/NewHttpArchiveFunction.java | 16 +- .../android/AndroidNdkRepositoryFunction.java | 4 +- .../android/AndroidSdkRepositoryFunction.java | 4 +- .../rules/workspace/NewGitRepositoryRule.java | 10 +- .../bazel/rules/workspace/NewHttpArchiveRule.java | 10 +- .../repository/NewLocalRepositoryFunction.java | 16 +- .../rules/repository/NewLocalRepositoryRule.java | 10 +- .../repository/NewRepositoryBuildFileHandler.java | 168 +++++++++++++++++++++ .../lib/rules/repository/RepositoryFunction.java | 65 +------- 10 files changed, 235 insertions(+), 83 deletions(-) create mode 100644 src/main/java/com/google/devtools/build/lib/rules/repository/NewRepositoryBuildFileHandler.java (limited to 'src/main/java/com/google/devtools/build') diff --git a/src/main/java/com/google/devtools/build/lib/bazel/repository/NewGitRepositoryFunction.java b/src/main/java/com/google/devtools/build/lib/bazel/repository/NewGitRepositoryFunction.java index b10ed9448a..2b89ce3a5d 100644 --- a/src/main/java/com/google/devtools/build/lib/bazel/repository/NewGitRepositoryFunction.java +++ b/src/main/java/com/google/devtools/build/lib/bazel/repository/NewGitRepositoryFunction.java @@ -15,7 +15,8 @@ package com.google.devtools.build.lib.bazel.repository; import com.google.devtools.build.lib.packages.Rule; -import com.google.devtools.build.lib.skyframe.FileValue; +import com.google.devtools.build.lib.rules.repository.NewRepositoryBuildFileHandler; +import com.google.devtools.build.lib.rules.repository.RepositoryDirectoryValue; import com.google.devtools.build.lib.vfs.Path; import com.google.devtools.build.skyframe.SkyFunction.Environment; import com.google.devtools.build.skyframe.SkyFunctionException; @@ -27,15 +28,19 @@ import com.google.devtools.build.skyframe.SkyValue; public class NewGitRepositoryFunction extends GitRepositoryFunction { @Override public SkyValue fetch(Rule rule, Path outputDirectory, Environment env) - throws SkyFunctionException { - FileValue buildFileValue = getBuildFileValue(rule, env); - if (env.valuesMissing()) { + throws SkyFunctionException { + + NewRepositoryBuildFileHandler buildFileHandler = + new NewRepositoryBuildFileHandler(getWorkspace()); + if (!buildFileHandler.prepareBuildFile(rule, env)) { return null; } createDirectory(outputDirectory, rule); GitCloner.clone(rule, outputDirectory, env.getListener()); createWorkspaceFile(outputDirectory, rule); - return symlinkBuildFile(buildFileValue, outputDirectory); + buildFileHandler.finishBuildFile(outputDirectory); + + return RepositoryDirectoryValue.create(outputDirectory); } } diff --git a/src/main/java/com/google/devtools/build/lib/bazel/repository/NewHttpArchiveFunction.java b/src/main/java/com/google/devtools/build/lib/bazel/repository/NewHttpArchiveFunction.java index 8321457ded..9d7af3ebcd 100644 --- a/src/main/java/com/google/devtools/build/lib/bazel/repository/NewHttpArchiveFunction.java +++ b/src/main/java/com/google/devtools/build/lib/bazel/repository/NewHttpArchiveFunction.java @@ -16,7 +16,8 @@ package com.google.devtools.build.lib.bazel.repository; import com.google.devtools.build.lib.packages.AggregatingAttributeMapper; import com.google.devtools.build.lib.packages.Rule; -import com.google.devtools.build.lib.skyframe.FileValue; +import com.google.devtools.build.lib.rules.repository.NewRepositoryBuildFileHandler; +import com.google.devtools.build.lib.rules.repository.RepositoryDirectoryValue; import com.google.devtools.build.lib.syntax.Type; import com.google.devtools.build.lib.vfs.FileSystemUtils; import com.google.devtools.build.lib.vfs.Path; @@ -38,10 +39,13 @@ public class NewHttpArchiveFunction extends HttpArchiveFunction { @Override public SkyValue fetch(Rule rule, Path outputDirectory, Environment env) throws RepositoryFunctionException, InterruptedException { - FileValue buildFileValue = getBuildFileValue(rule, env); - if (env.valuesMissing()) { + + NewRepositoryBuildFileHandler buildFileHandler = + new NewRepositoryBuildFileHandler(getWorkspace()); + if (!buildFileHandler.prepareBuildFile(rule, env)) { return null; } + try { FileSystemUtils.createDirectoryAndParents(outputDirectory); } catch (IOException e) { @@ -68,8 +72,10 @@ public class NewHttpArchiveFunction extends HttpArchiveFunction { .setPrefix(prefix) .build()); - // Add WORKSPACE and BUILD files. + // Finally, write WORKSPACE and BUILD files. createWorkspaceFile(decompressed, rule); - return symlinkBuildFile(buildFileValue, outputDirectory); + buildFileHandler.finishBuildFile(outputDirectory); + + return RepositoryDirectoryValue.create(outputDirectory); } } diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/android/AndroidNdkRepositoryFunction.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/android/AndroidNdkRepositoryFunction.java index 5261bd7a79..04d9c5b8b8 100644 --- a/src/main/java/com/google/devtools/build/lib/bazel/rules/android/AndroidNdkRepositoryFunction.java +++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/android/AndroidNdkRepositoryFunction.java @@ -25,6 +25,7 @@ import com.google.devtools.build.lib.bazel.rules.android.ndkcrosstools.StlImpls; import com.google.devtools.build.lib.packages.AttributeMap; import com.google.devtools.build.lib.packages.NonconfigurableAttributeMapper; import com.google.devtools.build.lib.packages.Rule; +import com.google.devtools.build.lib.rules.repository.RepositoryDirectoryValue; import com.google.devtools.build.lib.rules.repository.RepositoryFunction; import com.google.devtools.build.lib.skyframe.FileSymlinkException; import com.google.devtools.build.lib.skyframe.FileValue; @@ -124,7 +125,8 @@ public class AndroidNdkRepositoryFunction extends RepositoryFunction { } String buildFile = createBuildFile(ruleName, crosstoolsAndStls.build()); - return writeBuildFile(outputDirectory, buildFile); + writeBuildFile(outputDirectory, buildFile); + return RepositoryDirectoryValue.create(outputDirectory); } @Override diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/android/AndroidSdkRepositoryFunction.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/android/AndroidSdkRepositoryFunction.java index 1e2a4dd360..3e4a767b1d 100644 --- a/src/main/java/com/google/devtools/build/lib/bazel/rules/android/AndroidSdkRepositoryFunction.java +++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/android/AndroidSdkRepositoryFunction.java @@ -17,6 +17,7 @@ import com.google.devtools.build.lib.analysis.RuleDefinition; import com.google.devtools.build.lib.packages.AttributeMap; import com.google.devtools.build.lib.packages.NonconfigurableAttributeMapper; import com.google.devtools.build.lib.packages.Rule; +import com.google.devtools.build.lib.rules.repository.RepositoryDirectoryValue; import com.google.devtools.build.lib.rules.repository.RepositoryFunction; import com.google.devtools.build.lib.syntax.Type; import com.google.devtools.build.lib.util.ResourceFileLoader; @@ -65,7 +66,8 @@ public class AndroidSdkRepositoryFunction extends RepositoryFunction { .replaceAll("%build_tools_version%", buildToolsVersion) .replaceAll("%api_level%", apiLevel.toString()); - return writeBuildFile(outputDirectory, buildFile); + writeBuildFile(outputDirectory, buildFile); + return RepositoryDirectoryValue.create(outputDirectory); } @Override 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 d75d533946..ae264bc248 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 @@ -54,11 +54,19 @@ public class NewGitRepositoryRule implements RuleDefinition { /* The file to use as the BUILD file for this repository. +

Either build_file or build_file_content must be specified.

+

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.

*/ - .add(attr("build_file", STRING).mandatory()) + .add(attr("build_file", STRING)) + /* + The content for the BUILD file for this repository. + +

Either build_file or build_file_content must be specified.

+ */ + .add(attr("build_file_content", STRING)) /* Whether to clone submodules in the repository. 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 ab6224eb05..459f80527e 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 @@ -51,11 +51,19 @@ public class NewHttpArchiveRule implements RuleDefinition { /* The file to use as the BUILD file for this repository. +

Either build_file or build_file_content must be specified.

+

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.

*/ - .add(attr("build_file", STRING).mandatory()) + .add(attr("build_file", STRING)) + /* + The content for the BUILD file for this repository. + +

Either build_file or build_file_content must be specified.

+ */ + .add(attr("build_file_content", STRING)) /* The archive type of the downloaded file. diff --git a/src/main/java/com/google/devtools/build/lib/rules/repository/NewLocalRepositoryFunction.java b/src/main/java/com/google/devtools/build/lib/rules/repository/NewLocalRepositoryFunction.java index 27bdc9a1c4..4fec7696ff 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/repository/NewLocalRepositoryFunction.java +++ b/src/main/java/com/google/devtools/build/lib/rules/repository/NewLocalRepositoryFunction.java @@ -16,7 +16,6 @@ package com.google.devtools.build.lib.rules.repository; import com.google.devtools.build.lib.analysis.RuleDefinition; import com.google.devtools.build.lib.packages.Rule; -import com.google.devtools.build.lib.skyframe.FileValue; import com.google.devtools.build.lib.vfs.Path; import com.google.devtools.build.lib.vfs.PathFragment; import com.google.devtools.build.skyframe.SkyFunction.Environment; @@ -27,6 +26,7 @@ import com.google.devtools.build.skyframe.SkyValue; * Create a repository from a directory on the local filesystem. */ public class NewLocalRepositoryFunction extends RepositoryFunction { + @Override public boolean isLocal() { return true; @@ -35,21 +35,25 @@ public class NewLocalRepositoryFunction extends RepositoryFunction { @Override public SkyValue fetch(Rule rule, Path outputDirectory, Environment env) throws SkyFunctionException { - FileValue buildFileValue = getBuildFileValue(rule, env); - if (env.valuesMissing()) { + + NewRepositoryBuildFileHandler buildFileHandler = + new NewRepositoryBuildFileHandler(getWorkspace()); + if (!buildFileHandler.prepareBuildFile(rule, env)) { return null; } + prepareLocalRepositorySymlinkTree(rule, outputDirectory); PathFragment pathFragment = getTargetPath(rule, getWorkspace()); - + // Link x/y/z to /some/path/to/y/z. if (!symlinkLocalRepositoryContents( outputDirectory, getOutputBase().getFileSystem().getPath(pathFragment))) { return null; } - // Link x/BUILD to /x.BUILD. - return symlinkBuildFile(buildFileValue, outputDirectory); + buildFileHandler.finishBuildFile(outputDirectory); + + return RepositoryDirectoryValue.create(outputDirectory); } @Override 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 f68b506ed9..baef7788e8 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 @@ -41,11 +41,19 @@ public class NewLocalRepositoryRule implements RuleDefinition { /* A file to use as a BUILD file for this directory. +

Either build_file or build_file_content must be specified.

+

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.

*/ - .add(attr("build_file", STRING).mandatory()) + .add(attr("build_file", STRING)) + /* + The content for the BUILD file for this repository. + +

Either build_file or build_file_content must be specified.

+ */ + .add(attr("build_file_content", STRING)) .setWorkspaceOnly() .build(); } 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 new file mode 100644 index 0000000000..9518248772 --- /dev/null +++ b/src/main/java/com/google/devtools/build/lib/rules/repository/NewRepositoryBuildFileHandler.java @@ -0,0 +1,168 @@ +// Copyright 2014 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 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.syntax.EvalException; +import com.google.devtools.build.lib.syntax.Type; +import com.google.devtools.build.lib.vfs.Path; +import com.google.devtools.build.lib.vfs.PathFragment; +import com.google.devtools.build.lib.vfs.RootedPath; +import com.google.devtools.build.skyframe.SkyFunction.Environment; +import com.google.devtools.build.skyframe.SkyFunctionException.Transience; +import com.google.devtools.build.skyframe.SkyKey; + +import java.io.IOException; + +/** + * Encapsulates the 2-step behavior of creating build files for the new_*_repository rules. + */ +public class NewRepositoryBuildFileHandler { + + private final Path workspacePath; + private FileValue buildFileValue; + private String buildFileContent; + + public NewRepositoryBuildFileHandler(Path workspacePath) { + this.workspacePath = workspacePath; + } + + /** + * Prepares for writing a build file by validating the build_file and build_file_content + * attributes of the rule. + * + * @return true if the build file was successfully created, false if the environment is missing + * values (the calling fetch() function should return null in this case). + * @throws RepositoryFunctionException if the rule does not define the build_file or + * build_file_content attributes, or if it defines both, or if the build file could not be + * retrieved, written, or symlinked. + */ + public boolean prepareBuildFile(Rule rule, Environment env) + throws RepositoryFunctionException { + + AggregatingAttributeMapper mapper = AggregatingAttributeMapper.of(rule); + boolean hasBuildFile = mapper.isAttributeValueExplicitlySpecified("build_file"); + boolean hasBuildFileContent = mapper.isAttributeValueExplicitlySpecified("build_file_content"); + + if (hasBuildFile && hasBuildFileContent) { + + String error = String.format( + "Rule %s cannot have both a 'build_file' and 'build_file_content' attribute", rule); + throw new RepositoryFunctionException( + new EvalException(rule.getLocation(), error), Transience.PERSISTENT); + + } else if (hasBuildFile) { + + buildFileValue = getBuildFileValue(rule, env); + if (env.valuesMissing()) { + return false; + } + + } else if (hasBuildFileContent) { + + buildFileContent = mapper.get("build_file_content", Type.STRING); + + } else { + + String error = String.format( + "Rule %s requires a 'build_file' or 'build_file_content' attribute", rule); + throw new RepositoryFunctionException( + new EvalException(rule.getLocation(), error), Transience.PERSISTENT); + } + + return true; + } + + /** + * Writes the build file, based on the state set by prepareBuildFile(). + * + * @param outputDirectory the directory to write the build file. + * @throws RepositoryFunctionException if the build file could not be written or symlinked + * @throws IllegalStateException if prepareBuildFile() was not called before this, or if + * prepareBuildFile() failed and this was called. + */ + public void finishBuildFile(Path outputDirectory) throws RepositoryFunctionException { + if (buildFileValue != null) { + // Link x/BUILD to /x.BUILD. + symlinkBuildFile(buildFileValue, outputDirectory); + } else if (buildFileContent != null) { + RepositoryFunction.writeBuildFile(outputDirectory, buildFileContent); + } else { + throw new IllegalStateException( + "prepareBuildFile() must be called before finishBuildFile()"); + } + } + + 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); + } + + RootedPath rootedBuild; + 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; + try { + // Note that this dependency is, strictly speaking, not necessary: the symlink could simply + // point to this FileValue and the symlink chasing could be done while loading the package + // but this results in a nicer error message and it's correct as long as RepositoryFunctions + // don't write to things in the file system this FileValue depends on. In theory, the latter + // is possible if the file referenced by build_file is a symlink to somewhere under the + // external/ directory, but if you do that, you are really asking for trouble. + buildFileValue = (FileValue) env.getValueOrThrow(buildFileKey, IOException.class, + FileSymlinkException.class, InconsistentFilesystemException.class); + if (buildFileValue == null) { + return null; + } + } catch (IOException | FileSymlinkException | InconsistentFilesystemException e) { + throw new RepositoryFunctionException( + new IOException("Cannot lookup " + buildFile + ": " + e.getMessage()), + Transience.TRANSIENT); + } + + return buildFileValue; + } + + /** + * Symlinks a BUILD file from the local filesystem into the external repository's root. + * @param buildFileValue {@link FileValue} representing the BUILD file to be linked in + * @param outputDirectory the directory of the remote repository + * @throws RepositoryFunctionException if the BUILD file specified does not exist or cannot be + * linked. + */ + private void symlinkBuildFile( + FileValue buildFileValue, Path outputDirectory) throws RepositoryFunctionException { + Path buildFilePath = outputDirectory.getRelative("BUILD"); + RepositoryFunction.createSymbolicLink(buildFilePath, buildFileValue.realRootedPath().asPath()); + } +} \ No newline at end of file diff --git a/src/main/java/com/google/devtools/build/lib/rules/repository/RepositoryFunction.java b/src/main/java/com/google/devtools/build/lib/rules/repository/RepositoryFunction.java index ee93a82227..c2f327d749 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/repository/RepositoryFunction.java +++ b/src/main/java/com/google/devtools/build/lib/rules/repository/RepositoryFunction.java @@ -216,7 +216,6 @@ public abstract class RepositoryFunction { } } - protected Path prepareLocalRepositorySymlinkTree(Rule rule, Path repositoryDirectory) throws RepositoryFunctionException { try { @@ -242,8 +241,8 @@ public abstract class RepositoryFunction { } } - protected RepositoryDirectoryValue writeBuildFile(Path repositoryDirectory, String contents) - throws RepositoryFunctionException { + protected static RepositoryDirectoryValue writeBuildFile( + Path repositoryDirectory, String contents) throws RepositoryFunctionException { Path buildFilePath = repositoryDirectory.getRelative("BUILD"); try { FileSystemUtils.writeContentAsLatin1(buildFilePath, contents); @@ -254,64 +253,6 @@ public abstract class RepositoryFunction { return RepositoryDirectoryValue.create(repositoryDirectory); } - protected 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 = directories.getWorkspace().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); - } - - RootedPath rootedBuild; - if (buildFile.isAbsolute()) { - rootedBuild = RootedPath.toRootedPath( - buildFileTarget.getParentDirectory(), new PathFragment(buildFileTarget.getBaseName())); - } else { - rootedBuild = RootedPath.toRootedPath(directories.getWorkspace(), buildFile); - } - SkyKey buildFileKey = FileValue.key(rootedBuild); - FileValue buildFileValue; - try { - // Note that this dependency is, strictly speaking, not necessary: the symlink could simply - // point to this FileValue and the symlink chasing could be done while loading the package - // but this results in a nicer error message and it's correct as long as RepositoryFunctions - // don't write to things in the file system this FileValue depends on. In theory, the latter - // is possible if the file referenced by build_file is a symlink to somewhere under the - // external/ directory, but if you do that, you are really asking for trouble. - buildFileValue = (FileValue) env.getValueOrThrow(buildFileKey, IOException.class, - FileSymlinkException.class, InconsistentFilesystemException.class); - if (buildFileValue == null) { - return null; - } - } catch (IOException | FileSymlinkException | InconsistentFilesystemException e) { - throw new RepositoryFunctionException( - new IOException("Cannot lookup " + buildFile + ": " + e.getMessage()), - Transience.TRANSIENT); - } - - return buildFileValue; - } - - /** - * Symlinks a BUILD file from the local filesystem into the external repository's root. - * @param buildFileValue {@link FileValue} representing the BUILD file to be linked in - * @param outputDirectory the directory of the remote repository - * @return the file value of the symlink created. - * @throws RepositoryFunctionException if the BUILD file specified does not exist or cannot be - * linked. - */ - protected RepositoryDirectoryValue symlinkBuildFile( - FileValue buildFileValue, Path outputDirectory) throws RepositoryFunctionException { - Path buildFilePath = outputDirectory.getRelative("BUILD"); - createSymbolicLink(buildFilePath, buildFileValue.realRootedPath().asPath()); - return RepositoryDirectoryValue.create(outputDirectory); - } - @VisibleForTesting protected static PathFragment getTargetPath(Rule rule, Path workspace) throws RepositoryFunctionException { @@ -350,7 +291,7 @@ public abstract class RepositoryFunction { return true; } - private static void createSymbolicLink(Path from, Path to) + static void createSymbolicLink(Path from, Path to) throws RepositoryFunctionException { try { // Remove not-symlinks that are already there. -- cgit v1.2.3