diff options
Diffstat (limited to 'src/main/java/com')
5 files changed, 76 insertions, 22 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/buildtool/BuildRequestOptions.java b/src/main/java/com/google/devtools/build/lib/buildtool/BuildRequestOptions.java index f5701cb5d0..858930ae20 100644 --- a/src/main/java/com/google/devtools/build/lib/buildtool/BuildRequestOptions.java +++ b/src/main/java/com/google/devtools/build/lib/buildtool/BuildRequestOptions.java @@ -367,6 +367,21 @@ public class BuildRequestOptions extends OptionsBase { } @Option( + name = "print_workspace_in_output_paths_if_needed", + defaultValue = "false", + documentationCategory = OptionDocumentationCategory.UNDOCUMENTED, + effectTags = {OptionEffectTag.TERMINAL_OUTPUT}, + help = + "If enabled, when the current working directory is deeper than the workspace (for example, " + + "when running from <workspace>/foo instead of <workspace>), printed output paths " + + "include the absolute path to the workspace (for example, " + + "<workspace>/<symlink_prefix>-bin/foo/binary instead of " + + "<symlink_prefix>-bin/foo/binary)." + ) + public boolean printWorkspaceInOutputPathsIfNeeded; + + + @Option( name = "use_action_cache", defaultValue = "true", documentationCategory = OptionDocumentationCategory.UNDOCUMENTED, diff --git a/src/main/java/com/google/devtools/build/lib/buildtool/BuildResultPrinter.java b/src/main/java/com/google/devtools/build/lib/buildtool/BuildResultPrinter.java index 005b1858a3..133588792e 100644 --- a/src/main/java/com/google/devtools/build/lib/buildtool/BuildResultPrinter.java +++ b/src/main/java/com/google/devtools/build/lib/buildtool/BuildResultPrinter.java @@ -123,6 +123,9 @@ class BuildResultPrinter { temp.getPath(), env.getWorkspaceName(), env.getWorkspace(), + request.getBuildOptions().printWorkspaceInOutputPathsIfNeeded + ? env.getWorkingDirectory() + : env.getWorkspace(), request.getBuildOptions().getSymlinkPrefix(productName), productName)); } @@ -181,9 +184,16 @@ class BuildResultPrinter { private String formatArtifactForShowResults(Artifact artifact, BuildRequest request) { String productName = env.getRuntime().getProductName(); - return " " + OutputDirectoryLinksUtils.getPrettyPath(artifact.getPath(), - env.getWorkspaceName(), env.getWorkspace(), - request.getBuildOptions().getSymlinkPrefix(productName), productName); + return " " + + OutputDirectoryLinksUtils.getPrettyPath( + artifact.getPath(), + env.getWorkspaceName(), + env.getWorkspace(), + request.getBuildOptions().printWorkspaceInOutputPathsIfNeeded + ? env.getWorkingDirectory() + : env.getWorkspace(), + request.getBuildOptions().getSymlinkPrefix(productName), + productName); } /** diff --git a/src/main/java/com/google/devtools/build/lib/buildtool/OutputDirectoryLinksUtils.java b/src/main/java/com/google/devtools/build/lib/buildtool/OutputDirectoryLinksUtils.java index 2cfd532b8a..7917087735 100644 --- a/src/main/java/com/google/devtools/build/lib/buildtool/OutputDirectoryLinksUtils.java +++ b/src/main/java/com/google/devtools/build/lib/buildtool/OutputDirectoryLinksUtils.java @@ -150,34 +150,44 @@ public class OutputDirectoryLinksUtils { /** * Returns a convenient path to the specified file, relativizing it and using output-dir symlinks - * if possible. Otherwise, return a path relative to the workspace directory if possible. + * if possible. Otherwise, return a path relative to the workspace directory if possible. * Otherwise, return the absolute path. * * <p>This method must be called after the symlinks are created at the end of a build. If called * before, the pretty path may be incorrect if the symlinks end up pointing somewhere new. */ - public static PathFragment getPrettyPath(Path file, String workspaceName, - Path workspaceDirectory, String symlinkPrefix, String productName) { + public static PathFragment getPrettyPath( + Path file, + String workspaceName, + Path workspaceDirectory, + Path workingDirectory, + String symlinkPrefix, + String productName) { if (NO_CREATE_SYMLINKS_PREFIX.equals(symlinkPrefix)) { return file.asFragment(); } for (String link : LINKS) { - PathFragment result = relativize(file, workspaceDirectory, symlinkPrefix + link); + PathFragment result = + relativize(file, workspaceDirectory, workingDirectory, symlinkPrefix + link); if (result != null) { return result; } } - PathFragment result = relativize(file, workspaceDirectory, - execRootSymlink(symlinkPrefix, workspaceName)); + PathFragment result = + relativize( + file, + workspaceDirectory, + workingDirectory, + execRootSymlink(symlinkPrefix, workspaceName)); if (result != null) { return result; } ImmutableList<String> outputSymlinkNames = getOutputSymlinkNames(productName, symlinkPrefix); checkArgument(!outputSymlinkNames.isEmpty()); - result = relativize(file, workspaceDirectory, outputSymlinkNames.get(0)); + result = relativize(file, workspaceDirectory, workingDirectory, outputSymlinkNames.get(0)); if (result != null) { return result; } @@ -187,14 +197,19 @@ public class OutputDirectoryLinksUtils { // Helper to getPrettyPath. Returns file, relativized w.r.t. the referent of // "linkname", or null if it was a not a child. - private static PathFragment relativize(Path file, Path workspaceDirectory, String linkname) { + private static PathFragment relativize( + Path file, Path workspaceDirectory, Path workingDirectory, String linkname) { PathFragment link = PathFragment.create(linkname); try { Path dir = workspaceDirectory.getRelative(link); PathFragment levelOneLinkTarget = dir.readSymbolicLink(); if (levelOneLinkTarget.isAbsolute() && file.startsWith(dir = file.getRelative(levelOneLinkTarget))) { - return link.getRelative(file.relativeTo(dir)); + PathFragment outputLink = + workingDirectory.equals(workspaceDirectory) + ? link + : workspaceDirectory.getRelative(link).asFragment(); + return outputLink.getRelative(file.relativeTo(dir)); } } catch (IOException e) { /* ignore */ diff --git a/src/main/java/com/google/devtools/build/lib/runtime/CommandEnvironment.java b/src/main/java/com/google/devtools/build/lib/runtime/CommandEnvironment.java index 32d31a2979..3870931203 100644 --- a/src/main/java/com/google/devtools/build/lib/runtime/CommandEnvironment.java +++ b/src/main/java/com/google/devtools/build/lib/runtime/CommandEnvironment.java @@ -14,6 +14,7 @@ package com.google.devtools.build.lib.runtime; +import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Preconditions; import com.google.common.eventbus.EventBus; import com.google.devtools.build.lib.actions.PackageRootResolver; @@ -146,7 +147,7 @@ public final class CommandEnvironment { // TODO(ulfjack): We don't call beforeCommand() in tests, but rely on workingDirectory being set // in setupPackageCache(). This leads to NPE if we don't set it here. - this.workingDirectory = directories.getWorkspace(); + this.setWorkingDirectory(directories.getWorkspace()); this.workspaceName = null; workspace.getSkyframeExecutor().setEventBus(eventBus); @@ -554,8 +555,16 @@ public final class CommandEnvironment { return commandStartTime; } - void setWorkingDirectory(Path workingDirectory) { + @VisibleForTesting + public void setWorkingDirectoryForTesting(Path workingDirectory) { + setWorkingDirectory(workingDirectory); + } + + private void setWorkingDirectory(Path workingDirectory) { this.workingDirectory = workingDirectory; + if (getWorkspace() != null) { + this.relativeWorkingDirectory = workingDirectory.relativeTo(getWorkspace()); + } } /** @@ -608,8 +617,7 @@ public final class CommandEnvironment { workspace = FileSystemUtils.getWorkingDirectory(getRuntime().getFileSystem()); workingDirectory = workspace; } - this.relativeWorkingDirectory = workingDirectory.relativeTo(workspace); - this.workingDirectory = workingDirectory; + this.setWorkingDirectory(workingDirectory); // Fail fast in the case where a Blaze command forgets to install the package path correctly. skyframeExecutor.setActive(false); diff --git a/src/main/java/com/google/devtools/build/lib/runtime/commands/RunCommand.java b/src/main/java/com/google/devtools/build/lib/runtime/commands/RunCommand.java index 25fd5f2432..7acf1c7304 100644 --- a/src/main/java/com/google/devtools/build/lib/runtime/commands/RunCommand.java +++ b/src/main/java/com/google/devtools/build/lib/runtime/commands/RunCommand.java @@ -186,13 +186,19 @@ public class RunCommand implements BlazeCommand { String productName = env.getRuntime().getProductName(); Artifact executable = targetToRun.getProvider(FilesToRunProvider.class).getExecutable(); + BuildRequestOptions requestOptions = env.getOptions().getOptions(BuildRequestOptions.class); + PathFragment executablePath = executable.getPath().asFragment(); - PathFragment prettyExecutablePath = OutputDirectoryLinksUtils.getPrettyPath( - executable.getPath(), - env.getWorkspaceName(), - env.getWorkspace(), - env.getOptions().getOptions(BuildRequestOptions.class).getSymlinkPrefix(productName), - productName); + PathFragment prettyExecutablePath = + OutputDirectoryLinksUtils.getPrettyPath( + executable.getPath(), + env.getWorkspaceName(), + env.getWorkspace(), + requestOptions.printWorkspaceInOutputPathsIfNeeded + ? env.getWorkingDirectory() + : env.getWorkspace(), + requestOptions.getSymlinkPrefix(productName), + productName); RunUnder runUnder = env.getOptions().getOptions(BuildConfiguration.Options.class).runUnder; // Insert the command prefix specified by the "--run_under=<command-prefix>" option |