diff --git a/.ci/travis.sh b/.ci/travis.sh index 4c0e9c46b..bcbfabad9 100755 --- a/.ci/travis.sh +++ b/.ci/travis.sh @@ -34,9 +34,11 @@ patch-diff-report-tool) checkstyle-tester-launch-groovy) checkout_from https://github.com/checkstyle/checkstyle cd .ci-temp/checkstyle + LOCAL_GIT_REPO=$(pwd) mvn --batch-mode clean install -Passembly cd ../../checkstyle-tester - groovy launch.groovy -l projects-for-travis.properties -c my_check.xml -i + groovy diff.groovy -r "$LOCAL_GIT_REPO" -l projects-for-travis.properties --patchConfig my_check.xml \ + --patchBranch master --mode single --allowExcludes ;; checkstyle-tester-diff-groovy-patch) @@ -69,6 +71,74 @@ checkstyle-tester-diff-groovy-patch-only) -pc my_check.xml -p patch-branch -r ../.ci-temp/checkstyle -m single ;; +checkstyle-tester-diff-groovy-regression-single) + # Check out lateset checkstyle from master + rm -rf .ci-temp + checkout_from https://github.com/checkstyle/checkstyle + + # Run report from master branch of contribution + checkout_from https://github.com/checkstyle/contribution + cd .ci-temp/contribution/checkstyle-tester + sed -i'' 's/^guava/#guava/' projects-to-test-on.properties + sed -i'' 's/#checkstyle|/checkstyle|/' projects-to-test-on.properties + export MAVEN_OPTS="-Xmx2048m" + groovy ./diff.groovy --listOfProjects projects-to-test-on.properties \ + -pc ../../../checkstyle-tester/diff-groovy-regression-config.xml \ + -r ../../checkstyle -xm "-Dcheckstyle.failsOnError=false" \ + -m single -p master + + # Run report with current branch + cd ../../../checkstyle-tester/ + sed -i'' 's/^guava/#guava/' projects-to-test-on.properties + sed -i'' 's/#checkstyle|/checkstyle|/' projects-to-test-on.properties + rm -rf reports repositories + groovy ./diff.groovy --listOfProjects projects-to-test-on.properties \ + -pc diff-groovy-regression-config.xml -r ../.ci-temp/checkstyle/ \ + -m single -p master -xm "-Dcheckstyle.failsOnError=false" + + cd .. + # We need to ignore file paths below, since they will be different between reports + diff -I "contribution" checkstyle-tester/reports/diff/checkstyle/index.html \ + .ci-temp/contribution/checkstyle-tester/reports/diff/checkstyle/index.html + ;; + +checkstyle-tester-diff-groovy-regression) + # Check out latest checkstyle from master + rm -rf .ci-temp + checkout_from https://github.com/checkstyle/checkstyle + cd .ci-temp/checkstyle + MASTER_BRANCH_SHA=$(git log -n 1 --pretty=format:"%H") + cd ../.. + + # Run report from master branch of contribution + checkout_from https://github.com/checkstyle/contribution + cd .ci-temp/contribution/checkstyle-tester + sed -i'' 's/^guava/#guava/' projects-to-test-on.properties + sed -i'' 's/#checkstyle|/checkstyle|/' projects-to-test-on.properties + rm -rf reports repositories + export MAVEN_OPTS="-Xmx2048m" + groovy ./diff.groovy --listOfProjects projects-to-test-on.properties \ + -c ../../../checkstyle-tester/diff-groovy-regression-config.xml \ + -r ../../checkstyle \ + -b "$MASTER_BRANCH_SHA" -p 7190c47ca5515ad8cb827bc4065ae7664d2766c1 \ + -xm "-Dcheckstyle.failsOnError=false" + + # Run report with current branch + cd ../../../checkstyle-tester/ + sed -i'' 's/^guava/#guava/' projects-to-test-on.properties + sed -i'' 's/#checkstyle|/checkstyle|/' projects-to-test-on.properties + rm -rf reports repositories + groovy ./diff.groovy --listOfProjects projects-to-test-on.properties \ + -c diff-groovy-regression-config.xml -r ../.ci-temp/checkstyle/ \ + -b "$MASTER_BRANCH_SHA" -p 7190c47ca5515ad8cb827bc4065ae7664d2766c1 \ + -xm "-Dcheckstyle.failsOnError=false" + + cd .. + # We need to ignore file paths below, since they will be different between reports + diff -I "contribution" checkstyle-tester/reports/diff/checkstyle/index.html \ + .ci-temp/contribution/checkstyle-tester/reports/diff/checkstyle/index.html + ;; + codenarc) cd checkstyle-tester ./codenarc.sh . diff.groovy > diff.log && cat diff.log && grep '(p1=0; p2=0; p3=0)' diff.log diff --git a/.travis.yml b/.travis.yml index 9d2bb53c5..05016af5c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -44,6 +44,16 @@ matrix: - DESC="checkstyle-tester (diff.groovy) on linux with enabled patchOnly" - CMD="./.ci/travis.sh checkstyle-tester-diff-groovy-patch-only" + - jdk: openjdk8 + env: + - DESC="checkstyle-tester (diff.groovy) regression on linux in single mode" + - CMD="./.ci/travis.sh checkstyle-tester-diff-groovy-regression-single" + + - jdk: openjdk8 + env: + - DESC="checkstyle-tester (diff.groovy) regression on linux with master specified" + - CMD="./.ci/travis.sh checkstyle-tester-diff-groovy-regression" + # disabled till https://github.com/checkstyle/contribution/issues/448 # - jdk: openjdk8 # env: diff --git a/appveyor.yml b/appveyor.yml index a5ce9b200..c0d677035 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -83,7 +83,7 @@ environment: CMD3: " && cd checkstyle && git checkout -b patch-branch" CMD4: " " CMD5: " && cd ..\\checkstyle-tester " - CMD6: " && groovy diff.groovy -l projects-for-travis.properties -c my_check.xml -b master -p patch-branch -r C:\\projects\\contribution\\checkstyle -i -s" + CMD6: " && groovy diff.groovy -l projects-for-travis.properties -c my_check.xml -b master -p patch-branch -r C:\\projects\\contribution\\checkstyle -s" - JAVA_HOME: C:\Program Files\Java\jdk1.8.0 DESC: "checkstyle-tester (diff.groovy with base and patch configs) on guava" CMD1: " git clone -q --depth=10 --branch=master " @@ -91,7 +91,7 @@ environment: CMD3: " && cd checkstyle && git checkout -b patch-branch" CMD4: " " CMD5: " && cd ..\\checkstyle-tester " - CMD6: " && groovy diff.groovy -l projects-for-travis.properties -bc my_check.xml -pc my_check.xml -b master -p patch-branch -r C:\\projects\\contribution\\checkstyle -i -s" + CMD6: " && groovy diff.groovy -l projects-for-travis.properties -bc my_check.xml -pc my_check.xml -b master -p patch-branch -r C:\\projects\\contribution\\checkstyle -s" build_script: - ps: > diff --git a/checkstyle-tester/LAUNCH_GROOVY_README.md b/checkstyle-tester/LAUNCH_GROOVY_README.md index 6041433be..6bea7e274 100644 --- a/checkstyle-tester/LAUNCH_GROOVY_README.md +++ b/checkstyle-tester/LAUNCH_GROOVY_README.md @@ -1,3 +1,5 @@ +# _LAUNCH.GROOVY IS BEING DEPRECATED!!!_ + # launch.groovy Checkstyle report generation diff --git a/checkstyle-tester/README.md b/checkstyle-tester/README.md index 1d7e965d7..55306f27a 100644 --- a/checkstyle-tester/README.md +++ b/checkstyle-tester/README.md @@ -26,7 +26,7 @@ you may require other tools like Git or Mericural, for Git and HG repositories r `diff.groovy` supports the following command line arguments: -**localGitRepo** (r) - path to the local Checkstyle repository (required); +**localGitRepo** (r) - path to the local Checkstyle repository (required in diff mode); **baseBranch** (b) - name of the base branch in local Checkstyle repository (optional, if absent, then the tool will use only patchBranch in case the tool @@ -42,7 +42,7 @@ will finish the execution with the error. You must specify 'patchBranch' and 'patchConfig' if the mode is 'single', and 'baseBranch', 'baseConfig', 'patchBranch', and 'patchConfig' if the mode is 'diff'); -**patchBranch** (p) - name of the branch with your changes (required); +**patchBranch** (p) - name of the branch with your changes (required in diff mode); **baseConfig** (bc) - path to the base checkstyle configuration file. It will be applied to base branch (required if patchConfig is specified); @@ -65,6 +65,10 @@ This option is useful for Windows users where they are restricted to maximum dir to maven during the Checkstyle regression run. For example, if you want to skip site generation, you would add `--extraMvnRegressionOptions "-Dmaven.site.skip=true"` to `diff.groovy` execution. +**allowExcludes** (g) - this option tells `diff.groovy` to allow paths and files defined in the file specified for +the `--listOfProjects (-l)` argument to be excluded from report generation (optional, default is false). This option is + used for files that are not compilable or that Checkstyle cannot parse. + ## Outputs When the script finishes its work the following directory structure will be created diff --git a/checkstyle-tester/diff-groovy-regression-config.xml b/checkstyle-tester/diff-groovy-regression-config.xml new file mode 100644 index 000000000..8a882c32d --- /dev/null +++ b/checkstyle-tester/diff-groovy-regression-config.xml @@ -0,0 +1,638 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/checkstyle-tester/diff.groovy b/checkstyle-tester/diff.groovy index 62fe71fe6..dd53357a9 100644 --- a/checkstyle-tester/diff.groovy +++ b/checkstyle-tester/diff.groovy @@ -12,7 +12,7 @@ static void main(String[] args) { def configFilesList = [cfg.config, cfg.baseConfig, cfg.patchConfig, cfg.listOfProjects] copyConfigFilesAndUpdatePaths(configFilesList) - if (hasUnstagedChanges(cfg.localGitRepo)) { + if (cfg.localGitRepo && hasUnstagedChanges(cfg.localGitRepo)) { def exMsg = "Error: git repository ${cfg.localGitRepo.path} has unstaged changes!" throw new IllegalStateException(exMsg) } @@ -27,15 +27,18 @@ static void main(String[] args) { def checkstyleBaseReportInfo = null if (cfg.isDiffMode()) { - checkstyleBaseReportInfo = generateCheckstyleReport(cfg.checkstyleToolBaseConfig) + checkstyleBaseReportInfo = launchCheckstyleReport(cfg.checkstyleToolBaseConfig) } - def checkstylePatchReportInfo = generateCheckstyleReport(cfg.checkstyleToolPatchConfig) - deleteDir(cfg.reportsDir) - moveDir(cfg.tmpReportsDir, cfg.reportsDir) + def checkstylePatchReportInfo = launchCheckstyleReport(cfg.checkstyleToolPatchConfig) - generateDiffReport(cfg.diffToolConfig) - generateSummaryIndexHtml(cfg.diffDir, checkstyleBaseReportInfo, checkstylePatchReportInfo, configFilesList) + if (checkstylePatchReportInfo) { + deleteDir(cfg.reportsDir) + moveDir(cfg.tmpReportsDir, cfg.reportsDir) + + generateDiffReport(cfg.diffToolConfig) + generateSummaryIndexHtml(cfg.diffDir, checkstyleBaseReportInfo, checkstylePatchReportInfo, configFilesList) + } } else { throw new IllegalArgumentException('Error: invalid command line arguments!') @@ -60,6 +63,8 @@ def getCliOptions(args) { 'Path to the patch checkstyle config file (required if baseConfig is specified)') c(longOpt: 'config', args: 1, required: false, argName: 'path', 'Path to the checkstyle ' \ + 'config file (required if baseConfig and patchConfig are not secified)') + g(longOpt: 'allowExcludes', required: false, 'Whether to allow excludes specified in the list of ' \ + + 'projects (optional, default is false)') l(longOpt: 'listOfProjects', args: 1, required: true, argName: 'path', 'Path to file which contains projects to test on (required)') s(longOpt: 'shortFilePaths', required: false, 'Whether to save report file paths' \ @@ -78,10 +83,11 @@ def areValidCliOptions(cliOptions) { def patchConfig = cliOptions.patchConfig def config = cliOptions.config def toolMode = cliOptions.mode - def localGitRepo = new File(cliOptions.localGitRepo) def patchBranch = cliOptions.patchBranch def baseBranch = cliOptions.baseBranch def extraMvnRegressionOptions = cliOptions.extraMvnRegressionOptions + def listOfProjectsFile = new File(cliOptions.listOfProjects) + def localGitRepo = cliOptions.localGitRepo if (toolMode && !('diff'.equals(toolMode) || 'single'.equals(toolMode))) { err.println "Error: Invalid mode: \'$toolMode\'. The mode should be \'single\' or \'diff\'!" @@ -90,18 +96,23 @@ def areValidCliOptions(cliOptions) { else if (!isValidCheckstyleConfigsCombination(config, baseConfig, patchConfig, toolMode)) { valid = false } - else if (!isValidGitRepo(localGitRepo)) { + else if (localGitRepo && !isValidGitRepo(new File(localGitRepo))) { err.println "Error: $localGitRepo is not a valid git repository!" valid = false } - else if (!isExistingGitBranch(localGitRepo, patchBranch)) { + else if (localGitRepo && !isExistingGitBranch(new File(localGitRepo), patchBranch)) { err.println "Error: $patchBranch is not an exiting git branch!" valid = false } - else if (baseBranch && !isExistingGitBranch(localGitRepo, baseBranch)) { + else if (baseBranch && + !isExistingGitBranch(new File(localGitRepo), baseBranch)) { err.println "Error: $baseBranch is not an existing git branch!" valid = false } + else if (!listOfProjectsFile.exists()) { + err.println "Error: file ${listOfProjectsFile.name} does not exist!" + valid = false + } return valid } @@ -192,42 +203,108 @@ def getCheckstyleVersionFromPomXml(pathToPomXml, xmlTagName) { return true } } - if (checkstyleVersion == null) { - throw new GroovyRuntimeException("Error: cannot get Checkstyle version from $pathToPomXml!") - } return checkstyleVersion } -def generateCheckstyleReport(cfg) { - println "Installing Checkstyle artifact ($cfg.branch) into local Maven repository ..." - executeCmd("git checkout $cfg.branch", cfg.localGitRepo) - executeCmd("git log -1 --pretty=MSG:%s%nSHA-1:%H", cfg.localGitRepo) - - def checkstyleVersion = getCheckstyleVersionFromPomXml("$cfg.localGitRepo/pom.xml", 'version') +def launchCheckstyleReport(cfg) { + CheckstyleReportInfo reportInfo; + def isRegressionTesting = cfg.branch && cfg.localGitRepo - executeCmd("mvn -e --batch-mode -Pno-validations clean install", cfg.localGitRepo) + // If "no exception" testing, these may not be defined in repos other than checkstyle + if (isRegressionTesting) { + println "Installing Checkstyle artifact ($cfg.branch) into local Maven repository ..." + executeCmd("git checkout $cfg.branch", cfg.localGitRepo) + executeCmd("git log -1 --pretty=MSG:%s%nSHA-1:%H", cfg.localGitRepo) + executeCmd("mvn -e --batch-mode -Pno-validations clean install", cfg.localGitRepo) + } - command = """groovy launch.groovy --listOfProjects $cfg.listOfProjects - --config $cfg.checkstyleCfg --ignoreExceptions --ignoreExcludes - --checkstyleVersion $checkstyleVersion""" + cfg.checkstyleVersion = + getCheckstyleVersionFromPomXml("$cfg.localGitRepo/pom.xml", 'version') - if (cfg.extraMvnRegressionOptions == true) { - command.concat("--extraMvnOptions " + cfg.extraMvnRegressionOptions) - } - executeCmd(command) + generateCheckstyleReport(cfg) println "Moving Checkstyle report into $cfg.destDir ..." moveDir("reports", cfg.destDir) - return new CheckstyleReportInfo( - cfg.branch, - getLastCommitSha(cfg.localGitRepo, cfg.branch), - getLastCommitMsg(cfg.localGitRepo, cfg.branch), - getLastCommitTime(cfg.localGitRepo, cfg.branch) - ) + if (isRegressionTesting) { + reportInfo = new CheckstyleReportInfo( + cfg.branch, + getLastCheckstyleCommitSha(cfg.localGitRepo, cfg.branch), + getLastCommitMsg(cfg.localGitRepo, cfg.branch), + getLastCommitTime(cfg.localGitRepo, cfg.branch) + ) + } + return reportInfo +} + +def generateCheckstyleReport(cfg) { + println 'Testing Checkstyle started' + + def targetDir = 'target' + def srcDir = getOsSpecificPath("src", "main", "java") + def reposDir = 'repositories' + def reportsDir = 'reports' + createWorkDirsIfNotExist(srcDir, reposDir, reportsDir) + + final REPO_NAME_PARAM_NO = 0 + final REPO_TYPE_PARAM_NO = 1 + final REPO_URL_PARAM_NO = 2 + final REPO_COMMIT_ID_PARAM_NO = 3 + final REPO_EXCLUDES_PARAM_NO = 4 + final FULL_PARAM_LIST_SIZE = 5 + + def checkstyleConfig = cfg.checkstyleCfg + def checkstyleVersion = cfg.checkstyleVersion + def failsOnError = cfg.failsOnError + def allowExcludes = cfg.allowExcludes + def listOfProjectsFile = new File(cfg.listOfProjects) + def projects = listOfProjectsFile.readLines() + def extraMvnRegressionOptions = cfg.extraMvnRegressionOptions + + projects.each { + project -> + if (!project.startsWith('#') && !project.isEmpty()) { + def params = project.split('\\|', -1) + if (params.length < FULL_PARAM_LIST_SIZE) { + throw new InvalidPropertiesFormatException("Error: line '$project' " + + "in file '$listOfProjectsFile.name' should have $FULL_PARAM_LIST_SIZE " + + "pipe-delimited sections!") + } + + def repoName = params[REPO_NAME_PARAM_NO] + def repoType = params[REPO_TYPE_PARAM_NO] + def repoUrl = params[REPO_URL_PARAM_NO] + def commitId = params[REPO_COMMIT_ID_PARAM_NO] + + def excludes = "" + if (allowExcludes) { + excludes = params[REPO_EXCLUDES_PARAM_NO] + } + + deleteDir(srcDir) + if (repoType == 'local') { + copyDir(repoUrl, getOsSpecificPath("$srcDir", "$repoName")) + } else { + cloneRepository(repoName, repoType, repoUrl, commitId, reposDir) + copyDir(getOsSpecificPath("$reposDir", "$repoName"), getOsSpecificPath("$srcDir", "$repoName")) + } + runMavenExecution(srcDir, excludes, checkstyleConfig, failsOnError, + checkstyleVersion, extraMvnRegressionOptions) + def repoPath = repoUrl + if (repoType != 'local') { + repoPath = new File(getOsSpecificPath("$reposDir", "$repoName")).absolutePath + } + postProcessCheckstyleReport(targetDir, repoName, repoPath) + deleteDir(getOsSpecificPath("$srcDir", "$repoName")) + moveDir(targetDir, getOsSpecificPath("$reportsDir", "$repoName")) + } + } + + // restore empty_file to make src directory tracked by git + new File(getOsSpecificPath("$srcDir", "empty_file")).createNewFile() } -def getLastCommitSha(gitRepo, branch) { +def getLastCheckstyleCommitSha(gitRepo, branch) { executeCmd("git checkout $branch", gitRepo) return 'git rev-parse HEAD'.execute(null, gitRepo).text.trim() } @@ -242,6 +319,78 @@ def getLastCommitTime(gitRepo, branch) { return 'git log -1 --format=%cd'.execute(null, gitRepo).text.trim() } +def getCommitSha(commitId, repoType, srcDestinationDir) { + def cmd = '' + switch (repoType) { + case 'git': + cmd = "git rev-parse $commitId" + break + case 'hg': + cmd = "hg identify --id $commitId" + break + default: + throw new IllegalArgumentException("Error! Unknown $repoType repository.") + } + def sha = cmd.execute(null, new File("$srcDestinationDir")).text + // cmd output contains new line character which should be removed + return sha.replace('\n', '') +} + +def getCloneCmd(repoType, repoUrl, srcDestinationDir) { + def cloneCmd = '' + switch (repoType) { + case 'git': + cloneCmd = "git clone $repoUrl $srcDestinationDir" + break + case 'hg': + cloneCmd = "hg clone $repoUrl $srcDestinationDir" + break + default: + throw new IllegalArgumentException("Error! Unknown $repoType repository.") + } +} + +def cloneRepository(repoName, repoType, repoUrl, commitId, srcDir) { + def srcDestinationDir = getOsSpecificPath("$srcDir", "$repoName") + if (!Files.exists(Paths.get(srcDestinationDir))) { + def cloneCmd = getCloneCmd(repoType, repoUrl, srcDestinationDir) + println "Cloning $repoType repository '$repoName' to $srcDestinationDir folder ..." + executeCmdWithRetry(cloneCmd) + println "Cloning $repoType repository '$repoName' - completed\n" + } + + if (commitId && commitId != '') { + def lastCommitSha = getLastProjectCommitSha(repoType, srcDestinationDir) + def commitIdSha = getCommitSha(commitId, repoType, srcDestinationDir) + if (lastCommitSha != commitIdSha) { + def resetCmd = getResetCmd(repoType, commitId) + println "Resetting $repoType sources to commit '$commitId'" + executeCmd(resetCmd, new File("$srcDestinationDir")) + } + } + println "$repoName is synchronized" +} + +def executeCmdWithRetry(cmd, dir = new File("").getAbsoluteFile(), retry = 5) { + def osSpecificCmd = getOsSpecificCmd(cmd) + def left = retry + while (true) { + def proc = osSpecificCmd.execute(null, dir) + proc.consumeProcessOutput(System.out, System.err) + proc.waitFor() + left-- + if (proc.exitValue() != 0) { + if (left <= 0) { + throw new GroovyRuntimeException("Error: ${proc.err.text}!") + } else { + Thread.sleep(15000) + } + } else { + break + } + } +} + def generateDiffReport(cfg) { def diffToolDir = Paths.get("").toAbsolutePath() .parent @@ -376,6 +525,21 @@ def getFilenameWithoutExtension(filename) { return filenameWithoutExtension } +def createWorkDirsIfNotExist(srcDirPath, repoDirPath, reportsDirPath) { + def srcDir = new File(srcDirPath) + if (!srcDir.exists()) { + srcDir.mkdirs() + } + def repoDir = new File(repoDirPath) + if (!repoDir.exists()) { + repoDir.mkdir() + } + def reportsDir = new File(reportsDirPath) + if (!reportsDir.exists()) { + reportsDir.mkdir() + } +} + def printReportInfoSection(summaryIndexHtml, checkstyleBaseReportInfo, checkstylePatchReportInfo, projectsStatistic) { def date = new Date(); summaryIndexHtml << ('
') @@ -452,6 +616,42 @@ def getProjectsStatistic(diffDir) { return projectsStatistic } +def runMavenExecution(srcDir, excludes, checkstyleConfig, failsOnError, + checkstyleVersion, extraMvnRegressionOptions) { + println "Running 'mvn clean' on $srcDir ..." + def mvnClean = "mvn --batch-mode clean" + executeCmd(mvnClean) + println "Running Checkstyle on $srcDir ... with excludes {$excludes}" + def mvnSite = "mvn -e --batch-mode site -Dcheckstyle.config.location=$checkstyleConfig " + + "-Dcheckstyle.excludes=$excludes" + if (checkstyleVersion) { + mvnSite = mvnSite + " -Dcheckstyle.version=$checkstyleVersion" + } + if (extraMvnRegressionOptions) { + if (!extraMvnRegressionOptions.startsWith("-")){ + extraMvnRegressionOptions = "-" + extraMvnRegressionOptions + } + mvnSite = mvnSite + " " + extraMvnRegressionOptions + } + println(mvnSite) + executeCmd(mvnSite) + println "Running Checkstyle on $srcDir - finished" +} + +def postProcessCheckstyleReport(targetDir, repoName, repoPath) { + new AntBuilder().replace( + file: getOsSpecificPath("$targetDir", "checkstyle-result.xml"), + token: new File(getOsSpecificPath("src", "main", "java", "$repoName")).absolutePath, + value: getOsSpecificPath("$repoPath") + ) +} + +def copyDir(source, destination) { + new AntBuilder().copy(todir: destination) { + fileset(dir: source) + } +} + def moveDir(source, destination) { new AntBuilder().move(todir: destination) { fileset(dir: source) @@ -463,6 +663,7 @@ def deleteDir(dir) { } def executeCmd(cmd, dir = new File("").absoluteFile) { + println "Running command: ${cmd}" def osSpecificCmd = getOsSpecificCmd(cmd) def proc = osSpecificCmd.execute(null, dir) proc.consumeProcessOutput(System.out, System.err) @@ -483,6 +684,47 @@ def getOsSpecificCmd(cmd) { return osSpecificCmd } +def getOsSpecificPath(String... name) { + def slash = isWindows() ? "\\" : "/" + def path = name.join(slash) + return path +} + +def isWindows() { + return System.properties['os.name'].toLowerCase().contains('windows') +} + +def getResetCmd(repoType, commitId) { + def resetCmd = '' + switch (repoType) { + case 'git': + resetCmd = "git reset --hard $commitId" + break + case 'hg': + resetCmd = "hg up $commitId" + break + default: + throw new IllegalArgumentException("Error! Unknown $repoType repository.") + } +} + +def getLastProjectCommitSha(repoType, srcDestinationDir) { + def cmd = '' + switch (repoType) { + case 'git': + cmd = "git rev-parse HEAD" + break + case 'hg': + cmd = "hg id -i" + break + default: + throw new IllegalArgumentException("Error! Unknown $repoType repository.") + } + def sha = cmd.execute(null, new File("$srcDestinationDir")).text + // cmd output contains new line character which should be removed + return sha.replace('\n', '') +} + class Config { def localGitRepo def shortFilePaths @@ -505,12 +747,23 @@ class Config { def diffDir def extraMvnRegressionOptions + def checkstyleVersion + def sevntuVersion + def failsOnError + def allowExcludes + Config(cliOptions) { - localGitRepo = new File(cliOptions.localGitRepo) + if(cliOptions.localGitRepo) { + localGitRepo = new File(cliOptions.localGitRepo) + } + shortFilePaths = cliOptions.shortFilePaths listOfProjects = cliOptions.listOfProjects extraMvnRegressionOptions = cliOptions.extraMvnRegressionOptions + checkstyleVersion = cliOptions.checkstyleVersion + allowExcludes = cliOptions.allowExcludes + mode = cliOptions.mode if (!mode) { mode = 'diff' @@ -557,6 +810,7 @@ class Config { listOfProjects: listOfProjects, destDir: tmpMasterReportsDir, extraMvnRegressionOptions: extraMvnRegressionOptions, + allowExcludes:allowExcludes, ] } @@ -568,6 +822,7 @@ class Config { listOfProjects: listOfProjects, destDir: tmpPatchReportsDir, extraMvnRegressionOptions: extraMvnRegressionOptions, + allowExcludes: allowExcludes, ] } @@ -580,6 +835,7 @@ class Config { patchConfig: patchConfig, shortFilePaths: shortFilePaths, mode: mode, + allowExcludes: allowExcludes, ] } } diff --git a/checkstyle-tester/projects-to-test-on.properties b/checkstyle-tester/projects-to-test-on.properties index f40b15bdc..a007834ec 100644 --- a/checkstyle-tester/projects-to-test-on.properties +++ b/checkstyle-tester/projects-to-test-on.properties @@ -4,7 +4,7 @@ # Few projects that delivers set of unusual Java constructions that shall be correctly handled by AST visitor # 'InputAllEscapedUnicodeCharacters' must be skipped because it is too big and slows down JXR -#checkstyle|git|https://github.com/checkstyle/checkstyle.git|master|**/.ci-temp/**/*,**/resources-noncompilable/**/asttreestringprinter/**/*,**/resources-noncompilable/**/filefilters/**/*,**/resources-noncompilable/**/main/**/*,**/resources-noncompilable/**/suppressionsstringprinter/**/*,**/resources-noncompilable/**/gui/**/*,**/resources-noncompilable/**/javadocpropertiesgenerator/**/*,src/test/resources-noncompilable/com/puppycrawl/tools/checkstyle/javaparser/InputJavaParser.java,**/InputAllEscapedUnicodeCharacters.java,**/resources-noncompilable/**/javaparser/InputJavaParser.java,**/resources-noncompilable/**/checks/imports/unusedimports/InputUnusedImportsSingleWordPackage.java +checkstyle|git|https://github.com/checkstyle/checkstyle.git|master|**/.ci-temp/**/*,**/resources-noncompilable/**/asttreestringprinter/**/*,**/resources-noncompilable/**/filefilters/**/*,**/resources-noncompilable/**/main/**/*,**/resources-noncompilable/**/suppressionsstringprinter/**/*,**/resources-noncompilable/**/gui/**/*,**/resources-noncompilable/**/javadocpropertiesgenerator/**/*,src/test/resources-noncompilable/com/puppycrawl/tools/checkstyle/javaparser/InputJavaParser.java,**/InputAllEscapedUnicodeCharacters.java,**/resources-noncompilable/**/javaparser/InputJavaParser.java,**/resources-noncompilable/**/checks/imports/unusedimports/InputUnusedImportsSingleWordPackage.java #sevntu-checkstyle|git|https://github.com/sevntu-checkstyle/sevntu.checkstyle|master|| #checkstyle-sonar|git|https://github.com/checkstyle/sonar-checkstyle|master|| @@ -12,7 +12,7 @@ #openjdk8|hg|http://hg.openjdk.java.net/jdk8/jdk8/jdk/|default| #All details at checkstyle/checkstyle#3033: ModalDialogActivationTest till JDK-8166015 ; 'jxc/8073519/**' not compilable by design ; ', jhsdb/**' - checkstyle do not support unicode identifiers #openjdk9|hg|http://hg.openjdk.java.net/jdk9/jdk9/jdk/|default|**/test/java/awt/Focus/ModalDialogActivationTest/ModalDialogActivationTest.java,**/test/javax/xml/bind/jxc/8073519/**,**/test/sun/tools/jhsdb/** -guava|git|https://github.com/google/guava|v28.2|| +#guava|git|https://github.com/google/guava|v28.2|| #spotbugs|git|https://github.com/spotbugs/spotbugs|3.1.2|| #pmd|git|https://github.com/pmd/pmd|pmd_releases/6.21.0|**/pmd/pmd-java/src/test/**/*,**/pmd/cpd/files/*