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:
215215
216216* [ puppet-lint-action] ( https://github.com/marketplace/actions/puppet-lint-action )
217217
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+
218242## Options
219243
220244See ` 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)
175175
176176 next unless message [ :kind ] == :fixed || [ message [ :kind ] , :all ] . include? ( configuration . error_level )
177177
178- if configuration . json || configuration . sarif
178+ if configuration . json || configuration . sarif || configuration . codeclimate_report_file
179179 message [ 'context' ] = get_context ( message ) if configuration . with_context
180180 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
185181 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
186188 end
187189 $stderr. puts 'Try running `puppet parser validate <file>`' if problems . any? { |p | p [ :check ] == :syntax }
188190 json
@@ -225,7 +227,7 @@ def run
225227
226228 # Public: Print any problems that were found out to stdout.
227229 #
228- # Returns nothing.
230+ # Returns an array of problems. (Can be empty depending on configuration!)
229231 def print_problems
230232 report ( @problems )
231233 end
Original file line number Diff line number Diff line change 11require 'pathname'
22require 'uri'
33require 'puppet-lint/optparser'
4+ require 'puppet-lint/report/codeclimate'
45
56# Internal: The logic of the puppet-lint bin script, contained in a class for
67# ease of testing.
@@ -104,6 +105,10 @@ def run
104105 puts JSON . pretty_generate ( all_problems )
105106 end
106107
108+ if PuppetLint . configuration . codeclimate_report_file
109+ PuppetLint ::Report ::CodeClimateReporter . write_report_file ( all_problems , PuppetLint . configuration . codeclimate_report_file )
110+ end
111+
107112 return_val
108113 rescue PuppetLint ::NoCodeError
109114 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
153153 self . show_ignored = false
154154 self . ignore_paths = [ 'vendor/**/*.pp' ]
155155 self . github_actions = ENV . key? ( 'GITHUB_ACTION' )
156+ self . codeclimate_report_file = ENV [ 'CODECLIMATE_REPORT_FILE' ]
156157 end
157158end
Original file line number Diff line number Diff line change @@ -102,6 +102,10 @@ def self.build(args = [])
102102 PuppetLint . configuration . sarif = true
103103 end
104104
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+
105109 opts . on ( '--list-checks' , 'List available check names.' ) do
106110 PuppetLint . configuration . list_checks = true
107111 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 44require 'puppet-lint/optparser'
55require 'rake'
66require 'rake/tasklib'
7+ require 'puppet-lint/report/codeclimate'
78
89# Public: A Rake task that can be loaded and used with everything you need.
910#
@@ -90,19 +91,25 @@ def define(args, &task_block)
9091 RakeFileUtils . send ( :verbose , true ) do
9192 linter = PuppetLint . new
9293 matched_files = FileList [ @pattern ]
94+ all_problems = [ ]
9395
9496 matched_files = matched_files . exclude ( *@ignore_paths )
9597
9698 matched_files . to_a . each do |puppet_file |
9799 next unless File . file? ( puppet_file )
98100 linter . file = puppet_file
99101 linter . run
100- linter . print_problems
102+ all_problems << linter . print_problems
101103
102104 if PuppetLint . configuration . fix && linter . problems . none? { |e | e [ :check ] == :syntax }
103105 IO . write ( puppet_file , linter . manifest )
104106 end
105107 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+
106113 abort if linter . errors? || (
107114 linter . warnings? && PuppetLint . configuration . fail_on_warnings
108115 )
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)
437437 end
438438 end
439439
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+
440464 context 'when hiding ignored problems' do
441465 let ( :args ) do
442466 [
Original file line number Diff line number Diff line change 5555 end
5656
5757 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' ] ,
6970 )
7071 end
7172
7879 expect ( config . settings [ 'github_actions' ] ) . to be ( true )
7980 end
8081
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+
8191 def override_env
8292 old_env = ENV . to_h
8393 yield
You can’t perform that action at this time.
0 commit comments