puppet-check 2.2.0 → 2.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +7 -0
- data/README.md +19 -13
- data/lib/puppet-check/cli.rb +6 -4
- data/lib/puppet-check/data_parser.rb +24 -18
- data/lib/puppet-check/output_results.rb +36 -30
- data/lib/puppet-check/puppet_parser.rb +18 -16
- data/lib/puppet-check/rspec_puppet_support.rb +1 -1
- data/lib/puppet-check/ruby_parser.rb +27 -20
- data/lib/puppet-check/tasks.rb +6 -5
- data/lib/puppet_check.rb +28 -23
- data/spec/puppet-check/cli_spec.rb +1 -1
- data/spec/puppet-check/data_parser_spec.rb +60 -53
- data/spec/puppet-check/output_results_spec.rb +28 -39
- data/spec/puppet-check/puppet_parser_spec.rb +52 -42
- data/spec/puppet-check/rspec_puppet_support_spec.rb +4 -4
- data/spec/puppet-check/ruby_parser_spec.rb +52 -43
- data/spec/puppet-check/tasks_spec.rb +4 -8
- data/spec/puppet_check_spec.rb +63 -25
- data/spec/system/system_spec.rb +20 -20
- metadata +13 -64
data/lib/puppet_check.rb
CHANGED
@@ -5,33 +5,35 @@ require_relative 'puppet-check/output_results'
|
|
5
5
|
|
6
6
|
# interfaces from CLI/tasks and to individual parsers
|
7
7
|
class PuppetCheck
|
8
|
-
# initialize
|
9
|
-
@
|
10
|
-
|
11
|
-
|
8
|
+
# initialize files hash
|
9
|
+
@files = {
|
10
|
+
errors: {},
|
11
|
+
warnings: {},
|
12
|
+
clean: [],
|
13
|
+
ignored: []
|
14
|
+
}
|
15
|
+
|
16
|
+
# allow the parser methods write to the files
|
12
17
|
class << self
|
13
|
-
attr_accessor :
|
18
|
+
attr_accessor :files
|
14
19
|
end
|
15
20
|
|
16
21
|
# main runner for PuppetCheck
|
17
|
-
def run(settings, paths)
|
18
|
-
# establish settings
|
19
|
-
self.class.settings = settings
|
20
|
-
|
22
|
+
def run(settings = {}, paths = [])
|
21
23
|
# settings defaults
|
22
|
-
self.class.defaults(settings)
|
24
|
+
settings = self.class.defaults(settings)
|
23
25
|
|
24
26
|
# grab all of the files to be processed
|
25
27
|
files = self.class.parse_paths(paths)
|
26
28
|
|
27
29
|
# parse the files
|
28
|
-
execute_parsers(files, settings)
|
30
|
+
parsed_files = execute_parsers(files, settings)
|
29
31
|
|
30
32
|
# output the diagnostic results
|
31
|
-
|
33
|
+
OutputResults.run(parsed_files.clone, settings[:output_format])
|
32
34
|
|
33
35
|
# progress to regression checks if no errors in file checks
|
34
|
-
if
|
36
|
+
if parsed_files[:errors].empty? && (!settings[:fail_on_warning] || parsed_files[:warnings].empty?)
|
35
37
|
begin
|
36
38
|
require_relative 'puppet-check/regression_check'
|
37
39
|
# if octocatalog-diff is not installed then return immediately
|
@@ -68,7 +70,8 @@ class PuppetCheck
|
|
68
70
|
end
|
69
71
|
|
70
72
|
# establish default settings
|
71
|
-
def self.defaults(settings)
|
73
|
+
def self.defaults(settings = {})
|
74
|
+
private_class_method :method
|
72
75
|
# initialize fail on warning, style check, and regression check bools
|
73
76
|
settings[:fail_on_warning] ||= false
|
74
77
|
settings[:style] ||= false
|
@@ -82,12 +85,6 @@ class PuppetCheck
|
|
82
85
|
# initialize output format option
|
83
86
|
settings[:output_format] ||= 'text'
|
84
87
|
|
85
|
-
# initialize diagnostic output arrays
|
86
|
-
@settings[:error_files] = []
|
87
|
-
@settings[:warning_files] = []
|
88
|
-
@settings[:clean_files] = []
|
89
|
-
@settings[:ignored_files] = []
|
90
|
-
|
91
88
|
# initialize octocatalog-diff options
|
92
89
|
settings[:octoconfig] ||= '.octocatalog-diff.cfg.rb'
|
93
90
|
settings[:octonodes] ||= %w[localhost.localdomain]
|
@@ -95,10 +92,14 @@ class PuppetCheck
|
|
95
92
|
# initialize style arg arrays
|
96
93
|
settings[:puppetlint_args] ||= []
|
97
94
|
settings[:rubocop_args] ||= []
|
95
|
+
|
96
|
+
# return update settings
|
97
|
+
settings
|
98
98
|
end
|
99
99
|
|
100
100
|
# parse the paths and return the array of files
|
101
|
-
def self.parse_paths(paths)
|
101
|
+
def self.parse_paths(paths = [])
|
102
|
+
private_class_method :method
|
102
103
|
files = []
|
103
104
|
|
104
105
|
# traverse the unique paths and return all files
|
@@ -111,13 +112,15 @@ class PuppetCheck
|
|
111
112
|
end
|
112
113
|
|
113
114
|
# do not process fixtures, check that at least one file was found, and remove double slashes
|
114
|
-
files.reject! { |file| file
|
115
|
+
files.reject! { |file| file.include?('fixtures') }
|
115
116
|
raise "puppet-check: no files found in supplied paths '#{paths.join(', ')}'." if files.empty?
|
116
117
|
files.map! { |file| file.gsub('//', '/') }
|
117
118
|
|
118
119
|
files.uniq
|
119
120
|
end
|
120
121
|
|
122
|
+
private
|
123
|
+
|
121
124
|
# categorize and pass the files out to the parsers to determine their status
|
122
125
|
def execute_parsers(files, settings)
|
123
126
|
# check manifests
|
@@ -145,6 +148,8 @@ class PuppetCheck
|
|
145
148
|
librarians, files = files.partition { |file| File.basename(file) =~ /(?:Puppet|Module|Rake|Gem)file$/ }
|
146
149
|
RubyParser.librarian(librarians, settings[:style], settings[:rubocop_args]) unless librarians.empty?
|
147
150
|
# ignore everything else
|
148
|
-
self.class.
|
151
|
+
files.each { |file| self.class.files[:ignored].push(file.to_s) }
|
152
|
+
# return PuppetCheck.files to mitigate singleton write accessor side effects
|
153
|
+
PuppetCheck.files
|
149
154
|
end
|
150
155
|
end
|
@@ -4,7 +4,7 @@ require_relative '../../lib/puppet-check/cli'
|
|
4
4
|
describe PuppetCheck::CLI do
|
5
5
|
context '.run' do
|
6
6
|
it 'raises an error if no paths were specified' do
|
7
|
-
expect { PuppetCheck::CLI.run(%w[-s -f]) }.to raise_error(RuntimeError, 'puppet-check: no paths specified; try using --help')
|
7
|
+
expect { PuppetCheck::CLI.run(%w[-s -f]) }.to raise_error(RuntimeError, 'puppet-check: no file paths specified; try using --help')
|
8
8
|
end
|
9
9
|
end
|
10
10
|
|
@@ -3,37 +3,38 @@ require_relative '../../lib/puppet-check/data_parser'
|
|
3
3
|
|
4
4
|
describe DataParser do
|
5
5
|
before(:each) do
|
6
|
-
PuppetCheck.
|
7
|
-
|
8
|
-
|
6
|
+
PuppetCheck.files = {
|
7
|
+
errors: {},
|
8
|
+
warnings: {},
|
9
|
+
clean: [],
|
10
|
+
ignored: []
|
11
|
+
}
|
9
12
|
end
|
10
13
|
|
11
14
|
context '.yaml' do
|
12
|
-
it 'puts a bad syntax yaml file in the error files
|
15
|
+
it 'puts a bad syntax yaml file in the error files hash' do
|
13
16
|
DataParser.yaml(["#{fixtures_dir}hieradata/syntax.yaml"])
|
14
|
-
expect(PuppetCheck.
|
15
|
-
expect(PuppetCheck.
|
16
|
-
expect(PuppetCheck.
|
17
|
+
expect(PuppetCheck.files[:errors].keys).to eql(["#{fixtures_dir}hieradata/syntax.yaml"])
|
18
|
+
expect(PuppetCheck.files[:errors]["#{fixtures_dir}hieradata/syntax.yaml"].join("\n")).to match(%r{^block sequence entries are not allowed})
|
19
|
+
expect(PuppetCheck.files[:warnings]).to eql({})
|
20
|
+
expect(PuppetCheck.files[:clean]).to eql([])
|
17
21
|
end
|
18
22
|
it 'puts a good yaml file with potential hiera issues in the warning files array' do
|
19
23
|
DataParser.yaml(["#{fixtures_dir}hieradata/style.yaml"])
|
20
|
-
expect(PuppetCheck.
|
21
|
-
expect(PuppetCheck.
|
22
|
-
expect(PuppetCheck.
|
24
|
+
expect(PuppetCheck.files[:errors]).to eql({})
|
25
|
+
expect(PuppetCheck.files[:warnings].keys).to eql(["#{fixtures_dir}hieradata/style.yaml"])
|
26
|
+
expect(PuppetCheck.files[:warnings]["#{fixtures_dir}hieradata/style.yaml"].join("\n")).to match(%r{^Value\(s\) missing in key.*\nValue\(s\) missing in key.*\nThe string --- appears more than once in this data and Hiera may fail to parse it correctly})
|
27
|
+
expect(PuppetCheck.files[:clean]).to eql([])
|
23
28
|
end
|
24
29
|
it 'puts a good yaml file in the clean files array' do
|
25
30
|
DataParser.yaml(["#{fixtures_dir}hieradata/good.yaml"])
|
26
|
-
expect(PuppetCheck.
|
27
|
-
expect(PuppetCheck.
|
28
|
-
expect(PuppetCheck.
|
31
|
+
expect(PuppetCheck.files[:errors]).to eql({})
|
32
|
+
expect(PuppetCheck.files[:warnings]).to eql({})
|
33
|
+
expect(PuppetCheck.files[:clean]).to eql(["#{fixtures_dir}hieradata/good.yaml"])
|
29
34
|
end
|
30
35
|
end
|
31
36
|
|
32
37
|
context '.eyaml' do
|
33
|
-
before(:each) do
|
34
|
-
PuppetCheck.settings[:ignored_files] = []
|
35
|
-
end
|
36
|
-
|
37
38
|
it 'returns a warning if a public key was not specified' do
|
38
39
|
expect { DataParser.eyaml(['foo.eyaml'], nil, 'private.pem') }.to output("Public X509 and/or Private RSA PKCS7 certs were not specified. EYAML checks will not be executed.\n").to_stderr
|
39
40
|
end
|
@@ -43,74 +44,80 @@ describe DataParser do
|
|
43
44
|
it 'returns a warning if the public key or private key are not existing files' do
|
44
45
|
expect { DataParser.eyaml(['foo.eyaml'], 'public.pem', 'private.pem') }.to output("Specified Public X509 and/or Private RSA PKCS7 certs do not exist. EYAML checks will not be executed.\n").to_stderr
|
45
46
|
end
|
46
|
-
it 'puts a bad syntax eyaml file in the error files
|
47
|
+
it 'puts a bad syntax eyaml file in the error files hash' do
|
47
48
|
# DataParser.eyaml(["#{fixtures_dir}hieradata/syntax.eyaml'], fixtures_dir + 'keys/public_key.pkcs7.pem', fixtures_dir + 'keys/private_key.pkcs7.pem")
|
48
|
-
# expect(PuppetCheck.
|
49
|
-
expect(PuppetCheck.
|
50
|
-
expect(PuppetCheck.
|
49
|
+
# expect(PuppetCheck.files[:errors][0]).to match(%r{^#{fixtures_dir}hieradata/syntax.eyaml:\nblock sequence entries are not allowed})
|
50
|
+
expect(PuppetCheck.files[:warnings]).to eql({})
|
51
|
+
expect(PuppetCheck.files[:clean]).to eql([])
|
51
52
|
end
|
52
53
|
it 'puts a good eyaml file with potential hiera issues in the warning files array' do
|
53
54
|
# DataParser.eyaml(["#{fixtures_dir}hieradata/style.eyaml'], fixtures_dir + 'keys/public_key.pkcs7.pem', fixtures_dir + 'keys/private_key.pkcs7.pem")
|
54
|
-
expect(PuppetCheck.
|
55
|
-
# expect(PuppetCheck.
|
56
|
-
expect(PuppetCheck.
|
55
|
+
expect(PuppetCheck.files[:errors]).to eql({})
|
56
|
+
# expect(PuppetCheck.files[:warnings].keys).to eql(["#{fixtures_dir}hieradata/style.eyaml"])
|
57
|
+
# expect(PuppetCheck.files[:warnings]["#{fixtures_dir}hieradata/style.eyaml"]).to match(%r{^Value\(s\) missing in key.*\nValue\(s\) missing in key.*\nThe string --- appears more than once in this data and Hiera will fail to parse it correctly})
|
58
|
+
expect(PuppetCheck.files[:clean]).to eql([])
|
57
59
|
end
|
58
60
|
it 'puts a good eyaml file in the clean files array' do
|
59
61
|
# DataParser.eyaml(["#{fixtures_dir}hieradata/good.eyaml'], fixtures_dir + 'keys/public_key.pkcs7.pem', fixtures_dir + 'keys/private_key.pkcs7.pem")
|
60
|
-
expect(PuppetCheck.
|
61
|
-
expect(PuppetCheck.
|
62
|
-
# expect(PuppetCheck.
|
62
|
+
expect(PuppetCheck.files[:errors]).to eql({})
|
63
|
+
expect(PuppetCheck.files[:warnings]).to eql({})
|
64
|
+
# expect(PuppetCheck.files[:clean]).to eql(["#{fixtures_dir}hieradata/good.eyaml"])
|
63
65
|
end
|
64
66
|
end
|
65
67
|
|
66
68
|
context '.json' do
|
67
|
-
it 'puts a bad syntax json file in the error files
|
69
|
+
it 'puts a bad syntax json file in the error files hash' do
|
68
70
|
DataParser.json(["#{fixtures_dir}hieradata/syntax.json"])
|
69
|
-
expect(PuppetCheck.
|
70
|
-
expect(PuppetCheck.
|
71
|
-
expect(PuppetCheck.
|
71
|
+
expect(PuppetCheck.files[:errors].keys).to eql(["#{fixtures_dir}hieradata/syntax.json"])
|
72
|
+
expect(PuppetCheck.files[:errors]["#{fixtures_dir}hieradata/syntax.json"].join("\n")).to match(%r{^.*unexpected token})
|
73
|
+
expect(PuppetCheck.files[:warnings]).to eql({})
|
74
|
+
expect(PuppetCheck.files[:clean]).to eql([])
|
72
75
|
end
|
73
|
-
it 'puts a bad metadata json file in the error files
|
76
|
+
it 'puts a bad metadata json file in the error files hash' do
|
74
77
|
DataParser.json(["#{fixtures_dir}metadata_syntax/metadata.json"])
|
75
|
-
expect(PuppetCheck.
|
76
|
-
expect(PuppetCheck.
|
77
|
-
expect(PuppetCheck.
|
78
|
+
expect(PuppetCheck.files[:errors].keys).to eql(["#{fixtures_dir}metadata_syntax/metadata.json"])
|
79
|
+
expect(PuppetCheck.files[:errors]["#{fixtures_dir}metadata_syntax/metadata.json"].join("\n")).to match(%r{^Required field.*\nField 'requirements'.*\nDuplicate dependencies.*\nDeprecated field.*\nSummary exceeds})
|
80
|
+
expect(PuppetCheck.files[:warnings]).to eql({})
|
81
|
+
expect(PuppetCheck.files[:clean]).to eql([])
|
78
82
|
end
|
79
83
|
it 'puts a bad style metadata json file in the warning files array' do
|
80
84
|
DataParser.json(["#{fixtures_dir}metadata_style/metadata.json"])
|
81
|
-
expect(PuppetCheck.
|
82
|
-
expect(PuppetCheck.
|
83
|
-
expect(PuppetCheck.
|
85
|
+
expect(PuppetCheck.files[:errors]).to eql({})
|
86
|
+
expect(PuppetCheck.files[:warnings].keys).to eql(["#{fixtures_dir}metadata_style/metadata.json"])
|
87
|
+
expect(PuppetCheck.files[:warnings]["#{fixtures_dir}metadata_style/metadata.json"].join("\n")).to match(%r{^'pe' is missing an upper bound.\n.*operatingsystem_support.*\nLicense identifier})
|
88
|
+
expect(PuppetCheck.files[:clean]).to eql([])
|
84
89
|
end
|
85
90
|
it 'puts another bad style metadata json file in the warning files array' do
|
86
91
|
DataParser.json(["#{fixtures_dir}metadata_style_two/metadata.json"])
|
87
|
-
expect(PuppetCheck.
|
88
|
-
expect(PuppetCheck.
|
89
|
-
expect(PuppetCheck.
|
92
|
+
expect(PuppetCheck.files[:errors]).to eql({})
|
93
|
+
expect(PuppetCheck.files[:warnings].keys).to eql(["#{fixtures_dir}metadata_style_two/metadata.json"])
|
94
|
+
expect(PuppetCheck.files[:warnings]["#{fixtures_dir}metadata_style_two/metadata.json"].join("\n")).to match(%r{^'puppetlabs/one' has non-semantic versioning.*\n'puppetlabs/two' is missing an upper bound\.\n.*operatingsystem.*\n.*operatingsystemrelease})
|
95
|
+
expect(PuppetCheck.files[:clean]).to eql([])
|
90
96
|
end
|
91
97
|
it 'puts a bad task metadata json file in the warning files array' do
|
92
98
|
DataParser.json(["#{fixtures_dir}task_metadata/task_bad.json"])
|
93
|
-
expect(PuppetCheck.
|
94
|
-
expect(PuppetCheck.
|
95
|
-
expect(PuppetCheck.
|
99
|
+
expect(PuppetCheck.files[:errors]).to eql({})
|
100
|
+
expect(PuppetCheck.files[:warnings].keys).to eql(["#{fixtures_dir}task_metadata/task_bad.json"])
|
101
|
+
expect(PuppetCheck.files[:warnings]["#{fixtures_dir}task_metadata/task_bad.json"].join("\n")).to match(%r{^description value is not a String\ninput_method value is not one of environment, stdin, or powershell\nparameters value is not a Hash\npuppet_task_version value is not an Integer\nsupports_noop value is not a Boolean})
|
102
|
+
expect(PuppetCheck.files[:clean]).to eql([])
|
96
103
|
end
|
97
104
|
it 'puts a good json file in the clean files array' do
|
98
105
|
DataParser.json(["#{fixtures_dir}hieradata/good.json"])
|
99
|
-
expect(PuppetCheck.
|
100
|
-
expect(PuppetCheck.
|
101
|
-
expect(PuppetCheck.
|
106
|
+
expect(PuppetCheck.files[:errors]).to eql({})
|
107
|
+
expect(PuppetCheck.files[:warnings]).to eql({})
|
108
|
+
expect(PuppetCheck.files[:clean]).to eql(["#{fixtures_dir}hieradata/good.json"])
|
102
109
|
end
|
103
110
|
it 'puts a good metadata json file in the clean files array' do
|
104
111
|
DataParser.json(["#{fixtures_dir}metadata_good/metadata.json"])
|
105
|
-
expect(PuppetCheck.
|
106
|
-
expect(PuppetCheck.
|
107
|
-
expect(PuppetCheck.
|
112
|
+
expect(PuppetCheck.files[:errors]).to eql({})
|
113
|
+
expect(PuppetCheck.files[:warnings]).to eql({})
|
114
|
+
expect(PuppetCheck.files[:clean]).to eql(["#{fixtures_dir}metadata_good/metadata.json"])
|
108
115
|
end
|
109
116
|
it 'puts a good task metadata json file in the clean files array' do
|
110
117
|
DataParser.json(["#{fixtures_dir}task_metadata/task_good.json"])
|
111
|
-
expect(PuppetCheck.
|
112
|
-
expect(PuppetCheck.
|
113
|
-
expect(PuppetCheck.
|
118
|
+
expect(PuppetCheck.files[:errors]).to eql({})
|
119
|
+
expect(PuppetCheck.files[:warnings]).to eql({})
|
120
|
+
expect(PuppetCheck.files[:clean]).to eql(["#{fixtures_dir}task_metadata/task_good.json"])
|
114
121
|
end
|
115
122
|
end
|
116
123
|
end
|
@@ -3,73 +3,62 @@ require_relative '../../lib/puppet-check/output_results'
|
|
3
3
|
|
4
4
|
describe OutputResults do
|
5
5
|
context '.text' do
|
6
|
-
before(:each) do
|
7
|
-
PuppetCheck.settings[:error_files] = []
|
8
|
-
PuppetCheck.settings[:warning_files] = []
|
9
|
-
PuppetCheck.settings[:clean_files] = []
|
10
|
-
PuppetCheck.settings[:ignored_files] = []
|
11
|
-
end
|
12
|
-
|
13
6
|
it 'outputs files with errors' do
|
14
|
-
|
15
|
-
expect { OutputResults.text }.to output("\033[31mThe following files have errors:\033[0m\n-- foo
|
7
|
+
files = { errors: { 'foo' => ['i had an error'] } }
|
8
|
+
expect { OutputResults.text(files) }.to output("\033[31mThe following files have errors:\033[0m\n-- foo:\ni had an error\n").to_stdout
|
16
9
|
end
|
17
10
|
it 'outputs files with warnings' do
|
18
|
-
|
19
|
-
expect { OutputResults.text }.to output("\n\033[33mThe following files have warnings:\033[0m\n-- foo
|
11
|
+
files = { warnings: { 'foo' => ['i had a warning'] } }
|
12
|
+
expect { OutputResults.text(files) }.to output("\n\033[33mThe following files have warnings:\033[0m\n-- foo:\ni had a warning\n").to_stdout
|
20
13
|
end
|
21
14
|
it 'outputs files with no errors or warnings' do
|
22
|
-
|
23
|
-
expect { OutputResults.text }.to output("\n\033[32mThe following files have no errors or warnings:\033[0m\n-- foo
|
15
|
+
files = { clean: ['foo'] }
|
16
|
+
expect { OutputResults.text(files) }.to output("\n\033[32mThe following files have no errors or warnings:\033[0m\n-- foo\n").to_stdout
|
24
17
|
end
|
25
18
|
it 'outputs files that were not processed' do
|
26
|
-
|
27
|
-
expect { OutputResults.text }.to output("\n\033[36mThe following files have unrecognized formats and therefore were not processed:\033[0m\n-- foo
|
19
|
+
files = { ignored: ['foo'] }
|
20
|
+
expect { OutputResults.text(files) }.to output("\n\033[36mThe following files have unrecognized formats and therefore were not processed:\033[0m\n-- foo\n").to_stdout
|
28
21
|
end
|
29
22
|
end
|
30
23
|
|
31
|
-
context '.
|
32
|
-
|
33
|
-
|
34
|
-
PuppetCheck.settings[:warning_files] = []
|
35
|
-
PuppetCheck.settings[:clean_files] = []
|
36
|
-
PuppetCheck.settings[:ignored_files] = []
|
24
|
+
context '.run' do
|
25
|
+
it 'redirects to text output formatting as expected' do
|
26
|
+
expect { OutputResults.run({}, 'text') }.to output('').to_stdout
|
37
27
|
end
|
38
|
-
|
39
28
|
it 'outputs files with errors as yaml' do
|
40
|
-
|
41
|
-
expect { OutputResults.
|
29
|
+
files = { errors: { 'foo' => ['i had an error'] } }
|
30
|
+
expect { OutputResults.run(files, 'yaml') }.to output("---\nerrors:\n foo:\n - i had an error\n").to_stdout
|
42
31
|
end
|
43
32
|
it 'outputs files with warnings as yaml' do
|
44
|
-
|
45
|
-
expect { OutputResults.
|
33
|
+
files = { warnings: { 'foo' => ['i had a warning'] } }
|
34
|
+
expect { OutputResults.run(files, 'yaml') }.to output("---\nwarnings:\n foo:\n - i had a warning\n").to_stdout
|
46
35
|
end
|
47
36
|
it 'outputs files with no errors or warnings as yaml' do
|
48
|
-
|
49
|
-
expect { OutputResults.
|
37
|
+
files = { clean: ['foo'] }
|
38
|
+
expect { OutputResults.run(files, 'yaml') }.to output("---\nclean:\n- foo\n").to_stdout
|
50
39
|
end
|
51
40
|
it 'outputs files that were not processed as yaml' do
|
52
|
-
|
53
|
-
expect { OutputResults.
|
41
|
+
files = { ignored: ['foo'] }
|
42
|
+
expect { OutputResults.run(files, 'yaml') }.to output("---\nignored:\n- foo\n").to_stdout
|
54
43
|
end
|
55
44
|
it 'outputs files with errors as json' do
|
56
|
-
|
57
|
-
expect { OutputResults.
|
45
|
+
files = { errors: { 'foo' => ['i had an error'] } }
|
46
|
+
expect { OutputResults.run(files, 'json') }.to output("{\n \"errors\": {\n \"foo\": [\n \"i had an error\"\n ]\n }\n}\n").to_stdout
|
58
47
|
end
|
59
48
|
it 'outputs files with warnings as json' do
|
60
|
-
|
61
|
-
expect { OutputResults.
|
49
|
+
files = { warnings: { 'foo' => ['i had a warning'] } }
|
50
|
+
expect { OutputResults.run(files, 'json') }.to output("{\n \"warnings\": {\n \"foo\": [\n \"i had a warning\"\n ]\n }\n}\n").to_stdout
|
62
51
|
end
|
63
52
|
it 'outputs files with no errors or warnings as json' do
|
64
|
-
|
65
|
-
expect { OutputResults.
|
53
|
+
files = { clean: ['foo'] }
|
54
|
+
expect { OutputResults.run(files, 'json') }.to output("{\n \"clean\": [\n \"foo\"\n ]\n}\n").to_stdout
|
66
55
|
end
|
67
56
|
it 'outputs files that were not processed as json' do
|
68
|
-
|
69
|
-
expect { OutputResults.
|
57
|
+
files = { ignored: ['foo'] }
|
58
|
+
expect { OutputResults.run(files, 'json') }.to output("{\n \"ignored\": [\n \"foo\"\n ]\n}\n").to_stdout
|
70
59
|
end
|
71
60
|
it 'raises an error for an unsupported output format' do
|
72
|
-
expect { OutputResults.
|
61
|
+
expect { OutputResults.run({}, 'awesomesauce') }.to raise_error(RuntimeError, 'puppet-check: Unsupported output format \'awesomesauce\' was specified.')
|
73
62
|
end
|
74
63
|
end
|
75
64
|
end
|
@@ -3,72 +3,81 @@ require_relative '../../lib/puppet-check/puppet_parser'
|
|
3
3
|
|
4
4
|
describe PuppetParser do
|
5
5
|
before(:each) do
|
6
|
-
PuppetCheck.
|
7
|
-
|
8
|
-
|
6
|
+
PuppetCheck.files = {
|
7
|
+
errors: {},
|
8
|
+
warnings: {},
|
9
|
+
clean: [],
|
10
|
+
ignored: []
|
11
|
+
}
|
9
12
|
end
|
10
13
|
|
11
14
|
context '.manifest' do
|
12
|
-
it 'puts a bad syntax Puppet manifest in the error files
|
15
|
+
it 'puts a bad syntax Puppet manifest in the error files hash' do
|
13
16
|
PuppetParser.manifest(["#{fixtures_dir}manifests/syntax.pp"], false, [])
|
17
|
+
expect(PuppetCheck.files[:errors].keys).to eql(["#{fixtures_dir}manifests/syntax.pp"])
|
14
18
|
if Gem::Version.new(Puppet::PUPPETVERSION) >= Gem::Version.new('6.5.0')
|
15
|
-
expect(PuppetCheck.
|
19
|
+
expect(PuppetCheck.files[:errors]["#{fixtures_dir}manifests/syntax.pp"].join("\n")).to match(%r{^Language validation logged 2 errors})
|
16
20
|
else
|
17
|
-
expect(PuppetCheck.
|
21
|
+
expect(PuppetCheck.files[:errors]["#{fixtures_dir}hieradata/syntax.yaml"].join("\n")).to match(%r{^This Variable has no effect.*\nIllegal variable name})
|
18
22
|
end
|
19
|
-
expect(PuppetCheck.
|
20
|
-
expect(PuppetCheck.
|
23
|
+
expect(PuppetCheck.files[:warnings]).to eql({})
|
24
|
+
expect(PuppetCheck.files[:clean]).to eql([])
|
21
25
|
end
|
22
26
|
# puppet 5 api has output issues for this fixture
|
23
27
|
unless Gem::Version.new(Puppet::PUPPETVERSION) < Gem::Version.new('6.0.0')
|
24
|
-
it 'puts a bad syntax at eof Puppet manifest in the error files
|
28
|
+
it 'puts a bad syntax at eof Puppet manifest in the error files hash' do
|
25
29
|
PuppetParser.manifest(["#{fixtures_dir}manifests/eof_syntax.pp"], false, [])
|
26
|
-
expect(PuppetCheck.
|
27
|
-
expect(PuppetCheck.
|
28
|
-
expect(PuppetCheck.
|
30
|
+
expect(PuppetCheck.files[:errors].keys).to eql(["#{fixtures_dir}manifests/eof_syntax.pp"])
|
31
|
+
expect(PuppetCheck.files[:errors]["#{fixtures_dir}manifests/eof_syntax.pp"].join("\n")).to match(%r{^Syntax error at end of input})
|
32
|
+
expect(PuppetCheck.files[:warnings]).to eql({})
|
33
|
+
expect(PuppetCheck.files[:clean]).to eql([])
|
29
34
|
end
|
30
35
|
end
|
31
|
-
it 'puts a bad syntax Puppet plan in the error files
|
36
|
+
it 'puts a bad syntax Puppet plan in the error files hash' do
|
32
37
|
PuppetParser.manifest(["#{fixtures_dir}plans/syntax.pp"], false, [])
|
33
|
-
expect(PuppetCheck.
|
34
|
-
expect(PuppetCheck.
|
35
|
-
expect(PuppetCheck.
|
38
|
+
expect(PuppetCheck.files[:errors].keys).to eql(["#{fixtures_dir}plans/syntax.pp"])
|
39
|
+
expect(PuppetCheck.files[:errors]["#{fixtures_dir}plans/syntax.pp"].join("\n")).to match(%r{^Syntax error at '\)'})
|
40
|
+
expect(PuppetCheck.files[:warnings]).to eql({})
|
41
|
+
expect(PuppetCheck.files[:clean]).to eql([])
|
36
42
|
end
|
37
|
-
it 'puts a bad parser and lint style Puppet manifest in the warning files array' do
|
43
|
+
it 'puts a bad parser style and lint style Puppet manifest in the warning files array' do
|
38
44
|
PuppetParser.manifest(["#{fixtures_dir}manifests/style_parser.pp"], true, [])
|
39
|
-
expect(PuppetCheck.
|
40
|
-
expect(PuppetCheck.
|
41
|
-
expect(PuppetCheck.
|
45
|
+
expect(PuppetCheck.files[:errors]).to eql({})
|
46
|
+
expect(PuppetCheck.files[:warnings].keys).to eql(["#{fixtures_dir}manifests/style_parser.pp"])
|
47
|
+
expect(PuppetCheck.files[:warnings]["#{fixtures_dir}manifests/style_parser.pp"].join("\n")).to match(%r{^Unrecognized escape sequence.*\nUnrecognized escape sequence.*\n.*double quoted string containing})
|
48
|
+
expect(PuppetCheck.files[:clean]).to eql([])
|
42
49
|
end
|
43
50
|
it 'puts a bad lint style Puppet manifest in the warning files array' do
|
44
51
|
PuppetParser.manifest(["#{fixtures_dir}manifests/style_lint.pp"], true, [])
|
45
|
-
expect(PuppetCheck.
|
46
|
-
expect(PuppetCheck.
|
47
|
-
expect(PuppetCheck.
|
52
|
+
expect(PuppetCheck.files[:errors]).to eql({})
|
53
|
+
expect(PuppetCheck.files[:warnings].keys).to eql(["#{fixtures_dir}manifests/style_lint.pp"])
|
54
|
+
expect(PuppetCheck.files[:warnings]["#{fixtures_dir}manifests/style_lint.pp"].join("\n")).to match(%r{(?:indentation of|double quoted string containing).*\n.*(?:indentation of|double quoted string containing)})
|
55
|
+
expect(PuppetCheck.files[:clean]).to eql([])
|
48
56
|
end
|
49
57
|
it 'puts a bad style Puppet manifest in the clean files array when puppetlint_args ignores its warnings' do
|
50
58
|
PuppetParser.manifest(["#{fixtures_dir}manifests/style_lint.pp"], true, ['--no-double_quoted_strings-check', '--no-arrow_alignment-check'])
|
51
|
-
expect(PuppetCheck.
|
52
|
-
expect(PuppetCheck.
|
53
|
-
expect(PuppetCheck.
|
59
|
+
expect(PuppetCheck.files[:errors]).to eql({})
|
60
|
+
expect(PuppetCheck.files[:warnings]).to eql({})
|
61
|
+
expect(PuppetCheck.files[:clean]).to eql(["#{fixtures_dir}manifests/style_lint.pp"])
|
54
62
|
end
|
55
63
|
it 'puts a bad style Puppet plan in the warning files array' do
|
56
64
|
PuppetParser.manifest(["#{fixtures_dir}plans/style.pp"], true, [])
|
57
|
-
expect(PuppetCheck.
|
58
|
-
expect(PuppetCheck.
|
59
|
-
expect(PuppetCheck.
|
65
|
+
expect(PuppetCheck.files[:errors]).to eql({})
|
66
|
+
expect(PuppetCheck.files[:warnings].keys).to eql(["#{fixtures_dir}plans/style.pp"])
|
67
|
+
expect(PuppetCheck.files[:warnings]["#{fixtures_dir}plans/style.pp"].join("\n")).to match(%r{variable not enclosed in {}})
|
68
|
+
expect(PuppetCheck.files[:clean]).to eql([])
|
60
69
|
end
|
61
70
|
it 'puts a good Puppet manifest in the clean files array' do
|
62
71
|
PuppetParser.manifest(["#{fixtures_dir}manifests/good.pp"], true, [])
|
63
|
-
expect(PuppetCheck.
|
64
|
-
expect(PuppetCheck.
|
65
|
-
expect(PuppetCheck.
|
72
|
+
expect(PuppetCheck.files[:errors]).to eql({})
|
73
|
+
expect(PuppetCheck.files[:warnings]).to eql({})
|
74
|
+
expect(PuppetCheck.files[:clean]).to eql(["#{fixtures_dir}manifests/good.pp"])
|
66
75
|
end
|
67
76
|
it 'puts a good Puppet plan in the clean files array' do
|
68
77
|
PuppetParser.manifest(["#{fixtures_dir}plans/good.pp"], true, [])
|
69
|
-
expect(PuppetCheck.
|
70
|
-
expect(PuppetCheck.
|
71
|
-
expect(PuppetCheck.
|
78
|
+
expect(PuppetCheck.files[:errors]).to eql({})
|
79
|
+
expect(PuppetCheck.files[:warnings]).to eql({})
|
80
|
+
expect(PuppetCheck.files[:clean]).to eql(["#{fixtures_dir}plans/good.pp"])
|
72
81
|
end
|
73
82
|
it 'throws a well specified error for an invalid PuppetLint argument' do
|
74
83
|
expect { PuppetParser.manifest(["#{fixtures_dir}manifests/style_lint.pp"], true, ['--non-existent', '--does-not-exist']) }.to raise_error(RuntimeError, 'puppet-lint: invalid option supplied among --non-existent --does-not-exist')
|
@@ -76,17 +85,18 @@ describe PuppetParser do
|
|
76
85
|
end
|
77
86
|
|
78
87
|
context '.template' do
|
79
|
-
it 'puts a bad syntax Puppet template in the error files
|
88
|
+
it 'puts a bad syntax Puppet template in the error files hash' do
|
80
89
|
PuppetParser.template(["#{fixtures_dir}templates/syntax.epp"])
|
81
|
-
expect(PuppetCheck.
|
82
|
-
expect(PuppetCheck.
|
83
|
-
expect(PuppetCheck.
|
90
|
+
expect(PuppetCheck.files[:errors].keys).to eql(["#{fixtures_dir}templates/syntax.epp"])
|
91
|
+
expect(PuppetCheck.files[:errors]["#{fixtures_dir}templates/syntax.epp"].join("\n")).to match(%r{^This Name has no effect})
|
92
|
+
expect(PuppetCheck.files[:warnings]).to eql({})
|
93
|
+
expect(PuppetCheck.files[:clean]).to eql([])
|
84
94
|
end
|
85
95
|
it 'puts a good Puppet template in the clean files array' do
|
86
96
|
PuppetParser.template(["#{fixtures_dir}templates/good.epp"])
|
87
|
-
expect(PuppetCheck.
|
88
|
-
expect(PuppetCheck.
|
89
|
-
expect(PuppetCheck.
|
97
|
+
expect(PuppetCheck.files[:errors]).to eql({})
|
98
|
+
expect(PuppetCheck.files[:warnings]).to eql({})
|
99
|
+
expect(PuppetCheck.files[:clean]).to eql(["#{fixtures_dir}templates/good.epp"])
|
90
100
|
end
|
91
101
|
end
|
92
102
|
end
|
@@ -15,10 +15,10 @@ describe RSpecPuppetSupport do
|
|
15
15
|
|
16
16
|
it 'creates missing directories, missing site.pp, missing symlinks, and a missing spec_helper' do
|
17
17
|
# travis ci
|
18
|
-
if ENV['TRAVIS'] == 'true'
|
18
|
+
if ENV['TRAVIS'] == 'true'
|
19
19
|
expect { rspec_puppet_setup }.to output("puppetlabs/gruntmaster has an unspecified, or specified but unsupported, download method.\n").to_stderr
|
20
|
-
# circle ci
|
21
|
-
elsif ENV['CIRCLECI'] == 'true'
|
20
|
+
# circle ci and gh actions
|
21
|
+
elsif ENV['CIRCLECI'] == 'true' || ENV['GITHUB_ACTIONS'] == 'true'
|
22
22
|
expect { rspec_puppet_setup }.to output("git is not installed and cannot be used to retrieve dependency modules\nsubversion is not installed and cannot be used to retrieve dependency modules\npuppetlabs/gruntmaster has an unspecified, or specified but unsupported, download method.\n").to_stderr
|
23
23
|
else
|
24
24
|
expect { rspec_puppet_setup }.to output("subversion is not installed and cannot be used to retrieve dependency modules\npuppetlabs/gruntmaster has an unspecified, or specified but unsupported, download method.\n").to_stderr
|
@@ -32,7 +32,7 @@ describe RSpecPuppetSupport do
|
|
32
32
|
expect(File.file?('spec/spec_helper.rb')).to be true
|
33
33
|
|
34
34
|
# .dependency_setup
|
35
|
-
expect(File.directory?('spec/fixtures/modules/puppetlabs-lvm')).to be true unless ENV['CIRCLECI'] == 'true'
|
35
|
+
expect(File.directory?('spec/fixtures/modules/puppetlabs-lvm')).to be true unless ENV['CIRCLECI'] == 'true' || ENV['GITHUB_ACTIONS'] == 'true'
|
36
36
|
expect(File.directory?('spec/fixtures/modules/stdlib')).to be true
|
37
37
|
end
|
38
38
|
end
|