use of com.google.devtools.build.lib.vfs.Path in project bazel by bazelbuild.
the class QueryCommand method exec.
/**
* Exit codes:
* 0 on successful evaluation.
* 1 if query evaluation did not complete.
* 2 if query parsing failed.
* 3 if errors were reported but evaluation produced a partial result
* (only when --keep_going is in effect.)
*/
@Override
public ExitCode exec(CommandEnvironment env, OptionsProvider options) {
BlazeRuntime runtime = env.getRuntime();
QueryOptions queryOptions = options.getOptions(QueryOptions.class);
try {
env.setupPackageCache(options, runtime.getDefaultsPackageContent());
} catch (InterruptedException e) {
env.getReporter().handle(Event.error("query interrupted"));
return ExitCode.INTERRUPTED;
} catch (AbruptExitException e) {
env.getReporter().handle(Event.error(null, "Unknown error: " + e.getMessage()));
return e.getExitCode();
}
String query;
if (!options.getResidue().isEmpty()) {
if (!queryOptions.queryFile.isEmpty()) {
env.getReporter().handle(Event.error("Command-line query and --query_file cannot both be specified"));
return ExitCode.COMMAND_LINE_ERROR;
}
query = Joiner.on(' ').join(options.getResidue());
} else if (!queryOptions.queryFile.isEmpty()) {
// Works for absolute or relative query file.
Path residuePath = env.getWorkingDirectory().getRelative(queryOptions.queryFile);
try {
query = new String(FileSystemUtils.readContent(residuePath), StandardCharsets.UTF_8);
} catch (IOException e) {
env.getReporter().handle(Event.error("I/O error reading from " + residuePath.getPathString()));
return ExitCode.COMMAND_LINE_ERROR;
}
} else {
env.getReporter().handle(Event.error(String.format("missing query expression. Type '%s help query' for syntax and help", runtime.getProductName())));
return ExitCode.COMMAND_LINE_ERROR;
}
Iterable<OutputFormatter> formatters = runtime.getQueryOutputFormatters();
OutputFormatter formatter = OutputFormatter.getFormatter(formatters, queryOptions.outputFormat);
if (formatter == null) {
env.getReporter().handle(Event.error(String.format("Invalid output format '%s'. Valid values are: %s", queryOptions.outputFormat, OutputFormatter.formatterNames(formatters))));
return ExitCode.COMMAND_LINE_ERROR;
}
Set<Setting> settings = queryOptions.toSettings();
boolean streamResults = QueryOutputUtils.shouldStreamResults(queryOptions, formatter);
QueryEvalResult result;
AbstractBlazeQueryEnvironment<Target> queryEnv = newQueryEnvironment(env, queryOptions.keepGoing, !streamResults, queryOptions.universeScope, queryOptions.loadingPhaseThreads, settings);
// 1. Parse and transform query:
QueryExpression expr;
try {
expr = QueryExpression.parse(query, queryEnv);
} catch (QueryException e) {
env.getReporter().handle(Event.error(null, "Error while parsing '" + query + "': " + e.getMessage()));
return ExitCode.COMMAND_LINE_ERROR;
}
expr = queryEnv.transformParsedQuery(expr);
OutputStream out = env.getReporter().getOutErr().getOutputStream();
ThreadSafeOutputFormatterCallback<Target> callback;
if (streamResults) {
disableAnsiCharactersFiltering(env);
// 2. Evaluate expression:
StreamedFormatter streamedFormatter = ((StreamedFormatter) formatter);
streamedFormatter.setOptions(queryOptions, queryOptions.aspectDeps.createResolver(env.getPackageManager(), env.getReporter()));
callback = streamedFormatter.createStreamCallback(out, queryOptions, queryEnv);
} else {
callback = QueryUtil.newOrderedAggregateAllOutputFormatterCallback();
}
boolean catastrophe = true;
try {
result = queryEnv.evaluateQuery(expr, callback);
catastrophe = false;
} catch (QueryException e) {
catastrophe = false;
// Keep consistent with reportBuildFileError()
env.getReporter().handle(Event.error(e.getMessage() == null ? e.toString() : e.getMessage()));
return ExitCode.ANALYSIS_FAILURE;
} catch (InterruptedException e) {
catastrophe = false;
IOException ioException = callback.getIoException();
if (ioException == null || ioException instanceof ClosedByInterruptException) {
env.getReporter().handle(Event.error("query interrupted"));
return ExitCode.INTERRUPTED;
} else {
env.getReporter().handle(Event.error("I/O error: " + e.getMessage()));
return ExitCode.LOCAL_ENVIRONMENTAL_ERROR;
}
} catch (IOException e) {
catastrophe = false;
env.getReporter().handle(Event.error("I/O error: " + e.getMessage()));
return ExitCode.LOCAL_ENVIRONMENTAL_ERROR;
} finally {
if (!catastrophe) {
try {
out.flush();
} catch (IOException e) {
env.getReporter().handle(Event.error("Failed to flush query results: " + e.getMessage()));
return ExitCode.LOCAL_ENVIRONMENTAL_ERROR;
}
}
}
env.getEventBus().post(new NoBuildEvent());
if (!streamResults) {
disableAnsiCharactersFiltering(env);
// 3. Output results:
try {
Set<Target> targets = ((AggregateAllOutputFormatterCallback<Target>) callback).getResult();
QueryOutputUtils.output(queryOptions, result, targets, formatter, env.getReporter().getOutErr().getOutputStream(), queryOptions.aspectDeps.createResolver(env.getPackageManager(), env.getReporter()));
} catch (ClosedByInterruptException | InterruptedException e) {
env.getReporter().handle(Event.error("query interrupted"));
return ExitCode.INTERRUPTED;
} catch (IOException e) {
env.getReporter().handle(Event.error("I/O error: " + e.getMessage()));
return ExitCode.LOCAL_ENVIRONMENTAL_ERROR;
} finally {
try {
out.flush();
} catch (IOException e) {
env.getReporter().handle(Event.error("Failed to flush query results: " + e.getMessage()));
return ExitCode.LOCAL_ENVIRONMENTAL_ERROR;
}
}
}
if (result.isEmpty()) {
env.getReporter().handle(Event.info("Empty results"));
}
return result.getSuccess() ? ExitCode.SUCCESS : ExitCode.PARTIAL_ANALYSIS_FAILURE;
}
use of com.google.devtools.build.lib.vfs.Path in project bazel by bazelbuild.
the class RunCommand method exec.
@Override
public ExitCode exec(CommandEnvironment env, OptionsProvider options) {
RunOptions runOptions = options.getOptions(RunOptions.class);
// This list should look like: ["//executable:target", "arg1", "arg2"]
List<String> targetAndArgs = options.getResidue();
// The user must at the least specify an executable target.
if (targetAndArgs.isEmpty()) {
env.getReporter().handle(Event.error("Must specify a target to run"));
return ExitCode.COMMAND_LINE_ERROR;
}
String targetString = targetAndArgs.get(0);
List<String> runTargetArgs = targetAndArgs.subList(1, targetAndArgs.size());
RunUnder runUnder = options.getOptions(BuildConfiguration.Options.class).runUnder;
OutErr outErr = env.getReporter().getOutErr();
List<String> targets = (runUnder != null) && (runUnder.getLabel() != null) ? ImmutableList.of(targetString, runUnder.getLabel().toString()) : ImmutableList.of(targetString);
BuildRequest request = BuildRequest.create(this.getClass().getAnnotation(Command.class).name(), options, env.getRuntime().getStartupOptionsProvider(), targets, outErr, env.getCommandId(), env.getCommandStartTime());
currentRunUnder = runUnder;
BuildResult result;
try {
result = processRequest(env, request);
} finally {
currentRunUnder = null;
}
if (!result.getSuccess()) {
env.getReporter().handle(Event.error("Build failed. Not running target"));
return result.getExitCondition();
}
// Make sure that we have exactly 1 built target (excluding --run_under),
// and that it is executable.
// These checks should only fail if keepGoing is true, because we already did
// validation before the build began. See {@link #validateTargets()}.
Collection<ConfiguredTarget> targetsBuilt = result.getSuccessfulTargets();
ConfiguredTarget targetToRun = null;
ConfiguredTarget runUnderTarget = null;
if (targetsBuilt != null) {
int maxTargets = runUnder != null && runUnder.getLabel() != null ? 2 : 1;
if (targetsBuilt.size() > maxTargets) {
env.getReporter().handle(Event.error(SINGLE_TARGET_MESSAGE));
return ExitCode.COMMAND_LINE_ERROR;
}
for (ConfiguredTarget target : targetsBuilt) {
ExitCode targetValidation = fullyValidateTarget(env, target);
if (!targetValidation.equals(ExitCode.SUCCESS)) {
return targetValidation;
}
if (runUnder != null && target.getLabel().equals(runUnder.getLabel())) {
if (runUnderTarget != null) {
env.getReporter().handle(Event.error(null, "Can't identify the run_under target from multiple options?"));
return ExitCode.COMMAND_LINE_ERROR;
}
runUnderTarget = target;
} else if (targetToRun == null) {
targetToRun = target;
} else {
env.getReporter().handle(Event.error(SINGLE_TARGET_MESSAGE));
return ExitCode.COMMAND_LINE_ERROR;
}
}
}
// Handle target & run_under referring to the same target.
if ((targetToRun == null) && (runUnderTarget != null)) {
targetToRun = runUnderTarget;
}
if (targetToRun == null) {
env.getReporter().handle(Event.error(NO_TARGET_MESSAGE));
return ExitCode.COMMAND_LINE_ERROR;
}
Path executablePath = Preconditions.checkNotNull(targetToRun.getProvider(FilesToRunProvider.class).getExecutable().getPath());
BuildConfiguration configuration = targetToRun.getConfiguration();
if (configuration == null) {
// The target may be an input file, which doesn't have a configuration. In that case, we
// choose any target configuration.
configuration = result.getBuildConfigurationCollection().getTargetConfigurations().get(0);
}
Path workingDir;
try {
workingDir = ensureRunfilesBuilt(env, targetToRun);
} catch (CommandException e) {
env.getReporter().handle(Event.error("Error creating runfiles: " + e.getMessage()));
return ExitCode.LOCAL_ENVIRONMENTAL_ERROR;
}
List<String> args = runTargetArgs;
FilesToRunProvider provider = targetToRun.getProvider(FilesToRunProvider.class);
RunfilesSupport runfilesSupport = provider == null ? null : provider.getRunfilesSupport();
if (runfilesSupport != null && runfilesSupport.getArgs() != null) {
List<String> targetArgs = runfilesSupport.getArgs();
if (!targetArgs.isEmpty()) {
args = Lists.newArrayListWithCapacity(targetArgs.size() + runTargetArgs.size());
args.addAll(targetArgs);
args.addAll(runTargetArgs);
}
}
String productName = env.getRuntime().getProductName();
//
// We now have a unique executable ready to be run.
//
// We build up two different versions of the command to run: one with an absolute path, which
// we'll actually run, and a prettier one with the long absolute path to the executable
// replaced with a shorter relative path that uses the symlinks in the workspace.
PathFragment prettyExecutablePath = OutputDirectoryLinksUtils.getPrettyPath(executablePath, env.getWorkspaceName(), env.getWorkspace(), options.getOptions(BuildRequestOptions.class).getSymlinkPrefix(productName), productName);
List<String> cmdLine = new ArrayList<>();
if (runOptions.scriptPath == null) {
PathFragment processWrapperPath = env.getBlazeWorkspace().getBinTools().getExecPath(PROCESS_WRAPPER);
Preconditions.checkNotNull(processWrapperPath, PROCESS_WRAPPER + " not found in embedded tools");
cmdLine.add(env.getExecRoot().getRelative(processWrapperPath).getPathString());
cmdLine.add("-1");
cmdLine.add("15");
cmdLine.add("-");
cmdLine.add("-");
}
List<String> prettyCmdLine = new ArrayList<>();
// at the start of the command line.
if (runUnder != null) {
String runUnderValue = runUnder.getValue();
if (runUnderTarget != null) {
// --run_under specifies a target. Get the corresponding executable.
// This must be an absolute path, because the run_under target is only
// in the runfiles of test targets.
runUnderValue = runUnderTarget.getProvider(FilesToRunProvider.class).getExecutable().getPath().getPathString();
// If the run_under command contains any options, make sure to add them
// to the command line as well.
List<String> opts = runUnder.getOptions();
if (!opts.isEmpty()) {
runUnderValue += " " + ShellEscaper.escapeJoinAll(opts);
}
}
cmdLine.add(configuration.getShellExecutable().getPathString());
cmdLine.add("-c");
cmdLine.add(runUnderValue + " " + executablePath.getPathString() + " " + ShellEscaper.escapeJoinAll(args));
prettyCmdLine.add(configuration.getShellExecutable().getPathString());
prettyCmdLine.add("-c");
prettyCmdLine.add(runUnderValue + " " + prettyExecutablePath.getPathString() + " " + ShellEscaper.escapeJoinAll(args));
} else {
cmdLine.add(executablePath.getPathString());
cmdLine.addAll(args);
prettyCmdLine.add(prettyExecutablePath.getPathString());
prettyCmdLine.addAll(args);
}
// Add a newline between the blaze output and the binary's output.
outErr.printErrLn("");
if (runOptions.scriptPath != null) {
String unisolatedCommand = CommandFailureUtils.describeCommand(CommandDescriptionForm.COMPLETE_UNISOLATED, cmdLine, null, workingDir.getPathString());
if (writeScript(env, runOptions.scriptPath, unisolatedCommand)) {
return ExitCode.SUCCESS;
} else {
return ExitCode.RUN_FAILURE;
}
}
env.getReporter().handle(Event.info(null, "Running command line: " + ShellEscaper.escapeJoinAll(prettyCmdLine)));
com.google.devtools.build.lib.shell.Command command = new CommandBuilder().addArgs(cmdLine).setEnv(env.getClientEnv()).setWorkingDir(workingDir).build();
try {
// Restore a raw EventHandler if it is registered. This allows for blaze run to produce the
// actual output of the command being run even if --color=no is specified.
env.getReporter().switchToAnsiAllowingHandler();
// The command API is a little strange in that the following statement
// will return normally only if the program exits with exit code 0.
// If it ends with any other code, we have to catch BadExitStatusException.
command.execute(com.google.devtools.build.lib.shell.Command.NO_INPUT, com.google.devtools.build.lib.shell.Command.NO_OBSERVER, outErr.getOutputStream(), outErr.getErrorStream(), true).getTerminationStatus().getExitCode();
return ExitCode.SUCCESS;
} catch (BadExitStatusException e) {
String message = "Non-zero return code '" + e.getResult().getTerminationStatus().getExitCode() + "' from command: " + e.getMessage();
env.getReporter().handle(Event.error(message));
return ExitCode.RUN_FAILURE;
} catch (AbnormalTerminationException e) {
// The process was likely terminated by a signal in this case.
return ExitCode.INTERRUPTED;
} catch (CommandException e) {
env.getReporter().handle(Event.error("Error running program: " + e.getMessage()));
return ExitCode.RUN_FAILURE;
}
}
use of com.google.devtools.build.lib.vfs.Path in project bazel by bazelbuild.
the class ASTFileLookupFunction method compute.
@Override
public SkyValue compute(SkyKey skyKey, Environment env) throws SkyFunctionException, InterruptedException {
Label fileLabel = (Label) skyKey.argument();
PathFragment filePathFragment = fileLabel.toPathFragment();
//
// Determine whether the package designated by fileLabel exists.
//
SkyKey pkgSkyKey = PackageLookupValue.key(fileLabel.getPackageIdentifier());
PackageLookupValue pkgLookupValue = null;
try {
pkgLookupValue = (PackageLookupValue) env.getValueOrThrow(pkgSkyKey, BuildFileNotFoundException.class, InconsistentFilesystemException.class);
} catch (BuildFileNotFoundException e) {
throw new ASTLookupFunctionException(new ErrorReadingSkylarkExtensionException(e), Transience.PERSISTENT);
} catch (InconsistentFilesystemException e) {
throw new ASTLookupFunctionException(e, Transience.PERSISTENT);
}
if (pkgLookupValue == null) {
return null;
}
if (!pkgLookupValue.packageExists()) {
return ASTFileLookupValue.forBadPackage(fileLabel, pkgLookupValue.getErrorMsg());
}
//
// Determine whether the file designated by fileLabel exists.
//
Path packageRoot = pkgLookupValue.getRoot();
RootedPath rootedPath = RootedPath.toRootedPath(packageRoot, filePathFragment);
SkyKey fileSkyKey = FileValue.key(rootedPath);
FileValue fileValue = null;
try {
fileValue = (FileValue) env.getValueOrThrow(fileSkyKey, IOException.class, FileSymlinkException.class, InconsistentFilesystemException.class);
} catch (IOException | FileSymlinkException e) {
throw new ASTLookupFunctionException(new ErrorReadingSkylarkExtensionException(e), Transience.PERSISTENT);
} catch (InconsistentFilesystemException e) {
throw new ASTLookupFunctionException(e, Transience.PERSISTENT);
}
if (fileValue == null) {
return null;
}
if (!fileValue.isFile()) {
return ASTFileLookupValue.forBadFile(fileLabel);
}
//
// Both the package and the file exist; load the file and parse it as an AST.
//
BuildFileAST ast = null;
Path path = rootedPath.asPath();
try {
long astFileSize = fileValue.getSize();
try (Mutability mutability = Mutability.create("validate")) {
ValidationEnvironment validationEnv = new ValidationEnvironment(ruleClassProvider.createSkylarkRuleClassEnvironment(fileLabel, mutability, env.getListener(), /*astFileContentHashCode=*/
null, /*importMap=*/
null).setupDynamic(Runtime.PKG_NAME, Runtime.NONE).setupDynamic(Runtime.REPOSITORY_NAME, Runtime.NONE));
ast = BuildFileAST.parseSkylarkFile(path, astFileSize, env.getListener());
ast = ast.validate(validationEnv, env.getListener());
}
} catch (IOException e) {
throw new ASTLookupFunctionException(new ErrorReadingSkylarkExtensionException(e), Transience.TRANSIENT);
}
return ASTFileLookupValue.withFile(ast);
}
use of com.google.devtools.build.lib.vfs.Path in project bazel by bazelbuild.
the class FileArtifactValue method create.
@VisibleForTesting
public static FileArtifactValue create(Artifact artifact) throws IOException {
Path path = artifact.getPath();
FileStatus stat = path.stat();
boolean isFile = stat.isFile();
return create(artifact, isFile, isFile ? stat.getSize() : 0, null);
}
use of com.google.devtools.build.lib.vfs.Path in project bazel by bazelbuild.
the class FileStateValue method create.
public static FileStateValue create(RootedPath rootedPath, @Nullable TimestampGranularityMonitor tsgm) throws InconsistentFilesystemException, IOException {
Path path = rootedPath.asPath();
// Stat, but don't throw an exception for the common case of a nonexistent file. This still
// throws an IOException in case any other IO error is encountered.
FileStatus stat = path.statIfFound(Symlinks.NOFOLLOW);
if (stat == null) {
return NONEXISTENT_FILE_STATE_NODE;
}
return createWithStatNoFollow(rootedPath, FileStatusWithDigestAdapter.adapt(stat), tsgm);
}
Aggregations