Search in sources :

Example 11 with OptionsParsingException

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);
    }
}
Also used : LabelSyntaxException(com.google.devtools.build.lib.cmdline.LabelSyntaxException) TokenizationException(com.google.devtools.build.lib.shell.ShellUtils.TokenizationException) ArrayList(java.util.ArrayList) Label(com.google.devtools.build.lib.cmdline.Label) OptionsParsingException(com.google.devtools.common.options.OptionsParsingException)

Example 12 with OptionsParsingException

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();
}
Also used : UnparsedOptionValueDescription(com.google.devtools.common.options.OptionsParser.UnparsedOptionValueDescription) OptionsParsingException(com.google.devtools.common.options.OptionsParsingException)

Example 13 with OptionsParsingException

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;
        }
    }
}
Also used : OptionValueDescription(com.google.devtools.common.options.OptionsParser.OptionValueDescription) OptionDescription(com.google.devtools.common.options.OptionsParser.OptionDescription) FlagPolicy(com.google.devtools.build.lib.runtime.proto.InvocationPolicyOuterClass.FlagPolicy) DisallowValues(com.google.devtools.build.lib.runtime.proto.InvocationPolicyOuterClass.DisallowValues) AllowValues(com.google.devtools.build.lib.runtime.proto.InvocationPolicyOuterClass.AllowValues) OptionsParsingException(com.google.devtools.common.options.OptionsParsingException)

Example 14 with OptionsParsingException

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();
}
Also used : Runfiles(com.google.devtools.build.lib.analysis.Runfiles) RuleConfiguredTargetBuilder(com.google.devtools.build.lib.analysis.RuleConfiguredTargetBuilder) OptionsParsingException(com.google.devtools.common.options.OptionsParsingException) OptionsParser(com.google.devtools.common.options.OptionsParser) QueryOptions(com.google.devtools.build.lib.query2.output.QueryOptions) RunfilesProvider(com.google.devtools.build.lib.analysis.RunfilesProvider) Artifact(com.google.devtools.build.lib.actions.Artifact) Nullable(javax.annotation.Nullable)

Example 15 with OptionsParsingException

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);
    }
}
Also used : ExitCode(com.google.devtools.build.lib.util.ExitCode) ArrayList(java.util.ArrayList) EventHandler(com.google.devtools.build.lib.events.EventHandler) Path(com.google.devtools.build.lib.vfs.Path) PrintStream(java.io.PrintStream) DelegatingOutErr(com.google.devtools.build.lib.util.io.DelegatingOutErr) OutErr(com.google.devtools.build.lib.util.io.OutErr) Reporter(com.google.devtools.build.lib.events.Reporter) IOException(java.io.IOException) OptionsParser(com.google.devtools.common.options.OptionsParser) InvocationPolicyEnforcer(com.google.devtools.build.lib.flags.InvocationPolicyEnforcer) OptionsParsingException(com.google.devtools.common.options.OptionsParsingException) AbruptExitException(com.google.devtools.build.lib.util.AbruptExitException)

Aggregations

OptionsParsingException (com.google.devtools.common.options.OptionsParsingException)26 InvocationPolicyEnforcer (com.google.devtools.build.lib.flags.InvocationPolicyEnforcer)15 InvocationPolicy (com.google.devtools.build.lib.runtime.proto.InvocationPolicyOuterClass.InvocationPolicy)11 Test (org.junit.Test)11 OptionsParser (com.google.devtools.common.options.OptionsParser)6 Path (com.google.devtools.build.lib.vfs.Path)3 PackageCacheOptions (com.google.devtools.build.lib.pkgcache.PackageCacheOptions)2 BlazeRuntime (com.google.devtools.build.lib.runtime.BlazeRuntime)2 AbruptExitException (com.google.devtools.build.lib.util.AbruptExitException)2 OptionsBase (com.google.devtools.common.options.OptionsBase)2 IOException (java.io.IOException)2 ArrayList (java.util.ArrayList)2 Map (java.util.Map)2 Artifact (com.google.devtools.build.lib.actions.Artifact)1 RuleConfiguredTargetBuilder (com.google.devtools.build.lib.analysis.RuleConfiguredTargetBuilder)1 Runfiles (com.google.devtools.build.lib.analysis.Runfiles)1 RunfilesProvider (com.google.devtools.build.lib.analysis.RunfilesProvider)1 BuildOptions (com.google.devtools.build.lib.analysis.config.BuildOptions)1 FragmentOptions (com.google.devtools.build.lib.analysis.config.FragmentOptions)1 Label (com.google.devtools.build.lib.cmdline.Label)1