@@ -6,6 +6,7 @@ import com.netflix.nebula.lint.rule.GradleViolation
66import org.codenarc.rule.Rule
77import org.codenarc.rule.Violation
88import org.gradle.api.DefaultTask
9+ import org.gradle.api.Project
910import org.gradle.api.tasks.TaskAction
1011import org.gradle.logging.StyledTextOutput
1112import org.gradle.logging.StyledTextOutputFactory
@@ -18,102 +19,97 @@ class GradleLintCorrectionTask extends DefaultTask {
1819 null // see http://gradle.1045684.n5.nabble.com/injecting-dependencies-into-task-instances-td5712637.html
1920 }
2021
21- /**
22- * Clean up any ugly artifacts we may have created through the auto-fix process
23- * (e.g. empty extension object closures that have had all their property definitions removed)
24- */
25- void postProcess () {
26- def ruleSet = RuleSetFactory . configureRuleSet([new EmptyClosureRule ()])
22+ void performCorrections (Project p , CorrectableStringSourceAnalyzer analyzer ) {
23+ p. buildFile. text = analyzer. corrected // perform initial correction
2724
28- def analyzer = new CorrectableStringSourceAnalyzer (project. buildFile. text)
29- analyzer. analyze(ruleSet)
25+ // Clean up any ugly artifacts we may have created through the auto-fix process
26+ // (e.g. empty extension object closures that have had all their property definitions removed)
27+ def ruleSet = RuleSetFactory . configureRuleSet([new EmptyClosureRule ()])
28+ def postProcessor = new CorrectableStringSourceAnalyzer (p. buildFile. text)
29+ postProcessor. analyze(ruleSet)
3030
31- project. buildFile. newWriter(). withWriter { w ->
32- w << analyzer. corrected
33- }
31+ p. buildFile. text = postProcessor. corrected
3432 }
3533
3634 @TaskAction
3735 void lintCorrections () {
38- if (! project. buildFile. exists()) {
39- return
40- }
41-
42- def registry = new LintRuleRegistry (project)
43- def ruleSet = RuleSetFactory . configureRuleSet(project. extensions
44- .getByType(GradleLintExtension )
45- .rules
46- .collect { registry. buildRules(it) }
47- .flatten() as List<Rule > )
48-
4936 // look at org.gradle.logging.internal.DefaultColorMap
5037 def textOutput = textOutputFactory. create(' lint' )
38+ def registry = new LintRuleRegistry ()
5139
52- def analyzer = new CorrectableStringSourceAnalyzer (project. buildFile. text)
53- def results = analyzer. analyze(ruleSet)
40+ def violationsByProject = [:]
5441
55- if (results. violations. isEmpty()) {
56- textOutput. style(StyledTextOutput.Style.Identifier ). println (" Passed lint check with 0 violations; no corrections necessary" )
57- return
58- }
42+ ([project] + project. subprojects). each { p ->
43+ if (p. buildFile. exists()) {
44+ def ruleSet = RuleSetFactory . configureRuleSet(p. extensions
45+ .getByType(GradleLintExtension )
46+ .rules
47+ .collect { registry. buildRules(it, p) }
48+ .flatten() as List<Rule > )
5949
60- // perform initial correction
61- project. buildFile. newWriter(). withWriter { w ->
62- w << analyzer. corrected
63- }
64- postProcess()
50+ def analyzer = new CorrectableStringSourceAnalyzer (p. buildFile. text)
51+ def results = analyzer. analyze(ruleSet)
6552
66- printReport(results. violations, textOutput)
67- }
53+ performCorrections(p, analyzer)
54+ violationsByProject[p] = results. violations
55+ }
56+ }
6857
69- private List printReport ( List< Violation > violations , textOutput ) {
58+ def allViolations = violationsByProject . values() . flatten()
7059 def correctedViolations = 0 , uncorrectedViolations = 0
71- def buildFilePath = relPath(project. rootDir, project. buildFile). path
72-
73- violations. eachWithIndex { v , i ->
74- def severity = v. rule. priority <= 3 ? ' warning' : ' error'
7560
76- if (v instanceof GradleViolation && v. isFixable()) {
77- textOutput. withStyle(StyledTextOutput.Style.Identifier ). text(' fixed' . padRight(10 ))
78- } else {
79- textOutput. withStyle(StyledTextOutput.Style.Failure ). text(severity. padRight(10 ))
80- }
81-
82- textOutput. text(v. rule. ruleId. padRight(35 ))
83- textOutput. withStyle(StyledTextOutput.Style.Description ). println (v. message)
84-
85- textOutput. withStyle(StyledTextOutput.Style.UserInput ). println (buildFilePath + ' :' + v. lineNumber)
86- textOutput. println (" $v. sourceLine " )
87-
88- if (v instanceof GradleViolation && v. isFixable()) {
89- if (v. replacement) {
90- textOutput. withStyle(StyledTextOutput.Style.UserInput ). println (' replaced with:' )
91- textOutput. println (v. replacement)
92- correctedViolations++
93- } else if (v. deleteLine) {
94- textOutput. withStyle(StyledTextOutput.Style.UserInput ). println (" deleted line $v. deleteLine " )
95- correctedViolations++
96- } else if (v. addition) {
97- textOutput. withStyle(StyledTextOutput.Style.UserInput ). println (" adding:" )
98- textOutput. print (v. addition)
99- correctedViolations++
61+ if (allViolations. isEmpty()) {
62+ textOutput. style(StyledTextOutput.Style.Identifier ). println (" Passed lint check with 0 violations; no corrections necessary" )
63+ } else {
64+ textOutput. withStyle(StyledTextOutput.Style.UserInput ). text(' \n This project contains lint violations. ' )
65+ textOutput. println (' A complete listing of my attempt to fix them follows. Please review and commit the changes.\n ' )
66+
67+ violationsByProject. entrySet(). each {
68+ def buildFilePath = it. key. rootDir. toURI(). relativize(it. key. buildFile. toURI()). toString()
69+ def violations = it. value
70+
71+ violations. each { Violation v ->
72+ def severity = v. rule. priority <= 3 ? ' warning' : ' error'
73+
74+ if (v instanceof GradleViolation && v. isFixable()) {
75+ textOutput. withStyle(StyledTextOutput.Style.Identifier ). text(' fixed' . padRight(10 ))
76+ } else {
77+ textOutput. withStyle(StyledTextOutput.Style.Failure ). text(severity. padRight(10 ))
78+ }
79+
80+ textOutput. text(v. rule. ruleId. padRight(35 ))
81+ textOutput. withStyle(StyledTextOutput.Style.Description ). println (v. message)
82+
83+ textOutput. withStyle(StyledTextOutput.Style.UserInput ). println (buildFilePath + ' :' + v. lineNumber)
84+ textOutput. println (" $v. sourceLine " )
85+
86+ if (v instanceof GradleViolation && v. isFixable()) {
87+ if (v. replacement) {
88+ textOutput. withStyle(StyledTextOutput.Style.UserInput ). println (' replaced with:' )
89+ textOutput. println (v. replacement)
90+ correctedViolations++
91+ } else if (v. deleteLine) {
92+ textOutput. withStyle(StyledTextOutput.Style.UserInput ). println (" deleted line $v. deleteLine " )
93+ correctedViolations++
94+ } else if (v. addition) {
95+ textOutput. withStyle(StyledTextOutput.Style.UserInput ). println (" adding:" )
96+ textOutput. print (v. addition)
97+ correctedViolations++
98+ }
99+ } else {
100+ textOutput. withStyle(StyledTextOutput.Style.Error ). println (' \u 2716 no auto-correct available' )
101+ uncorrectedViolations++
102+ }
103+
104+ textOutput. println () // extra space between violations
100105 }
101- } else {
102- textOutput. withStyle(StyledTextOutput.Style.Error ). println (' \u 2716 no auto-correct available' )
103- uncorrectedViolations++
104106 }
105107
106- textOutput. println () // extra space between violations
107- }
108-
109- if (correctedViolations > 0 )
110- textOutput. style(StyledTextOutput.Style.Identifier ). println (" Corrected $correctedViolations lint problems" )
108+ if (correctedViolations > 0 )
109+ textOutput. style(StyledTextOutput.Style.Identifier ). println (" Corrected $correctedViolations lint problems\n " )
111110
112- if (uncorrectedViolations > 0 )
113- textOutput. style(StyledTextOutput.Style.Error ). println (" Corrected $correctedViolations lint problems" )
114- }
115-
116- private static File relPath (File root , File f ) {
117- new File (root. toURI(). relativize(f. toURI()). toString())
111+ if (uncorrectedViolations > 0 )
112+ textOutput. style(StyledTextOutput.Style.Error ). println (" Corrected $correctedViolations lint problems\n " )
113+ }
118114 }
119115}
0 commit comments