Skip to content

Commit

Permalink
Add show/hide validation event filtering to CLI
Browse files Browse the repository at this point in the history
The --show-validators and --hide-validators can now be used in the CLI
anywhere that --severity was being used. This allows validation events
to be hidden/show explicitly based on a comma separated list of
heirarchical validation event IDs (i.e., dot based prefix event
matching just like suppressions).
  • Loading branch information
mtdowling committed Feb 6, 2024
1 parent bc5b7df commit 33922a3
Show file tree
Hide file tree
Showing 7 changed files with 256 additions and 86 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ public String getSummary() {
public int execute(Arguments arguments, Env env) {
arguments.addReceiver(new ConfigOptions());
arguments.addReceiver(new DiscoveryOptions());
arguments.addReceiver(new SeverityOption());
arguments.addReceiver(new ValidatorOptions());
arguments.addReceiver(new BuildOptions());
arguments.addReceiver(new Options());

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ public String getSummary() {
@Override
public int execute(Arguments arguments, Env env) {
arguments.addReceiver(new ConfigOptions());
arguments.addReceiver(new SeverityOption());
arguments.addReceiver(new ValidatorOptions());
arguments.addReceiver(new BuildOptions());
arguments.addReceiver(new Options());
arguments.getReceiver(BuildOptions.class).noPositionalArguments(true);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,13 @@ public Model build() {

StandardOptions standardOptions = arguments.getReceiver(StandardOptions.class);
BuildOptions buildOptions = arguments.getReceiver(BuildOptions.class);
Severity minSeverity = resolveMinSeverity(standardOptions);

// Resolve validator options and severity.
ValidatorOptions validatorOption = arguments.hasReceiver(ValidatorOptions.class)
? arguments.getReceiver(ValidatorOptions.class) : new ValidatorOptions();
Severity minSeverity = resolveMinSeverity(standardOptions, validatorOption);
validatorOption.severity(minSeverity);

ClassLoader classLoader = env.classLoader();
ColorFormatter colors = env.colors();
CliPrinter stderr = env.stderr();
Expand Down Expand Up @@ -176,8 +182,8 @@ public Model build() {

for (ValidationEvent event : sortedEvents) {
// Only log events that are >= --severity. Note that setting --quiet inherently
// configures events to need to be >= DANGER.
if (event.getSeverity().ordinal() >= minSeverity.ordinal()) {
// configures events to need to be >= DANGER. Also filter using --show-validators and --hide-validators.
if (validatorOption.isVisible(event)) {
validationPrinter.println(formatter.format(event));
}
}
Expand Down Expand Up @@ -274,13 +280,11 @@ private static void discoverModelsWithClasspath(String rawClasspath, ModelAssemb
}

// Determine a default severity if one wasn't given, by inspecting if there is a --severity option.
private Severity resolveMinSeverity(StandardOptions standardOptions) {
private Severity resolveMinSeverity(StandardOptions standardOptions, ValidatorOptions validatorOption) {
if (severity != null) {
return severity;
} else if (arguments.hasReceiver(SeverityOption.class)) {
return arguments.getReceiver(SeverityOption.class).severity(standardOptions);
} else {
return Severity.WARNING;
return validatorOption.severity(standardOptions);
}
}

Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ public String getSummary() {
public int execute(Arguments arguments, Env env) {
arguments.addReceiver(new ConfigOptions());
arguments.addReceiver(new DiscoveryOptions());
arguments.addReceiver(new SeverityOption());
arguments.addReceiver(new ValidatorOptions());
arguments.addReceiver(new BuildOptions());

CommandAction action = HelpActionWrapper.fromCommand(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
/*
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/

package software.amazon.smithy.cli.commands;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.function.Consumer;
import software.amazon.smithy.cli.ArgumentReceiver;
import software.amazon.smithy.cli.CliError;
import software.amazon.smithy.cli.HelpPrinter;
import software.amazon.smithy.cli.StandardOptions;
import software.amazon.smithy.model.validation.Severity;
import software.amazon.smithy.model.validation.ValidationEvent;

/**
* Add validation specific options.
*/
final class ValidatorOptions implements ArgumentReceiver {

static final String SEVERITY = "--severity";
static final String SHOW_VALIDATORS = "--show-validators";
static final String HIDE_VALIDATORS = "--hide-validators";

private Severity severity;
private List<String> showValidators = Collections.emptyList();
private List<String> hideValidators = Collections.emptyList();

@Override
public void registerHelp(HelpPrinter printer) {
printer.param(SEVERITY, null, "SEVERITY", "Set the minimum reported validation severity (one of NOTE, "
+ "WARNING [default setting], DANGER, ERROR).");
printer.param(SHOW_VALIDATORS, null, "VALIDATORS", "Comma-separated list of hierarchical validation event "
+ "IDs to show in the output of the command, "
+ "hiding the rest.");
printer.param(HIDE_VALIDATORS, null, "VALIDATORS", "Comma-separated list of hierarchical validation event "
+ "IDs to hide in the output of the command, "
+ "showing the rest.");
}

@Override
public Consumer<String> testParameter(String name) {
switch (name) {
case SEVERITY:
return value -> {
severity(Severity.fromString(value).orElseThrow(() -> {
return new CliError("Invalid severity level: " + value);
}));
};
case SHOW_VALIDATORS:
return value -> {
if (!hideValidators.isEmpty()) {
throw new CliError(SHOW_VALIDATORS + " and " + HIDE_VALIDATORS + " are mutually exclusive");
}
showValidators(parseIds(value));
};
case HIDE_VALIDATORS:
return value -> {
if (!showValidators.isEmpty()) {
throw new CliError(SHOW_VALIDATORS + " and " + HIDE_VALIDATORS + " are mutually exclusive");
}
hideValidators(parseIds(value));
};
default:
return null;
}
}

private List<String> parseIds(String value) {
List<String> result = new ArrayList<>();
for (String id : value.split("\\s*,\\s*")) {
id = id.trim();
if (id.isEmpty()) {
throw new CliError("Invalid validation event ID");
}
result.add(id);
}
return result;
}

/**
* Set the severity.
*
* @param severity Severity to set.
*/
void severity(Severity severity) {
this.severity = severity;
}

/**
* Get the severity level, taking into account standard options that affect the default.
*
* @param options Standard options to query if no severity is explicitly set.
* @return Returns the resolved severity option.
*/
Severity severity(StandardOptions options) {
if (severity != null) {
return severity;
} else if (options.quiet()) {
return Severity.DANGER;
} else {
return Severity.WARNING;
}
}

/**
* Set the list of validators to show, but hide everything else.
*
* @param validators Validators to show.
*/
void showValidators(List<String> validators) {
this.showValidators = validators;
}

/**
* Get the list of validators to show.
*
* @return Validator event IDs.
*/
List<String> showValidators() {
return showValidators;
}

/**
* Get the list of validators to hide.
*
* @return Validator event IDs.
*/
List<String> hideValidators(String csv) {
return hideValidators;
}

/**
* Set the list of validators to hide.
*
* @param validators Validators to hide.
*/
void hideValidators(List<String> validators) {
this.hideValidators = validators;
}

/**
* Check if the given validation event matches the show/hide settings.
*
* <p>A severity must be set before calling this method.
*
* @param event Event to check.
* @return Return true if the event can be seen.
*/
boolean isVisible(ValidationEvent event) {
if (event.getSeverity().ordinal() < severity.ordinal()) {
return false;
}

if (!showValidators.isEmpty()) {
for (String show : showValidators) {
if (event.containsId(show)) {
return true;
}
}
return false;
}

if (!hideValidators.isEmpty()) {
for (String hide : hideValidators) {
if (event.containsId(hide)) {
return false;
}
}
}

return true;
}
}
Loading

0 comments on commit 33922a3

Please sign in to comment.