From: OleksandrZharov Date: Fri, 13 May 2022 18:13:23 +0000 (+0200) Subject: Switch yang-model-validator to argparse4j X-Git-Tag: v9.0.0~47 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=yangtools.git;a=commitdiff_plain;h=60569c85de288552196f166a262d2364165d7d3d Switch yang-model-validator to argparse4j Switched to use argparse4j in yang-model-validator instead of commons-cli. Modernized both tools interactions with argparse4j to the latest best recommended practice. JIRA: YANGTOOLS-1424 Change-Id: I3520d6b398831cdac0843816e857026675fde5a2 Signed-off-by: OleksandrZharov Signed-off-by: Ivan Hrasko --- diff --git a/tools/yang-model-validator/pom.xml b/tools/yang-model-validator/pom.xml index bfbbb53c7a..75b0f620c8 100644 --- a/tools/yang-model-validator/pom.xml +++ b/tools/yang-model-validator/pom.xml @@ -40,9 +40,9 @@ logback-classic - commons-cli - commons-cli - 1.5.0 + net.sourceforge.argparse4j + argparse4j + 0.9.0 diff --git a/tools/yang-model-validator/src/main/java/org/opendaylight/yangtools/yang/validator/Main.java b/tools/yang-model-validator/src/main/java/org/opendaylight/yangtools/yang/validator/Main.java index 1d9aac62de..26d5ffa306 100644 --- a/tools/yang-model-validator/src/main/java/org/opendaylight/yangtools/yang/validator/Main.java +++ b/tools/yang-model-validator/src/main/java/org/opendaylight/yangtools/yang/validator/Main.java @@ -14,19 +14,14 @@ import ch.qos.logback.core.FileAppender; import com.google.common.base.Stopwatch; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collection; import java.util.HashSet; import java.util.List; import java.util.Set; -import org.apache.commons.cli.CommandLine; -import org.apache.commons.cli.CommandLineParser; -import org.apache.commons.cli.DefaultParser; -import org.apache.commons.cli.HelpFormatter; -import org.apache.commons.cli.Option; -import org.apache.commons.cli.OptionGroup; -import org.apache.commons.cli.Options; -import org.apache.commons.cli.ParseException; +import net.sourceforge.argparse4j.ArgumentParsers; +import net.sourceforge.argparse4j.impl.Arguments; +import net.sourceforge.argparse4j.inf.ArgumentParser; +import net.sourceforge.argparse4j.inf.Namespace; import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext; import org.slf4j.Logger; @@ -36,21 +31,7 @@ import org.slf4j.LoggerFactory; * Main class of Yang parser system test. * *

- * yang-system-test [-f features] [-h help] [-p path] [-v verbose] yangFiles... - * -f,--features <arg> features is a string in the form - * [feature(,feature)*] and feature is a string in the form - * [($namespace?revision=$revision)$local_name]. - * This option is used to prune the data model by removing - * all nodes that are defined with a "if-feature". - * -h,--help print help message and exit. - * -p,--path <arg> path is a colon (:) separated list of directories - * to search for yang modules. - * -r, --recursive recursive search of directories specified by -p option - * -v, --verbose shows details about the results of test running. - * -o, --output path to output file for logs. Output file will be overwritten. - * -m, --module-name validate yang by module name. - * -K, --no-warning-for-unkeyed-lists - * do not add warnings about unkeyed lists with config true. + * Type yang-system-test -h for usage. */ @SuppressWarnings({"checkstyle:LoggerMustBeSlf4j", "checkstyle:LoggerFactoryClassParameter"}) public final class Main { @@ -59,82 +40,53 @@ public final class Main { (ch.qos.logback.classic.Logger) LoggerFactory.getLogger(ch.qos.logback.classic.Logger.ROOT_LOGGER_NAME); private static final int MB = 1024 * 1024; - private static final Option FEATURE = new Option("f", "features", true, - "features is a string in the form [feature(,feature)*] and feature is a string in the form " - + "[($namespace?revision=$revision)$local_name]. This option is used to prune the data model " - + "by removing all nodes that are defined with a \"if-feature\"."); - - private static final Option HELP = new Option("h", "help", false, "print help message and exit."); - private static final Option MODULE_NAME = new Option("m", "module-name", true, - "validate yang model by module name."); - private static final Option OUTPUT = new Option("o", "output", true, - "path to output file for logs. Output file will be overwritten"); - private static final Option PATH = new Option("p", "path", true, - "path is a colon (:) separated list of directories to search for yang modules."); - private static final Option RECURSIVE = new Option("r", "recursive", false, - "recursive search of directories specified by -p option."); - - private static final Option DEBUG = new Option("d", "debug", false, "add debug output"); - private static final Option QUIET = new Option("q", "quiet", false, "completely suppress output."); - private static final Option VERBOSE = new Option("v", "verbose", false, - "shows details about the results of test running."); - private static final Option LIST_WARNING_OFF = new Option("K", "no-warning-for-unkeyed-lists", false, - "do not add warnings about unkeyed lists with config true"); + private static final String YANG_MODEL = "yang-model"; + private static final String PATH = "path"; + private static final String RECURSIVE = "recursive"; + private static final String LIST_WARNING_OFF = "no-warning-for-unkeyed-lists"; + private static final String OUTPUT = "output"; + private static final String MODULE_NAME = "module-name"; + private static final String FEATURES = "features"; + private static final String DEBUG = "debug"; + private static final String QUIET = "quiet"; + private static final String VERBOSE = "verbose"; private Main() { // Hidden on purpose } - private static Options createOptions() { - return new Options() - .addOption(HELP) - .addOption(PATH) - .addOption(RECURSIVE) - .addOptionGroup(new OptionGroup().addOption(DEBUG).addOption(QUIET).addOption(VERBOSE)) - .addOption(LIST_WARNING_OFF) - .addOption(OUTPUT) - .addOption(MODULE_NAME) - .addOption(FEATURE); - } - public static void main(final String[] args) { - final HelpFormatter formatter = new HelpFormatter(); - final Options options = createOptions(); - final CommandLine arguments = parseArguments(args, options, formatter); - - if (arguments.hasOption(HELP.getLongOpt())) { - printHelp(options, formatter); - return; - } + final ArgumentParser parser = getParser(); + final Namespace arguments = parser.parseArgsOrFail(args); - final String[] outputValues = arguments.getOptionValues(OUTPUT.getLongOpt()); + final String outputValues = arguments.get(OUTPUT); if (outputValues != null) { setOutput(outputValues); } LOG_ROOT.setLevel(Level.WARN); - if (arguments.hasOption(DEBUG.getLongOpt())) { + if (arguments.getBoolean(DEBUG)) { LOG_ROOT.setLevel(Level.DEBUG); - } else if (arguments.hasOption(VERBOSE.getLongOpt())) { + } else if (arguments.getBoolean(VERBOSE)) { LOG_ROOT.setLevel(Level.INFO); - } else if (arguments.hasOption(QUIET.getLongOpt())) { + } else if (arguments.getBoolean(QUIET)) { LOG_ROOT.detachAndStopAllAppenders(); } - final boolean warnForUnkeyedLists = !arguments.hasOption(LIST_WARNING_OFF.getLongOpt()); - final List yangLibDirs = initYangDirsPath(arguments); final List yangFiles = new ArrayList<>(); - final String[] moduleNameValues = arguments.getOptionValues(MODULE_NAME.getLongOpt()); + final List moduleNameValues = arguments.get(MODULE_NAME); if (moduleNameValues != null) { - yangFiles.addAll(Arrays.asList(moduleNameValues)); + yangFiles.addAll(moduleNameValues); + } + if (arguments.get(YANG_MODEL) != null) { + yangFiles.addAll(arguments.get(YANG_MODEL)); } - yangFiles.addAll(Arrays.asList(arguments.getArgs())); final Set supportedFeatures = initSupportedFeatures(arguments); - runSystemTest(yangLibDirs, yangFiles, supportedFeatures, arguments.hasOption(RECURSIVE.getLongOpt()), - warnForUnkeyedLists); + runSystemTest(yangLibDirs, yangFiles, supportedFeatures, arguments.getBoolean(RECURSIVE), + !arguments.getBoolean(LIST_WARNING_OFF)); LOG_ROOT.getLoggerContext().reset(); } @@ -190,23 +142,20 @@ public final class Main { printMemoryInfo("after gc"); } - private static List initYangDirsPath(final CommandLine arguments) { + private static List initYangDirsPath(final Namespace arguments) { final List yangDirs = new ArrayList<>(); - if (arguments.hasOption("path")) { - for (final String pathArg : arguments.getOptionValues("path")) { - yangDirs.addAll(Arrays.asList(pathArg.split(":"))); - } + final List path = arguments.get(PATH); + if (path != null) { + yangDirs.addAll(path); } return yangDirs; } - private static Set initSupportedFeatures(final CommandLine arguments) { - Set supportedFeatures = null; - if (arguments.hasOption("features")) { - supportedFeatures = new HashSet<>(); - for (final String pathArg : arguments.getOptionValues("features")) { - supportedFeatures.addAll(createQNames(pathArg.split(","))); - } + private static Set initSupportedFeatures(final Namespace arguments) { + final Set supportedFeatures = new HashSet<>(); + final List features = arguments.get(FEATURES); + if (features != null) { + supportedFeatures.addAll(createQNames(features.toArray(new String[0]))); } return supportedFeatures; } @@ -216,29 +165,62 @@ public final class Main { for (final String featureStr : featuresArg) { qnames.add(QName.create(featureStr)); } - return qnames; } - @SuppressFBWarnings("DM_EXIT") - private static CommandLine parseArguments(final String[] args, final Options options, - final HelpFormatter formatter) { - final CommandLineParser parser = new DefaultParser(); - - CommandLine cmd = null; - try { - cmd = parser.parse(options, args); - } catch (final ParseException e) { - LOG.error("Failed to parse command line options.", e); - printHelp(options, formatter); - System.exit(1); - } - - return cmd; - } - - private static void printHelp(final Options options, final HelpFormatter formatter) { - formatter.printHelp("yang-system-test [OPTION...] YANG-FILE...", options); + private static ArgumentParser getParser() { + final var parser = ArgumentParsers.newFor("yang-system-test").addHelp(true).build() + .description("Main class of Yang parser system test."); + parser.addArgument(YANG_MODEL) + .help("yang file(s) to validate") + .dest(YANG_MODEL) + .nargs("*") + .metavar(YANG_MODEL) + .type(String.class); + parser.addArgument("-p", "--path") + .help("path is a space separated list of directories to search for yang modules") + .dest(PATH) + .nargs("+") + .type(String.class); + parser.addArgument("-r", "--recursive") + .help("recursive search of directories specified by -p option") + .dest(RECURSIVE) + .action(Arguments.storeTrue()); + parser.addArgument("-K", "--no-warning-for-unkeyed-lists") + .help("do not add warnings about unkeyed lists with config true") + .dest(LIST_WARNING_OFF) + .action(Arguments.storeTrue()); + parser.addArgument("-o", "--output") + .help("path to output file for logs. Output file will be overwritten") + .dest(OUTPUT); + parser.addArgument("-m", "--module-name") + .help("validate yang model by module name.") + .dest(MODULE_NAME) + .nargs("+") + .type(String.class); + parser.addArgument("-f", "--features").help( + """ + features is a space separated list strings in the form [($namespace?revision=$revision)$local_name]. + This option is used to prune the data model by removing all nodes that are defined with a "if-feature". + """) + .dest(FEATURES) + .nargs("+") + .type(String.class); + final var group = parser.addMutuallyExclusiveGroup("logging") + .description("exclusive group for logging parameters"); + group.addArgument("-d", "--debug") + .help("add debug output") + .dest(DEBUG) + .action(Arguments.storeTrue()); + group.addArgument("-q", "--quiet") + .help("completely suppress output") + .dest(QUIET) + .action(Arguments.storeTrue()); + group.addArgument("-v", "--verbose") + .help("shows details about the results of test running") + .dest(VERBOSE) + .action(Arguments.storeTrue()); + return parser; } private static void printMemoryInfo(final String info) { diff --git a/tools/yang-validation-tool/src/main/java/org/opendaylight/yangtools/yang/validation/tool/Params.java b/tools/yang-validation-tool/src/main/java/org/opendaylight/yangtools/yang/validation/tool/Params.java index aab1789532..4117c08f23 100644 --- a/tools/yang-validation-tool/src/main/java/org/opendaylight/yangtools/yang/validation/tool/Params.java +++ b/tools/yang-validation-tool/src/main/java/org/opendaylight/yangtools/yang/validation/tool/Params.java @@ -21,7 +21,7 @@ final class Params { private File yangSourceDir; static ArgumentParser getParser() { - final ArgumentParser parser = ArgumentParsers.newArgumentParser("jar_file_name"); + final ArgumentParser parser = ArgumentParsers.newFor("jar_file_name").addHelp(true).build(); parser.description("Validation Tool for Yang Models") .formatUsage();