File tree Expand file tree Collapse file tree 10 files changed +179
-18
lines changed Expand file tree Collapse file tree 10 files changed +179
-18
lines changed Original file line number Diff line number Diff line change @@ -215,6 +215,30 @@ There is a GitHub Actions action available to get linter feedback in workflows:
215
215
216
216
* [ puppet-lint-action] ( https://github.com/marketplace/actions/puppet-lint-action )
217
217
218
+ ## Integration with GitLab Code Quality
219
+
220
+ [ GitLab] ( https://gitlab.com/ ) users can use the ` --codeclimate-report-file ` configuration option to generate a report for use with the
221
+ [ Code Quality] ( https://docs.gitlab.com/ee/ci/testing/code_quality.html ) feature.
222
+
223
+ The easiest way to set this option, (and without having to modify rake tasks), is with the ` CODECLIMATE_REPORT_FILE ` environment variable.
224
+
225
+ For example, the following GitLab job sets the environment variable and
226
+ [ archives the report] ( https://docs.gitlab.com/ee/ci/yaml/artifacts_reports.html#artifactsreportscodequality ) produced.
227
+ ``` yaml
228
+ validate lint check rubocop-Ruby 2.7.2-Puppet ~> 7 :
229
+ stage : syntax
230
+ image : ruby:2.7.2
231
+ script :
232
+ - bundle exec rake validate lint check rubocop
233
+ variables :
234
+ PUPPET_GEM_VERSION : ' ~> 7'
235
+ CODECLIMATE_REPORT_FILE : ' gl-code-quality-report.json'
236
+ artifacts :
237
+ reports :
238
+ codequality : gl-code-quality-report.json
239
+ expire_in : 1 week
240
+ ` ` `
241
+
218
242
## Options
219
243
220
244
See ` puppet-lint --help` for a full list of command line options and checks.
Original file line number Diff line number Diff line change @@ -175,14 +175,16 @@ def report(problems)
175
175
176
176
next unless message [ :kind ] == :fixed || [ message [ :kind ] , :all ] . include? ( configuration . error_level )
177
177
178
- if configuration . json || configuration . sarif
178
+ if configuration . json || configuration . sarif || configuration . codeclimate_report_file
179
179
message [ 'context' ] = get_context ( message ) if configuration . with_context
180
180
json << message
181
- else
182
- format_message ( message )
183
- print_context ( message ) if configuration . with_context
184
- print_github_annotation ( message ) if configuration . github_actions
185
181
end
182
+
183
+ next if configuration . json || configuration . sarif
184
+
185
+ format_message ( message )
186
+ print_context ( message ) if configuration . with_context
187
+ print_github_annotation ( message ) if configuration . github_actions
186
188
end
187
189
$stderr. puts 'Try running `puppet parser validate <file>`' if problems . any? { |p | p [ :check ] == :syntax }
188
190
json
@@ -225,7 +227,7 @@ def run
225
227
226
228
# Public: Print any problems that were found out to stdout.
227
229
#
228
- # Returns nothing.
230
+ # Returns an array of problems. (Can be empty depending on configuration!)
229
231
def print_problems
230
232
report ( @problems )
231
233
end
Original file line number Diff line number Diff line change 1
1
require 'pathname'
2
2
require 'uri'
3
3
require 'puppet-lint/optparser'
4
+ require 'puppet-lint/report/codeclimate'
4
5
5
6
# Internal: The logic of the puppet-lint bin script, contained in a class for
6
7
# ease of testing.
@@ -104,6 +105,10 @@ def run
104
105
puts JSON . pretty_generate ( all_problems )
105
106
end
106
107
108
+ if PuppetLint . configuration . codeclimate_report_file
109
+ PuppetLint ::Report ::CodeClimateReporter . write_report_file ( all_problems , PuppetLint . configuration . codeclimate_report_file )
110
+ end
111
+
107
112
return_val
108
113
rescue PuppetLint ::NoCodeError
109
114
puts 'puppet-lint: no file specified or specified file does not exist'
Original file line number Diff line number Diff line change @@ -153,5 +153,6 @@ def defaults
153
153
self . show_ignored = false
154
154
self . ignore_paths = [ 'vendor/**/*.pp' ]
155
155
self . github_actions = ENV . key? ( 'GITHUB_ACTION' )
156
+ self . codeclimate_report_file = ENV [ 'CODECLIMATE_REPORT_FILE' ]
156
157
end
157
158
end
Original file line number Diff line number Diff line change @@ -102,6 +102,10 @@ def self.build(args = [])
102
102
PuppetLint . configuration . sarif = true
103
103
end
104
104
105
+ opts . on ( '--codeclimate-report-file FILE' , 'Save a code climate compatible report to this file' ) do |file |
106
+ PuppetLint . configuration . codeclimate_report_file = file
107
+ end
108
+
105
109
opts . on ( '--list-checks' , 'List available check names.' ) do
106
110
PuppetLint . configuration . list_checks = true
107
111
end
Original file line number Diff line number Diff line change
1
+ # frozen_string_literal: true
2
+
3
+ require 'digest'
4
+ require 'json'
5
+
6
+ class PuppetLint ::Report
7
+ class CodeClimateReporter
8
+ def self . write_report_file ( problems , report_file )
9
+ report = [ ]
10
+ problems . each do |messages |
11
+ messages . each do |message |
12
+ case message [ :kind ]
13
+ when :warning
14
+ severity = 'minor'
15
+ when :error
16
+ severity = 'major'
17
+ else
18
+ next
19
+ end
20
+
21
+ issue = {
22
+ type : :issue ,
23
+ check_name : message [ :check ] ,
24
+ description : message [ :message ] ,
25
+ categories : [ :Style ] ,
26
+ severity : severity ,
27
+ location : {
28
+ path : message [ :path ] ,
29
+ lines : {
30
+ begin : message [ :line ] ,
31
+ end : message [ :line ] ,
32
+ }
33
+ } ,
34
+ fingerprint : Digest ::MD5 . hexdigest ( Marshal . dump ( message ) )
35
+ }
36
+
37
+ if message . key? ( :description ) && message . key? ( :help_uri )
38
+ issue [ :content ] = "#{ message [ :description ] . chomp ( '.' ) } . See [this page](#{ message [ :help_uri ] } ) for more information about the `#{ message [ :check ] } ` check."
39
+ end
40
+ report << issue
41
+ end
42
+ end
43
+ File . write ( report_file , JSON . pretty_generate ( report ) )
44
+ end
45
+ end
46
+ end
Original file line number Diff line number Diff line change 4
4
require 'puppet-lint/optparser'
5
5
require 'rake'
6
6
require 'rake/tasklib'
7
+ require 'puppet-lint/report/codeclimate'
7
8
8
9
# Public: A Rake task that can be loaded and used with everything you need.
9
10
#
@@ -90,19 +91,25 @@ def define(args, &task_block)
90
91
RakeFileUtils . send ( :verbose , true ) do
91
92
linter = PuppetLint . new
92
93
matched_files = FileList [ @pattern ]
94
+ all_problems = [ ]
93
95
94
96
matched_files = matched_files . exclude ( *@ignore_paths )
95
97
96
98
matched_files . to_a . each do |puppet_file |
97
99
next unless File . file? ( puppet_file )
98
100
linter . file = puppet_file
99
101
linter . run
100
- linter . print_problems
102
+ all_problems << linter . print_problems
101
103
102
104
if PuppetLint . configuration . fix && linter . problems . none? { |e | e [ :check ] == :syntax }
103
105
IO . write ( puppet_file , linter . manifest )
104
106
end
105
107
end
108
+
109
+ if PuppetLint . configuration . codeclimate_report_file
110
+ PuppetLint ::Report ::CodeClimateReporter . write_report_file ( all_problems , PuppetLint . configuration . codeclimate_report_file )
111
+ end
112
+
106
113
abort if linter . errors? || (
107
114
linter . warnings? && PuppetLint . configuration . fail_on_warnings
108
115
)
Original file line number Diff line number Diff line change
1
+ [
2
+ {
3
+ "type" : " issue" ,
4
+ "check_name" : " autoloader_layout" ,
5
+ "description" : " test::foo not in autoload module layout" ,
6
+ "categories" : [
7
+ " Style"
8
+ ],
9
+ "severity" : " major" ,
10
+ "location" : {
11
+ "path" : " spec/fixtures/test/manifests/fail.pp" ,
12
+ "lines" : {
13
+ "begin" : 2 ,
14
+ "end" : 2
15
+ }
16
+ },
17
+ "fingerprint" : " 7694e41686e47731a83238e2ed2cd519" ,
18
+ "content" : " Test the manifest tokens for any classes or defined types that are not in an appropriately named file for the autoloader to detect and record an error of each instance found. See [this page](https://puppet.com/docs/puppet/latest/style_guide.html#separate-files) for more information about the `autoloader_layout` check."
19
+ },
20
+ {
21
+ "type" : " issue" ,
22
+ "check_name" : " parameter_order" ,
23
+ "description" : " optional parameter listed before required parameter" ,
24
+ "categories" : [
25
+ " Style"
26
+ ],
27
+ "severity" : " minor" ,
28
+ "location" : {
29
+ "path" : " spec/fixtures/test/manifests/warning.pp" ,
30
+ "lines" : {
31
+ "begin" : 2 ,
32
+ "end" : 2
33
+ }
34
+ },
35
+ "fingerprint" : " e6d2f0563638599500bd81f8106a2cea" ,
36
+ "content" : " Test the manifest tokens for any parameterised classes or defined types that take parameters and record a warning if there are any optional parameters listed before required parameters. See [this page](https://puppet.com/docs/puppet/latest/style_guide.html#display-order-of-parameters) for more information about the `parameter_order` check."
37
+ }
38
+ ]
Original file line number Diff line number Diff line change @@ -437,6 +437,30 @@ def initialize(args)
437
437
end
438
438
end
439
439
440
+ context 'when outputting code climate report' do
441
+ let ( :report_file ) do
442
+ Tempfile . new ( 'report_file.json' )
443
+ end
444
+
445
+ let ( :args ) do
446
+ [
447
+ '--codeclimate-report-file' ,
448
+ report_file . path ,
449
+ 'spec/fixtures/test/manifests/fail.pp' ,
450
+ 'spec/fixtures/test/manifests/warning.pp' ,
451
+ ]
452
+ end
453
+
454
+ after ( :each ) do
455
+ report_file . unlink
456
+ end
457
+
458
+ it 'creates a code climate report' do
459
+ expect ( bin . exitstatus ) . to eq ( 1 )
460
+ expect ( FileUtils . compare_file ( report_file . path , 'spec/fixtures/test/reports/code_climate.json' ) ) . to be_truthy
461
+ end
462
+ end
463
+
440
464
context 'when hiding ignored problems' do
441
465
let ( :args ) do
442
466
[
Original file line number Diff line number Diff line change 55
55
end
56
56
57
57
expect ( config . settings ) . to eq (
58
- 'with_filename' => false ,
59
- 'fail_on_warnings' => false ,
60
- 'error_level' => :all ,
61
- 'log_format' => '' ,
62
- 'sarif' => false ,
63
- 'with_context' => false ,
64
- 'fix' => false ,
65
- 'github_actions' => false ,
66
- 'show_ignored' => false ,
67
- 'json' => false ,
68
- 'ignore_paths' => [ 'vendor/**/*.pp' ] ,
58
+ 'with_filename' => false ,
59
+ 'fail_on_warnings' => false ,
60
+ 'codeclimate_report_file' => nil ,
61
+ 'error_level' => :all ,
62
+ 'log_format' => '' ,
63
+ 'sarif' => false ,
64
+ 'with_context' => false ,
65
+ 'fix' => false ,
66
+ 'github_actions' => false ,
67
+ 'show_ignored' => false ,
68
+ 'json' => false ,
69
+ 'ignore_paths' => [ 'vendor/**/*.pp' ] ,
69
70
)
70
71
end
71
72
78
79
expect ( config . settings [ 'github_actions' ] ) . to be ( true )
79
80
end
80
81
82
+ it 'defaults codeclimate_report_file to the CODECLIMATE_REPORT_FILE environment variable' do
83
+ override_env do
84
+ ENV [ 'CODECLIMATE_REPORT_FILE' ] = '/path/to/report.json'
85
+ config . defaults
86
+ end
87
+
88
+ expect ( config . settings [ 'codeclimate_report_file' ] ) . to eq ( '/path/to/report.json' )
89
+ end
90
+
81
91
def override_env
82
92
old_env = ENV . to_h
83
93
yield
You can’t perform that action at this time.
0 commit comments