From bb25bd367e90d857fb93fd3fb2a52afc82a00993 Mon Sep 17 00:00:00 2001 From: Luolc Date: Fri, 21 Jul 2017 01:47:36 +0800 Subject: [PATCH] Issue #32: Main --- .travis.yml | 6 + appveyor.yml | 4 + config/import-control.xml | 3 + pom.xml | 81 +++++++ .../github/checkstyle/regression/Main.java | 204 +++++++++++++++++- 5 files changed, 297 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 7e29498..6a91b90 100644 --- a/.travis.yml +++ b/.travis.yml @@ -60,6 +60,12 @@ matrix: - CMD8="mvn test -Dtest=ExtractInfoGeneratorTest#generateExtractInfoFile" - CMD="$CMD1$CMD2$CMD3$CMD4$CMD5$CMD6$CMD7$CMD8" + # package no error (oraclejdk8) + - jdk: oraclejdk8 + env: + - DESC="package no error" + - CMD="mvn clean package -Passembly" + script: eval $CMD after_success: diff --git a/appveyor.yml b/appveyor.yml index 2c6a1d9..b3a793a 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -61,6 +61,10 @@ environment: - JAVA_HOME: C:\Program Files\Java\jdk1.8.0 DESC: "verify without checkstyle" CMD1: "mvn -e verify -Dcheckstyle.ant.skip=true -Dcheckstyle.skip=true" + # package no error + - JAVA_HOME: C:\Program Files\Java\jdk1.8.0 + DESC: "package no error" + CMD1: "mvn clean package -Passembly" build_script: - ps: > diff --git a/config/import-control.xml b/config/import-control.xml index b5aba58..c9411e6 100644 --- a/config/import-control.xml +++ b/config/import-control.xml @@ -4,6 +4,9 @@ "http://www.puppycrawl.com/dtds/import_control_1_1.dtd"> + + + diff --git a/pom.xml b/pom.xml index 201cda1..dc50c7a 100644 --- a/pom.xml +++ b/pom.xml @@ -219,6 +219,28 @@ + + + + org.apache.maven.plugins + maven-jar-plugin + 3.0.2 + + + + true + true + + + + + + + test-jar + + + + @@ -261,6 +283,65 @@ + + + + assembly + + true + true + true + true + true + true + true + true + true + true + + true + + + + + + + org.apache.maven.plugins + maven-shade-plugin + 3.0.0 + + + package + + shade + + + true + all + + + com.github.checkstyle.regression.Main + + + + + *:* + + META-INF/*.SF + META-INF/*.DSA + META-INF/*.RSA + + + + + + + + + + + cobertura-check diff --git a/src/main/java/com/github/checkstyle/regression/Main.java b/src/main/java/com/github/checkstyle/regression/Main.java index 11d1b09..e678757 100644 --- a/src/main/java/com/github/checkstyle/regression/Main.java +++ b/src/main/java/com/github/checkstyle/regression/Main.java @@ -19,11 +19,51 @@ package com.github.checkstyle.regression; +import java.io.File; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Optional; + +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.Options; +import org.apache.commons.cli.ParseException; +import org.immutables.value.Value; + +import com.github.checkstyle.regression.configuration.ConfigGenerator; +import com.github.checkstyle.regression.data.GitChange; +import com.github.checkstyle.regression.data.ModuleExtractInfo; +import com.github.checkstyle.regression.data.ModuleInfo; +import com.github.checkstyle.regression.extract.ExtractInfoProcessor; +import com.github.checkstyle.regression.git.DiffParser; +import com.github.checkstyle.regression.module.ModuleCollector; +import com.github.checkstyle.regression.module.ModuleUtils; +import com.github.checkstyle.regression.report.ReportGenerator; + /** * Utility class, contains main function and its auxiliary routines. * @author LuoLiangchen */ public final class Main { + /** Option name of the local checkstyle repository path. */ + private static final String OPT_LOCAL_GIT_REPO = "localGitRepo"; + + /** Option name of the PR branch name. */ + private static final String OPT_PATCH_BRANCH = "patchBranch"; + + /** Option name of checkstyle-tester path. */ + private static final String OPT_CHECKSTYLE_TESTER_PATH = "checkstyleTesterPath"; + + /** Option name of whether to stop after generating config. */ + private static final String OPT_STOP_AFTER_GENERATE_CONFIG = "stopAfterGenerateConfig"; + /** Prevents instantiation. */ private Main() { } @@ -34,6 +74,168 @@ private Main() { * @throws Exception execute failure */ public static void main(String[] args) throws Exception { - // empty for now + final Options options = createOptions(); + final CommandLineParser parser = new DefaultParser(); + final HelpFormatter formatter = new HelpFormatter(); + CommandLine cmd = null; + + try { + cmd = parser.parse(options, args); + } + catch (ParseException ex) { + System.err.println(ex.getMessage()); + formatter.printHelp("java -jar regression-tool.jar", options, true); + System.exit(1); + } + + final Arguments arguments = ImmutableArguments.builder() + .repoPath(cmd.getOptionValue(OPT_LOCAL_GIT_REPO)) + .branch(cmd.getOptionValue(OPT_PATCH_BRANCH)) + .checkstyleTesterPath( + Optional.ofNullable(cmd.getOptionValue(OPT_CHECKSTYLE_TESTER_PATH))) + .stopAfterGenerateConfig(cmd.hasOption(OPT_STOP_AFTER_GENERATE_CONFIG)) + .build(); + + validateArguments(arguments); + runRegression(arguments); + } + + /** + * Creates and initializes the {@link Options} instance. + * @return the initialized options + */ + private static Options createOptions() { + final Options options = new Options(); + + final Option repo = Option.builder("r") + .longOpt(OPT_LOCAL_GIT_REPO) + .required() + .hasArg() + .desc("the path of the checkstyle repository") + .build(); + repo.setRequired(true); + options.addOption(repo); + + final Option branch = Option.builder("p") + .longOpt(OPT_PATCH_BRANCH) + .required() + .hasArg() + .desc("the name of the PR branch") + .build(); + options.addOption(branch); + + final Option tester = Option.builder("t") + .longOpt(OPT_CHECKSTYLE_TESTER_PATH) + .required(false) + .hasArg() + .desc("the path of the checkstyle-tester directory") + .build(); + options.addOption(tester); + + final Option stopAfterGenerateConfig = Option.builder() + .longOpt(OPT_STOP_AFTER_GENERATE_CONFIG) + .required(false) + .hasArg(false) + .desc("indicates that regression tool would stop after generating config") + .build(); + options.addOption(stopAfterGenerateConfig); + + return options; + } + + /** + * Validates the parsed CLI arguments. + * @param args the parsed CLI arguments. + * @throws IllegalArgumentException the arguments are invalid + */ + private static void validateArguments(Arguments args) { + if (!existAndIsDirectory(args.repoPath())) { + throw new IllegalArgumentException( + "path of local git repo must exist and be a directory"); + } + if (!args.stopAfterGenerateConfig()) { + if (args.checkstyleTesterPath().isPresent()) { + if (!existAndIsDirectory(args.checkstyleTesterPath().get())) { + throw new IllegalArgumentException( + "path of checkstyle tester must exist and be a directory"); + } + } + else { + throw new IllegalArgumentException("missing checkstyleTesterPath, " + + "which is required if you are not using --stopAfterGenerateConfig mode"); + } + } + } + + /** + * Runs the regression tool. + * @param args the parsed CLI arguments. + * @throws Exception execute failure + */ + private static void runRegression(Arguments args) throws Exception { + final File config = generateConfig(args); + System.out.println("config generated at " + config.getAbsolutePath()); + if (!args.stopAfterGenerateConfig()) { + final File report = ReportGenerator.generate( + args.checkstyleTesterPath().get(), args.repoPath(), args.branch(), config); + System.out.println("report generated at " + report.getAbsolutePath()); + } + } + + /** + * Generates the config file. + * @param args the parsed CLI arguments. + * @return the generated config file + * @throws Exception generation failure + */ + private static File generateConfig(Arguments args) + throws Exception { + final List changes = DiffParser.parse(args.repoPath(), args.branch()); + final Map extractInfos = + ExtractInfoProcessor.getModuleExtractInfos(args.repoPath(), args.branch()); + ModuleUtils.setNameToModuleExtractInfo(extractInfos); + final List moduleInfos = ModuleCollector.generate(changes); + final DateFormat format = new SimpleDateFormat("yyyyMMddHHmmss", Locale.getDefault()); + final String configFileName = + String.format("config-%s-%s.xml", args.branch(), format.format(new Date())); + return ConfigGenerator.generateConfig(configFileName, moduleInfos); + } + + /** + * Checks whether the file in given path exists and is a directory. + * @param path the path to check + * @return true if file exists and is a directory + */ + private static boolean existAndIsDirectory(String path) { + final File file = new File(path); + return !path.isEmpty() && file.exists() && file.isDirectory(); + } + + /** Represents the CLI arguments. */ + @Value.Immutable + /* default */ interface Arguments { + /** + * The local checkstyle repository path. + * @return the local checkstyle repository path + */ + String repoPath(); + + /** + * The PR branch name. + * @return the PR branch name + */ + String branch(); + + /** + * Checkstyle-tester path. + * @return Checkstyle-tester path + */ + Optional checkstyleTesterPath(); + + /** + * Whether to stop after generating config. + * @return whether to stop after generating config + */ + boolean stopAfterGenerateConfig(); } }