puppet-lint-halyard 1.1.0.1
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 +7 -0
- data/.gitignore +9 -0
- data/.travis.yml +10 -0
- data/Gemfile +3 -0
- data/LICENSE +20 -0
- data/README.md +210 -0
- data/Rakefile +14 -0
- data/bin/puppet-lint +7 -0
- data/lib/puppet-lint.rb +214 -0
- data/lib/puppet-lint/bin.rb +79 -0
- data/lib/puppet-lint/checkplugin.rb +176 -0
- data/lib/puppet-lint/checks.rb +91 -0
- data/lib/puppet-lint/configuration.rb +153 -0
- data/lib/puppet-lint/data.rb +521 -0
- data/lib/puppet-lint/lexer.rb +373 -0
- data/lib/puppet-lint/lexer/token.rb +101 -0
- data/lib/puppet-lint/monkeypatches.rb +2 -0
- data/lib/puppet-lint/monkeypatches/string_percent.rb +52 -0
- data/lib/puppet-lint/monkeypatches/string_prepend.rb +13 -0
- data/lib/puppet-lint/optparser.rb +118 -0
- data/lib/puppet-lint/plugins.rb +74 -0
- data/lib/puppet-lint/plugins/check_classes.rb +285 -0
- data/lib/puppet-lint/plugins/check_comments.rb +55 -0
- data/lib/puppet-lint/plugins/check_conditionals.rb +65 -0
- data/lib/puppet-lint/plugins/check_documentation.rb +31 -0
- data/lib/puppet-lint/plugins/check_nodes.rb +29 -0
- data/lib/puppet-lint/plugins/check_resources.rb +194 -0
- data/lib/puppet-lint/plugins/check_strings.rb +174 -0
- data/lib/puppet-lint/plugins/check_variables.rb +19 -0
- data/lib/puppet-lint/plugins/check_whitespace.rb +170 -0
- data/lib/puppet-lint/tasks/puppet-lint.rb +91 -0
- data/lib/puppet-lint/version.rb +3 -0
- data/puppet-lint.gemspec +24 -0
- data/spec/fixtures/test/manifests/fail.pp +2 -0
- data/spec/fixtures/test/manifests/ignore.pp +1 -0
- data/spec/fixtures/test/manifests/ignore_multiple_block.pp +6 -0
- data/spec/fixtures/test/manifests/ignore_multiple_line.pp +2 -0
- data/spec/fixtures/test/manifests/ignore_reason.pp +1 -0
- data/spec/fixtures/test/manifests/init.pp +3 -0
- data/spec/fixtures/test/manifests/malformed.pp +1 -0
- data/spec/fixtures/test/manifests/url_interpolation.pp +12 -0
- data/spec/fixtures/test/manifests/warning.pp +2 -0
- data/spec/puppet-lint/bin_spec.rb +326 -0
- data/spec/puppet-lint/configuration_spec.rb +56 -0
- data/spec/puppet-lint/ignore_overrides_spec.rb +109 -0
- data/spec/puppet-lint/lexer/token_spec.rb +18 -0
- data/spec/puppet-lint/lexer_spec.rb +783 -0
- data/spec/puppet-lint/plugins/check_classes/autoloader_layout_spec.rb +105 -0
- data/spec/puppet-lint/plugins/check_classes/class_inherits_from_params_class_spec.rb +35 -0
- data/spec/puppet-lint/plugins/check_classes/inherits_across_namespaces_spec.rb +33 -0
- data/spec/puppet-lint/plugins/check_classes/names_containing_dash_spec.rb +45 -0
- data/spec/puppet-lint/plugins/check_classes/nested_classes_or_defines_spec.rb +76 -0
- data/spec/puppet-lint/plugins/check_classes/parameter_order_spec.rb +73 -0
- data/spec/puppet-lint/plugins/check_classes/right_to_left_relationship_spec.rb +25 -0
- data/spec/puppet-lint/plugins/check_classes/variable_scope_spec.rb +196 -0
- data/spec/puppet-lint/plugins/check_comments/slash_comments_spec.rb +45 -0
- data/spec/puppet-lint/plugins/check_comments/star_comments_spec.rb +84 -0
- data/spec/puppet-lint/plugins/check_conditionals/case_without_default_spec.rb +98 -0
- data/spec/puppet-lint/plugins/check_conditionals/selector_inside_resource_spec.rb +36 -0
- data/spec/puppet-lint/plugins/check_documentation/documentation_spec.rb +52 -0
- data/spec/puppet-lint/plugins/check_nodes/unquoted_node_name_spec.rb +146 -0
- data/spec/puppet-lint/plugins/check_resources/duplicate_params_spec.rb +100 -0
- data/spec/puppet-lint/plugins/check_resources/ensure_first_param_spec.rb +55 -0
- data/spec/puppet-lint/plugins/check_resources/ensure_not_symlink_target_spec.rb +89 -0
- data/spec/puppet-lint/plugins/check_resources/file_mode_spec.rb +113 -0
- data/spec/puppet-lint/plugins/check_resources/unquoted_file_mode_spec.rb +45 -0
- data/spec/puppet-lint/plugins/check_resources/unquoted_resource_title_spec.rb +216 -0
- data/spec/puppet-lint/plugins/check_strings/double_quoted_strings_spec.rb +199 -0
- data/spec/puppet-lint/plugins/check_strings/only_variable_string_spec.rb +114 -0
- data/spec/puppet-lint/plugins/check_strings/puppet_url_without_modules_spec.rb +62 -0
- data/spec/puppet-lint/plugins/check_strings/quoted_booleans_spec.rb +129 -0
- data/spec/puppet-lint/plugins/check_strings/single_quote_string_with_variables_spec.rb +17 -0
- data/spec/puppet-lint/plugins/check_strings/variables_not_enclosed_spec.rb +73 -0
- data/spec/puppet-lint/plugins/check_variables/variable_contains_dash_spec.rb +37 -0
- data/spec/puppet-lint/plugins/check_whitespace/2sp_soft_tabs_spec.rb +21 -0
- data/spec/puppet-lint/plugins/check_whitespace/80chars_spec.rb +54 -0
- data/spec/puppet-lint/plugins/check_whitespace/arrow_alignment_spec.rb +524 -0
- data/spec/puppet-lint/plugins/check_whitespace/hard_tabs_spec.rb +45 -0
- data/spec/puppet-lint/plugins/check_whitespace/trailing_whitespace_spec.rb +101 -0
- data/spec/puppet-lint_spec.rb +20 -0
- data/spec/spec_helper.rb +129 -0
- metadata +229 -0
@@ -0,0 +1,19 @@
|
|
1
|
+
# Public: Test the manifest tokens for variables that contain a dash and
|
2
|
+
# record a warning for each instance found.
|
3
|
+
PuppetLint.new_check(:variable_contains_dash) do
|
4
|
+
VARIABLE_TYPES = Set[:VARIABLE, :UNENC_VARIABLE]
|
5
|
+
|
6
|
+
def check
|
7
|
+
tokens.select { |r|
|
8
|
+
VARIABLE_TYPES.include? r.type
|
9
|
+
}.each do |token|
|
10
|
+
if token.value.gsub(/\[.+?\]/, '').match(/-/)
|
11
|
+
notify :warning, {
|
12
|
+
:message => 'variable contains a dash',
|
13
|
+
:line => token.line,
|
14
|
+
:column => token.column,
|
15
|
+
}
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,170 @@
|
|
1
|
+
# Public: Check the raw manifest string for lines containing hard tab
|
2
|
+
# characters and record an error for each instance found.
|
3
|
+
PuppetLint.new_check(:hard_tabs) do
|
4
|
+
WHITESPACE_TYPES = Set[:INDENT, :WHITESPACE]
|
5
|
+
|
6
|
+
def check
|
7
|
+
tokens.select { |r|
|
8
|
+
WHITESPACE_TYPES.include?(r.type) && r.value.include?("\t")
|
9
|
+
}.each do |token|
|
10
|
+
notify :error, {
|
11
|
+
:message => 'tab character found',
|
12
|
+
:line => token.line,
|
13
|
+
:column => token.column,
|
14
|
+
:token => token,
|
15
|
+
}
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def fix(problem)
|
20
|
+
problem[:token].value.gsub!("\t", ' ')
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
# Public: Check the manifest tokens for lines ending with whitespace and record
|
25
|
+
# an error for each instance found.
|
26
|
+
PuppetLint.new_check(:trailing_whitespace) do
|
27
|
+
def check
|
28
|
+
tokens.select { |token|
|
29
|
+
[:WHITESPACE, :INDENT].include?(token.type)
|
30
|
+
}.select { |token|
|
31
|
+
token.next_token.nil? || token.next_token.type == :NEWLINE
|
32
|
+
}.each do |token|
|
33
|
+
notify :error, {
|
34
|
+
:message => 'trailing whitespace found',
|
35
|
+
:line => token.line,
|
36
|
+
:column => token.column,
|
37
|
+
:token => token,
|
38
|
+
}
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def fix(problem)
|
43
|
+
prev_token = problem[:token].prev_token
|
44
|
+
next_token = problem[:token].next_token
|
45
|
+
prev_token.next_token = next_token
|
46
|
+
next_token.prev_token = prev_token unless next_token.nil?
|
47
|
+
tokens.delete(problem[:token])
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
# Public: Test the raw manifest string for lines containing more than 80
|
52
|
+
# characters and record a warning for each instance found. The only exceptions
|
53
|
+
# to this rule are lines containing URLs and template() calls which would hurt
|
54
|
+
# readability if split.
|
55
|
+
PuppetLint.new_check(:'80chars') do
|
56
|
+
def check
|
57
|
+
manifest_lines.each_with_index do |line, idx|
|
58
|
+
unless line =~ /:\/\// || line =~ /template\(/
|
59
|
+
if line.scan(/./mu).size > 80
|
60
|
+
notify :warning, {
|
61
|
+
:message => 'line has more than 80 characters',
|
62
|
+
:line => idx + 1,
|
63
|
+
:column => 80,
|
64
|
+
}
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
# Public: Check the manifest tokens for any indentation not using 2 space soft
|
72
|
+
# tabs and record an error for each instance found.
|
73
|
+
PuppetLint.new_check(:'2sp_soft_tabs') do
|
74
|
+
def check
|
75
|
+
tokens.select { |r|
|
76
|
+
r.type == :INDENT
|
77
|
+
}.reject { |r|
|
78
|
+
r.value.length % 2 == 0
|
79
|
+
}.each do |token|
|
80
|
+
notify :error, {
|
81
|
+
:message => 'two-space soft tabs not used',
|
82
|
+
:line => token.line,
|
83
|
+
:column => token.column,
|
84
|
+
}
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
# Public: Check the manifest tokens for any arrows (=>) in a grouping ({}) that
|
90
|
+
# are not aligned with other arrows in that grouping.
|
91
|
+
PuppetLint.new_check(:arrow_alignment) do
|
92
|
+
COMMENT_TYPES = Set[:COMMENT, :SLASH_COMMENT, :MLCOMMENT]
|
93
|
+
|
94
|
+
def check
|
95
|
+
resource_indexes.each do |res_idx|
|
96
|
+
indent_depth = [0]
|
97
|
+
indent_depth_idx = 0
|
98
|
+
level_tokens = []
|
99
|
+
resource_tokens = res_idx[:tokens]
|
100
|
+
resource_tokens.reject! do |token|
|
101
|
+
COMMENT_TYPES.include? token.type
|
102
|
+
end
|
103
|
+
|
104
|
+
# If this is a single line resource, skip it
|
105
|
+
first_arrow = resource_tokens.index { |r| r.type == :FARROW }
|
106
|
+
last_arrow = resource_tokens.rindex { |r| r.type == :FARROW }
|
107
|
+
next if first_arrow.nil?
|
108
|
+
next if last_arrow.nil?
|
109
|
+
next unless resource_tokens[first_arrow..last_arrow].any? { |r| r.type == :NEWLINE }
|
110
|
+
|
111
|
+
resource_tokens.each_with_index do |token, idx|
|
112
|
+
if token.type == :FARROW
|
113
|
+
(level_tokens[indent_depth_idx] ||= []) << token
|
114
|
+
prev_indent_token = resource_tokens[0..idx].rindex { |t| t.type == :INDENT }
|
115
|
+
indent_token_length = prev_indent_token.nil? ? 0 : resource_tokens[prev_indent_token].to_manifest.length
|
116
|
+
indent_length = indent_token_length + token.prev_code_token.to_manifest.length + 2
|
117
|
+
|
118
|
+
if indent_depth[indent_depth_idx] < indent_length
|
119
|
+
indent_depth[indent_depth_idx] = indent_length
|
120
|
+
end
|
121
|
+
|
122
|
+
elsif token.type == :LBRACE
|
123
|
+
indent_depth_idx += 1
|
124
|
+
indent_depth << 0
|
125
|
+
level_tokens[indent_depth_idx] ||= []
|
126
|
+
elsif token.type == :RBRACE
|
127
|
+
level_tokens[indent_depth_idx].each do |arrow_tok|
|
128
|
+
unless arrow_tok.column == indent_depth[indent_depth_idx] || level_tokens[indent_depth_idx].size == 1
|
129
|
+
arrows_on_line = level_tokens[indent_depth_idx].select { |t| t.line == arrow_tok.line }
|
130
|
+
notify :warning, {
|
131
|
+
:message => 'indentation of => is not properly aligned',
|
132
|
+
:line => arrow_tok.line,
|
133
|
+
:column => arrow_tok.column,
|
134
|
+
:token => arrow_tok,
|
135
|
+
:indent_depth => indent_depth[indent_depth_idx],
|
136
|
+
:newline => !(arrows_on_line.index(arrow_tok) == 0),
|
137
|
+
:newline_indent => arrows_on_line.first.prev_code_token.prev_token.value,
|
138
|
+
}
|
139
|
+
end
|
140
|
+
end
|
141
|
+
indent_depth[indent_depth_idx] = 0
|
142
|
+
level_tokens[indent_depth_idx].clear
|
143
|
+
indent_depth_idx -= 1
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
def fix(problem)
|
150
|
+
new_ws_len = (problem[:indent_depth] - (problem[:newline_indent].length + problem[:token].prev_code_token.to_manifest.length + 1))
|
151
|
+
new_ws = ' ' * new_ws_len
|
152
|
+
if problem[:newline]
|
153
|
+
index = tokens.index(problem[:token].prev_code_token.prev_token)
|
154
|
+
|
155
|
+
#insert newline
|
156
|
+
tokens.insert(index, PuppetLint::Lexer::Token.new(:NEWLINE, "\n", 0, 0))
|
157
|
+
|
158
|
+
# indent the parameter to the correct depth
|
159
|
+
problem[:token].prev_code_token.prev_token.type = :INDENT
|
160
|
+
problem[:token].prev_code_token.prev_token.value = problem[:newline_indent].dup
|
161
|
+
end
|
162
|
+
|
163
|
+
if problem[:token].prev_token.type == :WHITESPACE
|
164
|
+
problem[:token].prev_token.value = new_ws
|
165
|
+
else
|
166
|
+
index = tokens.index(problem[:token].prev_token)
|
167
|
+
tokens.insert(index + 1, PuppetLint::Lexer::Token.new(:WHITESPACE, new_ws, 0, 0))
|
168
|
+
end
|
169
|
+
end
|
170
|
+
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
require 'puppet-lint'
|
2
|
+
require 'puppet-lint/optparser'
|
3
|
+
require 'rake'
|
4
|
+
require 'rake/tasklib'
|
5
|
+
|
6
|
+
class PuppetLint
|
7
|
+
# Public: A Rake task that can be loaded and used with everything you need.
|
8
|
+
#
|
9
|
+
# Examples
|
10
|
+
#
|
11
|
+
# require 'puppet-lint'
|
12
|
+
# PuppetLint::RakeTask.new
|
13
|
+
class RakeTask < ::Rake::TaskLib
|
14
|
+
include ::Rake::DSL if defined?(::Rake::DSL)
|
15
|
+
|
16
|
+
DEFAULT_PATTERN = '**/*.pp'
|
17
|
+
|
18
|
+
attr_accessor :name
|
19
|
+
attr_accessor :pattern
|
20
|
+
attr_accessor :ignore_paths
|
21
|
+
attr_accessor :with_filename
|
22
|
+
attr_accessor :disable_checks
|
23
|
+
attr_accessor :fail_on_warnings
|
24
|
+
attr_accessor :error_level
|
25
|
+
attr_accessor :log_format
|
26
|
+
attr_accessor :with_context
|
27
|
+
attr_accessor :fix
|
28
|
+
attr_accessor :show_ignored
|
29
|
+
attr_accessor :relative
|
30
|
+
|
31
|
+
# Public: Initialise a new PuppetLint::RakeTask.
|
32
|
+
#
|
33
|
+
# args - Not used.
|
34
|
+
#
|
35
|
+
# Example
|
36
|
+
#
|
37
|
+
# PuppetLint::RakeTask.new
|
38
|
+
def initialize(*args, &task_block)
|
39
|
+
@name = args.shift || :lint
|
40
|
+
@pattern = DEFAULT_PATTERN
|
41
|
+
@with_filename = true
|
42
|
+
@disable_checks = []
|
43
|
+
@ignore_paths = []
|
44
|
+
|
45
|
+
define(args, &task_block)
|
46
|
+
end
|
47
|
+
|
48
|
+
def define(args, &task_block)
|
49
|
+
desc 'Run puppet-lint'
|
50
|
+
|
51
|
+
task_block.call(*[self, args].slice(0, task_block.arity)) if task_block
|
52
|
+
|
53
|
+
# clear any (auto-)pre-existing task
|
54
|
+
Rake::Task[@name].clear if Rake::Task.task_defined?(@name)
|
55
|
+
task @name do
|
56
|
+
PuppetLint::OptParser.build
|
57
|
+
|
58
|
+
Array(@disable_checks).each do |check|
|
59
|
+
PuppetLint.configuration.send("disable_#{check}")
|
60
|
+
end
|
61
|
+
|
62
|
+
%w{with_filename fail_on_warnings error_level log_format with_context fix show_ignored relative}.each do |config|
|
63
|
+
value = instance_variable_get("@#{config}")
|
64
|
+
PuppetLint.configuration.send("#{config}=".to_sym, value) unless value.nil?
|
65
|
+
end
|
66
|
+
|
67
|
+
if PuppetLint.configuration.ignore_paths
|
68
|
+
@ignore_paths = PuppetLint.configuration.ignore_paths
|
69
|
+
end
|
70
|
+
|
71
|
+
RakeFileUtils.send(:verbose, true) do
|
72
|
+
linter = PuppetLint.new
|
73
|
+
matched_files = FileList[@pattern]
|
74
|
+
|
75
|
+
matched_files = matched_files.exclude(*@ignore_paths)
|
76
|
+
|
77
|
+
matched_files.to_a.each do |puppet_file|
|
78
|
+
linter.file = puppet_file
|
79
|
+
linter.run
|
80
|
+
linter.print_problems
|
81
|
+
end
|
82
|
+
abort if linter.errors? || (
|
83
|
+
linter.warnings? && PuppetLint.configuration.fail_on_warnings
|
84
|
+
)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
PuppetLint::RakeTask.new
|
data/puppet-lint.gemspec
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
$:.push File.expand_path("../lib", __FILE__)
|
2
|
+
require 'puppet-lint/version'
|
3
|
+
|
4
|
+
Gem::Specification.new do |s|
|
5
|
+
s.name = 'puppet-lint-halyard'
|
6
|
+
s.version = PuppetLint::VERSION
|
7
|
+
s.homepage = 'https://github.com/rodjek/puppet-lint/'
|
8
|
+
s.summary = 'Ensure your Puppet manifests conform with the Puppetlabs style guide'
|
9
|
+
s.description = 'Checks your Puppet manifests against the Puppetlabs
|
10
|
+
style guide and alerts you to any discrepancies.'
|
11
|
+
|
12
|
+
s.files = `git ls-files`.split("\n")
|
13
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
14
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
15
|
+
s.require_paths = ["lib"]
|
16
|
+
|
17
|
+
s.add_development_dependency 'rake', '~> 10.0'
|
18
|
+
s.add_development_dependency 'rspec', '~> 3.0'
|
19
|
+
s.add_development_dependency 'rspec-its', '~> 1.0'
|
20
|
+
s.add_development_dependency 'rspec-collection_matchers', '~> 1.0'
|
21
|
+
|
22
|
+
s.authors = ['Tim Sharpe']
|
23
|
+
s.email = 'tim@sharpe.id.au'
|
24
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
"test" # lint:ignore:double_quoted_strings
|
@@ -0,0 +1 @@
|
|
1
|
+
"test" # lint:ignore:double_quoted_strings for a good reason
|
@@ -0,0 +1 @@
|
|
1
|
+
class { 'apacheds': master => true' }
|
@@ -0,0 +1,326 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'rspec/mocks'
|
3
|
+
require 'optparse'
|
4
|
+
|
5
|
+
class CommandRun
|
6
|
+
attr_accessor :stdout, :stderr, :exitstatus
|
7
|
+
|
8
|
+
def initialize(args)
|
9
|
+
out = StringIO.new
|
10
|
+
err = StringIO.new
|
11
|
+
|
12
|
+
$stdout = out
|
13
|
+
$stderr = err
|
14
|
+
|
15
|
+
PuppetLint.configuration.defaults
|
16
|
+
@exitstatus = PuppetLint::Bin.new(args).run
|
17
|
+
PuppetLint.configuration.defaults
|
18
|
+
|
19
|
+
@stdout = out.string.strip
|
20
|
+
@stderr = err.string.strip
|
21
|
+
|
22
|
+
$stdout = STDOUT
|
23
|
+
$stderr = STDERR
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
describe PuppetLint::Bin do
|
28
|
+
subject do
|
29
|
+
if args.is_a? Array
|
30
|
+
sane_args = args
|
31
|
+
else
|
32
|
+
sane_args = [args]
|
33
|
+
end
|
34
|
+
|
35
|
+
CommandRun.new(sane_args)
|
36
|
+
end
|
37
|
+
|
38
|
+
context 'when running normally' do
|
39
|
+
let(:args) { 'spec/fixtures/test/manifests/init.pp' }
|
40
|
+
|
41
|
+
its(:exitstatus) { is_expected.to eq(0) }
|
42
|
+
end
|
43
|
+
|
44
|
+
context 'when running without arguments' do
|
45
|
+
let(:args) { [] }
|
46
|
+
|
47
|
+
its(:exitstatus) { is_expected.to eq(1) }
|
48
|
+
end
|
49
|
+
|
50
|
+
context 'when asked to display version' do
|
51
|
+
let(:args) { '--version' }
|
52
|
+
|
53
|
+
its(:exitstatus) { is_expected.to eq(0) }
|
54
|
+
its(:stdout) { is_expected.to eq("puppet-lint #{PuppetLint::VERSION}") }
|
55
|
+
end
|
56
|
+
|
57
|
+
context 'when passed multiple files' do
|
58
|
+
let(:args) { [
|
59
|
+
'spec/fixtures/test/manifests/warning.pp',
|
60
|
+
'spec/fixtures/test/manifests/fail.pp',
|
61
|
+
] }
|
62
|
+
|
63
|
+
its(:exitstatus) { is_expected.to eq(1) }
|
64
|
+
its(:stdout) { is_expected.to eq([
|
65
|
+
"#{args[0]} - WARNING: optional parameter listed before required parameter on line 2",
|
66
|
+
"#{args[1]} - ERROR: test::foo not in autoload module layout on line 2",
|
67
|
+
].join("\n")) }
|
68
|
+
end
|
69
|
+
|
70
|
+
context 'when passed a malformed file' do
|
71
|
+
let(:args) { 'spec/fixtures/test/manifests/malformed.pp' }
|
72
|
+
|
73
|
+
its(:exitstatus) { is_expected.to eq(1) }
|
74
|
+
its(:stdout) { is_expected.to eq('ERROR: Syntax error (try running `puppet parser validate <file>`) on line 1') }
|
75
|
+
end
|
76
|
+
|
77
|
+
context 'when limited to errors only' do
|
78
|
+
let(:args) { [
|
79
|
+
'--error-level', 'error',
|
80
|
+
'spec/fixtures/test/manifests/warning.pp',
|
81
|
+
'spec/fixtures/test/manifests/fail.pp',
|
82
|
+
] }
|
83
|
+
|
84
|
+
its(:exitstatus) { is_expected.to eq(1) }
|
85
|
+
its(:stdout) { is_expected.to match(/^#{args.last} - ERROR/) }
|
86
|
+
end
|
87
|
+
|
88
|
+
context 'when limited to warnings only' do
|
89
|
+
let(:args) { [
|
90
|
+
'--error-level', 'warning',
|
91
|
+
'spec/fixtures/test/manifests/warning.pp',
|
92
|
+
'spec/fixtures/test/manifests/fail.pp',
|
93
|
+
] }
|
94
|
+
|
95
|
+
its(:exitstatus) { is_expected.to eq(1) }
|
96
|
+
its(:stdout) { is_expected.to match(/WARNING/) }
|
97
|
+
its(:stdout) { is_expected.to_not match(/ERROR/) }
|
98
|
+
end
|
99
|
+
|
100
|
+
context 'when specifying a specific check to run' do
|
101
|
+
let(:args) { [
|
102
|
+
'--only-check', 'parameter_order',
|
103
|
+
'spec/fixtures/test/manifests/warning.pp',
|
104
|
+
'spec/fixtures/test/manifests/fail.pp',
|
105
|
+
] }
|
106
|
+
|
107
|
+
its(:exitstatus) { is_expected.to eq(0) }
|
108
|
+
its(:stdout) { is_expected.to_not match(/ERROR/) }
|
109
|
+
its(:stdout) { is_expected.to match(/WARNING/) }
|
110
|
+
end
|
111
|
+
|
112
|
+
context 'when asked to display filenames ' do
|
113
|
+
let(:args) { ['--with-filename', 'spec/fixtures/test/manifests/fail.pp'] }
|
114
|
+
|
115
|
+
its(:exitstatus) { is_expected.to eq(1) }
|
116
|
+
its(:stdout) { is_expected.to match(%r{^spec/fixtures/test/manifests/fail\.pp -}) }
|
117
|
+
end
|
118
|
+
|
119
|
+
context 'when not asked to fail on warnings' do
|
120
|
+
let(:args) { ['spec/fixtures/test/manifests/warning.pp'] }
|
121
|
+
|
122
|
+
its(:exitstatus) { is_expected.to eq(0) }
|
123
|
+
its(:stdout) { is_expected.to match(/optional parameter/) }
|
124
|
+
end
|
125
|
+
|
126
|
+
context 'when asked to provide context to problems' do
|
127
|
+
let(:args) { [
|
128
|
+
'--with-context',
|
129
|
+
'spec/fixtures/test/manifests/warning.pp',
|
130
|
+
] }
|
131
|
+
|
132
|
+
its(:exitstatus) { is_expected.to eq(0) }
|
133
|
+
its(:stdout) { is_expected.to eq([
|
134
|
+
'WARNING: optional parameter listed before required parameter on line 2',
|
135
|
+
'',
|
136
|
+
" define test::warning($foo='bar', $baz) { }",
|
137
|
+
' ^',
|
138
|
+
].join("\n"))
|
139
|
+
}
|
140
|
+
end
|
141
|
+
|
142
|
+
context 'when asked to fail on warnings' do
|
143
|
+
let(:args) { [
|
144
|
+
'--fail-on-warnings',
|
145
|
+
'spec/fixtures/test/manifests/warning.pp',
|
146
|
+
] }
|
147
|
+
|
148
|
+
its(:exitstatus) { is_expected.to eq(1) }
|
149
|
+
its(:stdout) { is_expected.to match(/optional parameter/) }
|
150
|
+
end
|
151
|
+
|
152
|
+
context 'when used with an invalid option' do
|
153
|
+
let(:args) { '--foo-bar-baz' }
|
154
|
+
|
155
|
+
its(:exitstatus) { is_expected.to eq(1) }
|
156
|
+
its(:stdout) { is_expected.to match(/invalid option/) }
|
157
|
+
end
|
158
|
+
|
159
|
+
context 'when passed a file that does not exist' do
|
160
|
+
let(:args) { 'spec/fixtures/test/manifests/enoent.pp' }
|
161
|
+
|
162
|
+
its(:exitstatus) { is_expected.to eq(1) }
|
163
|
+
its(:stdout) { is_expected.to match(/specified file does not exist/) }
|
164
|
+
end
|
165
|
+
|
166
|
+
context 'when passed a directory' do
|
167
|
+
let(:args) { 'spec/fixtures/' }
|
168
|
+
|
169
|
+
its(:exitstatus) { is_expected.to eq(1) }
|
170
|
+
its(:stdout) { is_expected.to match(/ERROR/) }
|
171
|
+
end
|
172
|
+
|
173
|
+
context 'when disabling a check' do
|
174
|
+
let(:args) { [
|
175
|
+
'--no-autoloader_layout',
|
176
|
+
'spec/fixtures/test/manifests/fail.pp'
|
177
|
+
] }
|
178
|
+
|
179
|
+
its(:exitstatus) { is_expected.to eq(0) }
|
180
|
+
its(:stdout) { is_expected.to eq("") }
|
181
|
+
end
|
182
|
+
|
183
|
+
context 'when changing the log format' do
|
184
|
+
context 'to print %{filename}' do
|
185
|
+
let(:args) { [
|
186
|
+
'--log-format', '%{filename}',
|
187
|
+
'spec/fixtures/test/manifests/fail.pp'
|
188
|
+
] }
|
189
|
+
|
190
|
+
its(:exitstatus) { is_expected.to eq(1) }
|
191
|
+
its(:stdout) { is_expected.to eq('fail.pp') }
|
192
|
+
end
|
193
|
+
|
194
|
+
context 'to print %{path}' do
|
195
|
+
let(:args) { [
|
196
|
+
'--log-format', '%{path}',
|
197
|
+
'spec/fixtures/test/manifests/fail.pp'
|
198
|
+
] }
|
199
|
+
|
200
|
+
its(:exitstatus) { is_expected.to eq(1) }
|
201
|
+
its(:stdout) { is_expected.to eq('spec/fixtures/test/manifests/fail.pp') }
|
202
|
+
end
|
203
|
+
|
204
|
+
context 'to print %{fullpath}' do
|
205
|
+
let(:args) { [
|
206
|
+
'--log-format', '%{fullpath}',
|
207
|
+
'spec/fixtures/test/manifests/fail.pp'
|
208
|
+
] }
|
209
|
+
|
210
|
+
its(:exitstatus) { is_expected.to eq(1) }
|
211
|
+
its(:stdout) {
|
212
|
+
is_expected.to match(%r{^/.+/spec/fixtures/test/manifests/fail\.pp$})
|
213
|
+
}
|
214
|
+
end
|
215
|
+
|
216
|
+
context 'to print %{linenumber}' do
|
217
|
+
let(:args) { [
|
218
|
+
'--log-format', '%{linenumber}',
|
219
|
+
'spec/fixtures/test/manifests/fail.pp'
|
220
|
+
] }
|
221
|
+
|
222
|
+
its(:exitstatus) { is_expected.to eq(1) }
|
223
|
+
its(:stdout) { is_expected.to eq('2') }
|
224
|
+
its(:stderr) { is_expected.to eq('DEPRECATION: Please use %{line} instead of %{linenumber}') }
|
225
|
+
end
|
226
|
+
|
227
|
+
context 'to print %{line}' do
|
228
|
+
let(:args) { [
|
229
|
+
'--log-format', '%{line}',
|
230
|
+
'spec/fixtures/test/manifests/fail.pp'
|
231
|
+
] }
|
232
|
+
|
233
|
+
its(:exitstatus) { is_expected.to eq(1) }
|
234
|
+
its(:stdout) { is_expected.to eq('2') }
|
235
|
+
end
|
236
|
+
|
237
|
+
context 'to print %{kind}' do
|
238
|
+
let(:args) { [
|
239
|
+
'--log-format', '%{kind}',
|
240
|
+
'spec/fixtures/test/manifests/fail.pp'
|
241
|
+
] }
|
242
|
+
|
243
|
+
its(:exitstatus) { is_expected.to eq(1) }
|
244
|
+
its(:stdout) { is_expected.to eq('error') }
|
245
|
+
end
|
246
|
+
|
247
|
+
context 'to print %{KIND}' do
|
248
|
+
let(:args) { [
|
249
|
+
'--log-format', '%{KIND}',
|
250
|
+
'spec/fixtures/test/manifests/fail.pp'
|
251
|
+
] }
|
252
|
+
|
253
|
+
its(:exitstatus) { is_expected.to eq(1) }
|
254
|
+
its(:stdout) { is_expected.to eq('ERROR') }
|
255
|
+
end
|
256
|
+
|
257
|
+
context 'to print %{check}' do
|
258
|
+
let(:args) { [
|
259
|
+
'--log-format', '%{check}',
|
260
|
+
'spec/fixtures/test/manifests/fail.pp'
|
261
|
+
] }
|
262
|
+
|
263
|
+
its(:exitstatus) { is_expected.to eq(1) }
|
264
|
+
its(:stdout) { is_expected.to eq('autoloader_layout') }
|
265
|
+
end
|
266
|
+
|
267
|
+
context 'to print %{message}' do
|
268
|
+
let(:args) { [
|
269
|
+
'--log-format', '%{message}',
|
270
|
+
'spec/fixtures/test/manifests/fail.pp'
|
271
|
+
] }
|
272
|
+
|
273
|
+
its(:exitstatus) { is_expected.to eq(1) }
|
274
|
+
its(:stdout) { is_expected.to eq('test::foo not in autoload module layout') }
|
275
|
+
end
|
276
|
+
end
|
277
|
+
|
278
|
+
context 'when hiding ignored problems' do
|
279
|
+
let(:args) { [
|
280
|
+
'spec/fixtures/test/manifests/ignore.pp'
|
281
|
+
] }
|
282
|
+
|
283
|
+
its(:exitstatus) { is_expected.to eq(0) }
|
284
|
+
its(:stdout) { is_expected.to_not match(/IGNORED/) }
|
285
|
+
end
|
286
|
+
|
287
|
+
context 'when showing ignored problems' do
|
288
|
+
let(:args) { [
|
289
|
+
'--show-ignored',
|
290
|
+
'spec/fixtures/test/manifests/ignore.pp',
|
291
|
+
] }
|
292
|
+
|
293
|
+
its(:exitstatus) { is_expected.to eq(0) }
|
294
|
+
its(:stdout) { is_expected.to match(/IGNORED/) }
|
295
|
+
end
|
296
|
+
|
297
|
+
context 'when showing ignored problems with a reason' do
|
298
|
+
let(:args) { [
|
299
|
+
'--show-ignored',
|
300
|
+
'spec/fixtures/test/manifests/ignore_reason.pp',
|
301
|
+
] }
|
302
|
+
|
303
|
+
its(:exitstatus) { is_expected.to eq(0) }
|
304
|
+
its(:stdout) { is_expected.to eq([
|
305
|
+
"IGNORED: double quoted string containing no variables on line 1",
|
306
|
+
" for a good reason",
|
307
|
+
].join("\n")) }
|
308
|
+
end
|
309
|
+
|
310
|
+
context 'ignoring multiple checks on a line' do
|
311
|
+
let(:args) { [
|
312
|
+
'spec/fixtures/test/manifests/ignore_multiple_line.pp',
|
313
|
+
] }
|
314
|
+
|
315
|
+
its(:exitstatus) { is_expected.to eq(0) }
|
316
|
+
end
|
317
|
+
|
318
|
+
context 'ignoring multiple checks in a block' do
|
319
|
+
let(:args) { [
|
320
|
+
'spec/fixtures/test/manifests/ignore_multiple_block.pp',
|
321
|
+
] }
|
322
|
+
|
323
|
+
its(:exitstatus) { is_expected.to eq(0) }
|
324
|
+
its(:stdout) { is_expected.to match(/^.*line 6$/) }
|
325
|
+
end
|
326
|
+
end
|