Skip to content

Commit 1d5eb4b

Browse files
Support config.file from yml (#8)
* Fix #4 * Abort execution on bad config * Supports old and new formats and fallback to default config if none is specified: ```yml config: rules.xml ``` ```yml config: file: rules.xml ```
1 parent 2f86bfb commit 1d5eb4b

File tree

6 files changed

+994
-45
lines changed

6 files changed

+994
-45
lines changed

Diff for: pmd.groovy

+79-40
Original file line numberDiff line numberDiff line change
@@ -3,65 +3,104 @@
33
import groovy.json.JsonSlurper
44
import groovy.util.FileNameFinder
55

6-
def appContext = setupContext(args)
7-
def parsedConfig = new JsonSlurper().parse(new File(appContext.configFile), "UTF-8")
86

9-
def includePaths = parsedConfig.include_paths?.join(" ")
10-
def codeFolder = new File(appContext.codeFolder)
7+
class Config {
8+
def args
9+
def appContext
10+
def parsedConfig
11+
def filesToAnalyze
12+
def filesList
13+
14+
Config(args) {
15+
this.args = args
16+
this.appContext = setupContext()
17+
this.parsedConfig = new JsonSlurper().parse(new File(appContext.configFile), "UTF-8")
18+
this.filesToAnalyze = filesToAnalyze()
19+
this.filesList = createTempFile()
20+
filesList << filesToAnalyze
21+
}
22+
23+
def noFiles() {
24+
filesToAnalyze.isEmpty()
25+
}
26+
27+
def ruleSet() {
28+
if(parsedConfig.config) {
29+
def configFile = parsedConfig.config instanceof String ? parsedConfig.config : parsedConfig.config.file
30+
31+
if(fileExists(configFile)) {
32+
return configFile
33+
} else {
34+
System.err.println "Config file ${configFile} not found"
35+
System.exit(1)
36+
}
37+
}
38+
39+
"/usr/src/app/ruleset.xml"
40+
}
41+
42+
def filesListPath() {
43+
filesList.absolutePath
44+
}
1145

12-
def filesToAnalyse = new FileNameFinder().getFileNames(appContext.codeFolder, includePaths)
46+
private def fileExists(file) {
47+
new File(file).exists()
48+
}
1349

14-
File analysisFilesTmp = new File("/tmp/files")
15-
analysisFilesTmp.createNewFile()
16-
analysisFilesTmp.deleteOnExit()
50+
private def filesToAnalyze() {
51+
def includePaths = parsedConfig.include_paths?.join(" ")
52+
def codeFolder = new File(appContext.codeFolder)
1753

18-
def i = filesToAnalyse.iterator()
19-
while(i.hasNext()) {
20-
string = i.next()
21-
if( !string.endsWith(".java") ) {
54+
def files = new FileNameFinder().getFileNames(appContext.codeFolder, includePaths)
55+
56+
def i = files.iterator()
57+
while(i.hasNext()) {
58+
def name = i.next()
59+
if(!name.endsWith(".java")) {
2260
i.remove()
61+
}
2362
}
24-
}
2563

26-
filesToAnalyse = filesToAnalyse.toString()
27-
filesToAnalyse = filesToAnalyse.substring(1, filesToAnalyse.length()-1).replaceAll("\\s+","")
28-
if (filesToAnalyse.isEmpty()) {
29-
System.exit(0)
30-
}
64+
def fileNames = files.toString()
65+
fileNames.substring(1, fileNames.length()-1).replaceAll("\\s+","")
66+
}
3167

32-
analysisFilesTmp << filesToAnalyse
68+
private def createTempFile() {
69+
File tmp = File.createTempFile("files", ".txt")
70+
tmp.deleteOnExit()
71+
tmp
72+
}
3373

34-
def ruleSetPath
35-
if ( parsedConfig.config && (new File(parsedConfig.config).exists()) ) {
36-
ruleSetPath = parsedConfig.config
37-
} else {
38-
ruleSetPath = "/usr/src/app/ruleset.xml"
74+
private def setupContext() {
75+
def cli = new CliBuilder(usage:"${this.class.name}")
76+
cli._(longOpt: "configFile", required: true, args: 1, "Path to config.json file")
77+
cli._(longOpt: "codeFolder", required: true, args: 1, "Path to code folder")
78+
cli.parse(args)
79+
}
3980
}
4081

41-
def pmdCommand = "/usr/src/app/lib/pmd/bin/run.sh pmd -filelist /tmp/files -f codeclimate -R ${ruleSetPath} -failOnViolation false"
82+
/* ********** MAIN ********** */
4283

43-
ProcessBuilder builder = new ProcessBuilder( pmdCommand.split(' ') )
84+
def config = new Config(args)
85+
if (config.noFiles()) {
86+
System.exit(0)
87+
}
4488

45-
Process process = builder.start()
89+
def command = "/usr/src/app/lib/pmd/bin/run.sh pmd -filelist ${config.filesListPath()} -f codeclimate -R ${config.ruleSet()} -failOnViolation false"
4690

47-
InputStream stdout = process.getInputStream ()
48-
BufferedReader reader = new BufferedReader (new InputStreamReader(stdout))
91+
ProcessBuilder builder = new ProcessBuilder(command.split(' '))
92+
Process process = builder.start()
4993

50-
while ((line = reader.readLine ()) != null) {
51-
System.out.println ( line )
94+
InputStream stdout = process.getInputStream()
95+
BufferedReader reader = new BufferedReader(new InputStreamReader(stdout))
96+
while ((line = reader.readLine()) != null) {
97+
System.out.println(line)
5298
}
5399

54100
process.waitForProcessOutput()
55101

56-
if ( process.exitValue() != 0 ) {
57-
System.exit(-1)
102+
if (process.exitValue() != 0) {
103+
System.exit(-1)
58104
}
59105

60106
System.exit(0)
61-
62-
def setupContext(cmdArgs) {
63-
def cli = new CliBuilder(usage:"${this.class.name}")
64-
cli._(longOpt: "configFile", required: true, args: 1, "Path to config.json file")
65-
cli._(longOpt: "codeFolder", required: true, args: 1, "Path to code folder")
66-
cli.parse(cmdArgs)
67-
}

Diff for: test.groovy

+31-5
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,41 @@
33
import groovy.json.JsonSlurper
44
import groovy.util.FileNameFinder
55

6-
def sanityCheck() {
7-
def command = "/usr/src/app/pmd.groovy --codeFolder=/code/test --configFile=/code/test/config.json"
8-
6+
def execute(command) {
97
def proc = command.execute()
108
def out = new StringBuffer()
119
def err = new StringBuffer()
1210

1311
proc.waitForProcessOutput(out, err)
1412

15-
assert proc.exitValue() == 0
13+
System.err.println err
14+
System.err.println out
15+
16+
return [proc, out, err]
17+
}
18+
19+
def sanityCheck() {
20+
def (proc, out, err) = execute("/usr/src/app/pmd.groovy --codeFolder=/code/test --configFile=/code/test/config.json")
21+
1622
assert !out.toString().isEmpty()
1723
assert err.toString().isEmpty()
24+
assert proc.exitValue() == 0
25+
}
26+
27+
def checkConfigBackwardCompatibility() {
28+
def (proc, out, _err) = execute("/usr/src/app/pmd.groovy --codeFolder=/code/test --configFile=/code/test/config.new.json")
29+
def (procOld, outOld, _errOld) = execute("/usr/src/app/pmd.groovy --codeFolder=/code/test --configFile=/code/test/config.old.json")
30+
31+
assert proc.exitValue() == procOld.exitValue()
32+
assert out.toString().equals(outOld.toString())
33+
assert proc.exitValue() == 0
34+
}
35+
36+
def abortOnBadConfig() {
37+
def (proc, out, err) = execute("/usr/src/app/pmd.groovy --codeFolder=/code/test --configFile=/code/test/config.bad.json")
38+
39+
assert !err.toString().isEmpty()
40+
assert proc.exitValue() != 0
1841
}
1942

2043
def engineCheckList() {
@@ -45,6 +68,9 @@ def dockerfileCheckList() {
4568

4669
/** MAIN **/
4770

48-
sanityCheck()
4971
engineCheckList()
5072
dockerfileCheckList()
73+
74+
sanityCheck()
75+
checkConfigBackwardCompatibility()
76+
abortOnBadConfig()

Diff for: test/config.bad.json

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"enabled": true,
3+
"channel": "beta",
4+
"config": {
5+
"file": "test/invalid_file",
6+
},
7+
"include_paths": [
8+
"Main.java"
9+
]
10+
}
11+
12+

Diff for: test/config.new.json

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"enabled": true,
3+
"channel": "beta",
4+
"config": {
5+
"file": "test/rules.xml",
6+
},
7+
"include_paths": [
8+
"Main.java"
9+
]
10+
}
11+

Diff for: test/config.old.json

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"enabled": true,
3+
"channel": "beta",
4+
"config": "test/rules.xml",
5+
"include_paths": [
6+
"Main.java"
7+
]
8+
}
9+

0 commit comments

Comments
 (0)