use of com.google.devtools.common.options.OptionsParsingException in project bazel by bazelbuild.
the class RunUnderConverter method convert.
@Override
public RunUnder convert(final String input) throws OptionsParsingException {
final List<String> runUnderList = new ArrayList<>();
try {
ShellUtils.tokenize(runUnderList, input);
} catch (TokenizationException e) {
throw new OptionsParsingException("Not a valid command prefix " + e.getMessage());
}
if (runUnderList.isEmpty()) {
throw new OptionsParsingException("Empty command");
}
final String runUnderCommand = runUnderList.get(0);
if (runUnderCommand.startsWith("//")) {
try {
final Label runUnderLabel = Label.parseAbsolute(runUnderCommand);
return new RunUnderLabel(input, runUnderLabel, runUnderList);
} catch (LabelSyntaxException e) {
throw new OptionsParsingException("Not a valid label " + e.getMessage());
}
} else {
return new RunUnderCommand(input, runUnderCommand, runUnderList);
}
}
use of com.google.devtools.common.options.OptionsParsingException in project bazel by bazelbuild.
the class OptionsUtils method asShellEscapedString.
/**
* Returns a string representation of the non-hidden specified options; option values are
* shell-escaped.
*/
public static String asShellEscapedString(Iterable<UnparsedOptionValueDescription> optionsList) {
StringBuilder result = new StringBuilder();
for (UnparsedOptionValueDescription option : optionsList) {
if (option.isHidden()) {
continue;
}
if (result.length() != 0) {
result.append(' ');
}
String value = option.getUnparsedValue();
if (option.isBooleanOption()) {
boolean isEnabled = false;
try {
isEnabled = new Converters.BooleanConverter().convert(value);
} catch (OptionsParsingException e) {
throw new RuntimeException("Unexpected parsing exception", e);
}
result.append(isEnabled ? "--" : "--no").append(option.getName());
} else {
result.append("--").append(option.getName());
if (value != null) {
// Can be null for Void options.
result.append("=").append(ShellEscaper.escapeString(value));
}
}
}
return result.toString();
}
use of com.google.devtools.common.options.OptionsParsingException in project bazel by bazelbuild.
the class InvocationPolicyEnforcer method enforce.
/**
* Applies this OptionsPolicyEnforcer's policy to the given OptionsParser.
*
* @param parser The OptionsParser to enforce policy on.
* @param command The current blaze command, for flag policies that apply to only specific
* commands. Such policies will be enforced only if they contain this command or a command
* they inherit from
* @throws OptionsParsingException if any flag policy is invalid.
*/
public void enforce(OptionsParser parser, @Nullable String command) throws OptionsParsingException {
if (invocationPolicy == null || invocationPolicy.getFlagPoliciesCount() == 0) {
return;
}
ImmutableSet<String> commandAndParentCommands = command == null ? ImmutableSet.<String>of() : CommandNameCache.CommandNameCacheInstance.INSTANCE.get(command);
for (FlagPolicy flagPolicy : invocationPolicy.getFlagPoliciesList()) {
String flagName = flagPolicy.getFlagName();
// then the policy applies to all commands.
if (!flagPolicy.getCommandsList().isEmpty() && !commandAndParentCommands.isEmpty()) {
boolean flagApplies = false;
for (String policyCommand : flagPolicy.getCommandsList()) {
if (commandAndParentCommands.contains(policyCommand)) {
flagApplies = true;
break;
}
}
if (!flagApplies) {
continue;
}
}
OptionValueDescription valueDescription;
try {
valueDescription = parser.getOptionValueDescription(flagName);
} catch (IllegalArgumentException e) {
// This flag doesn't exist. We are deliberately lenient if the flag policy has a flag
// we don't know about. This is for better future proofing so that as new flags are added,
// new policies can use the new flags without worrying about older versions of Bazel.
log.info(String.format("Flag '%s' specified by invocation policy does not exist", flagName));
continue;
}
OptionDescription optionDescription = parser.getOptionDescription(flagName);
// getOptionDescription() will return null if the option does not exist, however
// getOptionValueDescription() above would have thrown an IllegalArgumentException if that
// were the case.
Verify.verifyNotNull(optionDescription);
switch(flagPolicy.getOperationCase()) {
case SET_VALUE:
applySetValueOperation(parser, flagPolicy, flagName, valueDescription, optionDescription);
break;
case USE_DEFAULT:
applyUseDefaultOperation(parser, "UseDefault", flagName);
break;
case ALLOW_VALUES:
AllowValues allowValues = flagPolicy.getAllowValues();
FilterValueOperation.ALLOW_VALUE_OPERATION.apply(parser, allowValues.getAllowedValuesList(), allowValues.hasNewValue() ? allowValues.getNewValue() : null, allowValues.hasUseDefault(), flagName, valueDescription, optionDescription);
break;
case DISALLOW_VALUES:
DisallowValues disallowValues = flagPolicy.getDisallowValues();
FilterValueOperation.DISALLOW_VALUE_OPERATION.apply(parser, disallowValues.getDisallowedValuesList(), disallowValues.hasNewValue() ? disallowValues.getNewValue() : null, disallowValues.hasUseDefault(), flagName, valueDescription, optionDescription);
break;
case OPERATION_NOT_SET:
throw new OptionsParsingException(String.format("Flag policy for flag '%s' does not " + "have an operation", flagName));
default:
log.warning(String.format("Unknown operation '%s' from invocation policy for flag '%s'", flagPolicy.getOperationCase(), flagName));
break;
}
}
}
use of com.google.devtools.common.options.OptionsParsingException in project bazel by bazelbuild.
the class GenQuery method create.
@Override
@Nullable
public ConfiguredTarget create(RuleContext ruleContext) throws InterruptedException, RuleErrorException {
Artifact outputArtifact = ruleContext.createOutputArtifact();
// The query string
final String query = ruleContext.attributes().get("expression", Type.STRING);
OptionsParser optionsParser = OptionsParser.newOptionsParser(QueryOptions.class);
optionsParser.setAllowResidue(false);
try {
optionsParser.parse(ruleContext.attributes().get("opts", Type.STRING_LIST));
} catch (OptionsParsingException e) {
ruleContext.attributeError("opts", "error while parsing query options: " + e.getMessage());
return null;
}
// Parsed query options
QueryOptions queryOptions = optionsParser.getOptions(QueryOptions.class);
if (queryOptions.keepGoing) {
ruleContext.attributeError("opts", "option --keep_going is not allowed");
return null;
}
if (!queryOptions.universeScope.isEmpty()) {
ruleContext.attributeError("opts", "option --universe_scope is not allowed");
return null;
}
if (optionsParser.containsExplicitOption("order_results")) {
ruleContext.attributeError("opts", "option --order_results is not allowed");
return null;
}
if (optionsParser.containsExplicitOption("noorder_results")) {
ruleContext.attributeError("opts", "option --noorder_results is not allowed");
return null;
}
if (optionsParser.containsExplicitOption("order_output")) {
ruleContext.attributeError("opts", "option --order_output is not allowed");
return null;
}
// Force results to be deterministic.
queryOptions.orderOutput = OrderOutput.FULL;
// force relative_locations to true so it has a deterministic output across machines.
queryOptions.relativeLocations = true;
final byte[] result = executeQuery(ruleContext, queryOptions, getScope(ruleContext), query);
if (result == null || ruleContext.hasErrors()) {
return null;
}
ruleContext.registerAction(new QueryResultAction(ruleContext.getActionOwner(), outputArtifact, result));
NestedSet<Artifact> filesToBuild = NestedSetBuilder.create(Order.STABLE_ORDER, outputArtifact);
return new RuleConfiguredTargetBuilder(ruleContext).setFilesToBuild(filesToBuild).add(RunfilesProvider.class, RunfilesProvider.simple(new Runfiles.Builder(ruleContext.getWorkspaceName(), ruleContext.getConfiguration().legacyExternalRunfiles()).addTransitiveArtifacts(filesToBuild).build())).build();
}
use of com.google.devtools.common.options.OptionsParsingException in project bazel by bazelbuild.
the class BlazeCommandDispatcher method execExclusively.
private int execExclusively(List<String> args, OutErr outErr, long firstContactTime, String commandName, BlazeCommand command, long waitTimeInMs) throws ShutdownBlazeServerException {
Command commandAnnotation = command.getClass().getAnnotation(Command.class);
// Record the start time for the profiler. Do not put anything before this!
long execStartTimeNanos = runtime.getClock().nanoTime();
// The initCommand call also records the start time for the timestamp granularity monitor.
CommandEnvironment env = runtime.getWorkspace().initCommand();
// Record the command's starting time for use by the commands themselves.
env.recordCommandStartTime(firstContactTime);
AbruptExitException exitCausingException = null;
for (BlazeModule module : runtime.getBlazeModules()) {
try {
module.beforeCommand(commandAnnotation, env);
} catch (AbruptExitException e) {
// Don't let one module's complaints prevent the other modules from doing necessary
// setup. We promised to call beforeCommand exactly once per-module before each command
// and will be calling afterCommand soon in the future - a module's afterCommand might
// rightfully assume its beforeCommand has already been called.
outErr.printErrLn(e.getMessage());
// It's not ideal but we can only return one exit code, so we just pick the code of the
// last exception.
exitCausingException = e;
}
}
if (exitCausingException != null) {
return exitCausingException.getExitCode().getNumericExitCode();
}
try {
Path commandLog = getCommandLogPath(env.getOutputBase());
// Unlink old command log from previous build, if present, so scripts
// reading it don't conflate it with the command log we're about to write.
closeSilently(logOutputStream);
logOutputStream = null;
commandLog.delete();
if (env.getRuntime().writeCommandLog() && commandAnnotation.writeCommandLog()) {
logOutputStream = commandLog.getOutputStream();
outErr = tee(outErr, OutErr.create(logOutputStream, logOutputStream));
}
} catch (IOException ioException) {
LoggingUtil.logToRemote(Level.WARNING, "Unable to delete or open command.log", ioException);
}
ExitCode result = checkCwdInWorkspace(env, commandAnnotation, commandName, outErr);
if (!result.equals(ExitCode.SUCCESS)) {
return result.getNumericExitCode();
}
OptionsParser optionsParser;
// Delay output of notes regarding the parsed rc file, so it's possible to disable this in the
// rc file.
List<String> rcfileNotes = new ArrayList<>();
try {
optionsParser = createOptionsParser(command);
parseArgsAndConfigs(env, optionsParser, commandAnnotation, args, rcfileNotes, outErr);
InvocationPolicyEnforcer optionsPolicyEnforcer = new InvocationPolicyEnforcer(runtime.getInvocationPolicy());
optionsPolicyEnforcer.enforce(optionsParser, commandName);
optionsPolicyEnforcer = InvocationPolicyEnforcer.create(getRuntime().getStartupOptionsProvider().getOptions(BlazeServerStartupOptions.class).invocationPolicy);
optionsPolicyEnforcer.enforce(optionsParser, commandName);
} catch (OptionsParsingException e) {
for (String note : rcfileNotes) {
outErr.printErrLn("INFO: " + note);
}
outErr.printErrLn(e.getMessage());
return ExitCode.COMMAND_LINE_ERROR.getNumericExitCode();
}
// Setup log filtering
BlazeCommandEventHandler.Options eventHandlerOptions = optionsParser.getOptions(BlazeCommandEventHandler.Options.class);
OutErr colorfulOutErr = outErr;
if (!eventHandlerOptions.useColor()) {
outErr = ansiStripOut(ansiStripErr(outErr));
if (!commandAnnotation.binaryStdOut()) {
colorfulOutErr = ansiStripOut(colorfulOutErr);
}
if (!commandAnnotation.binaryStdErr()) {
colorfulOutErr = ansiStripErr(colorfulOutErr);
}
}
if (!commandAnnotation.binaryStdOut()) {
outErr = lineBufferOut(outErr);
}
if (!commandAnnotation.binaryStdErr()) {
outErr = lineBufferErr(outErr);
}
CommonCommandOptions commonOptions = optionsParser.getOptions(CommonCommandOptions.class);
if (!commonOptions.verbosity.equals(lastLogVerbosityLevel)) {
BlazeRuntime.setupLogging(commonOptions.verbosity);
lastLogVerbosityLevel = commonOptions.verbosity;
}
// Do this before an actual crash so we don't have to worry about
// allocating memory post-crash.
String[] crashData = env.getCrashData();
int numericExitCode = ExitCode.BLAZE_INTERNAL_ERROR.getNumericExitCode();
PrintStream savedOut = System.out;
PrintStream savedErr = System.err;
EventHandler handler = createEventHandler(outErr, eventHandlerOptions);
Reporter reporter = env.getReporter();
reporter.addHandler(handler);
env.getEventBus().register(handler);
// We register an ANSI-allowing handler associated with {@code handler} so that ANSI control
// codes can be re-introduced later even if blaze is invoked with --color=no. This is useful
// for commands such as 'blaze run' where the output of the final executable shouldn't be
// modified.
EventHandler ansiAllowingHandler = null;
if (!eventHandlerOptions.useColor()) {
ansiAllowingHandler = createEventHandler(colorfulOutErr, eventHandlerOptions);
reporter.registerAnsiAllowingHandler(handler, ansiAllowingHandler);
if (ansiAllowingHandler instanceof ExperimentalEventHandler) {
env.getEventBus().register(new PassiveExperimentalEventHandler((ExperimentalEventHandler) ansiAllowingHandler));
}
}
try {
// While a Blaze command is active, direct all errors to the client's
// event handler (and out/err streams).
OutErr reporterOutErr = reporter.getOutErr();
System.setOut(new PrintStream(reporterOutErr.getOutputStream(), /*autoflush=*/
true));
System.setErr(new PrintStream(reporterOutErr.getErrorStream(), /*autoflush=*/
true));
for (BlazeModule module : runtime.getBlazeModules()) {
module.checkEnvironment(env);
}
if (commonOptions.announceRcOptions) {
for (String note : rcfileNotes) {
reporter.handle(Event.info(note));
}
}
try {
// Notify the BlazeRuntime, so it can do some initial setup.
env.beforeCommand(commandAnnotation, optionsParser, commonOptions, execStartTimeNanos, waitTimeInMs);
// Allow the command to edit options after parsing:
command.editOptions(env, optionsParser);
} catch (AbruptExitException e) {
reporter.handle(Event.error(e.getMessage()));
return e.getExitCode().getNumericExitCode();
}
for (BlazeModule module : runtime.getBlazeModules()) {
module.handleOptions(optionsParser);
}
// Print warnings for odd options usage
for (String warning : optionsParser.getWarnings()) {
reporter.handle(Event.warn(warning));
}
ExitCode outcome = command.exec(env, optionsParser);
outcome = env.precompleteCommand(outcome);
numericExitCode = outcome.getNumericExitCode();
return numericExitCode;
} catch (ShutdownBlazeServerException e) {
numericExitCode = e.getExitStatus();
throw e;
} catch (Throwable e) {
e.printStackTrace();
BugReport.printBug(outErr, e);
BugReport.sendBugReport(e, args, crashData);
numericExitCode = BugReport.getExitCodeForThrowable(e);
throw new ShutdownBlazeServerException(numericExitCode, e);
} finally {
env.getEventBus().post(new AfterCommandEvent());
runtime.afterCommand(env, numericExitCode);
// Swallow IOException, as we are already in a finally clause
Flushables.flushQuietly(outErr.getOutputStream());
Flushables.flushQuietly(outErr.getErrorStream());
System.setOut(savedOut);
System.setErr(savedErr);
reporter.removeHandler(handler);
releaseHandler(handler);
if (!eventHandlerOptions.useColor()) {
reporter.removeHandler(ansiAllowingHandler);
releaseHandler(ansiAllowingHandler);
}
env.getTimestampGranularityMonitor().waitForTimestampGranularity(outErr);
}
}
Aggregations