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.
Files changed (82) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +9 -0
  3. data/.travis.yml +10 -0
  4. data/Gemfile +3 -0
  5. data/LICENSE +20 -0
  6. data/README.md +210 -0
  7. data/Rakefile +14 -0
  8. data/bin/puppet-lint +7 -0
  9. data/lib/puppet-lint.rb +214 -0
  10. data/lib/puppet-lint/bin.rb +79 -0
  11. data/lib/puppet-lint/checkplugin.rb +176 -0
  12. data/lib/puppet-lint/checks.rb +91 -0
  13. data/lib/puppet-lint/configuration.rb +153 -0
  14. data/lib/puppet-lint/data.rb +521 -0
  15. data/lib/puppet-lint/lexer.rb +373 -0
  16. data/lib/puppet-lint/lexer/token.rb +101 -0
  17. data/lib/puppet-lint/monkeypatches.rb +2 -0
  18. data/lib/puppet-lint/monkeypatches/string_percent.rb +52 -0
  19. data/lib/puppet-lint/monkeypatches/string_prepend.rb +13 -0
  20. data/lib/puppet-lint/optparser.rb +118 -0
  21. data/lib/puppet-lint/plugins.rb +74 -0
  22. data/lib/puppet-lint/plugins/check_classes.rb +285 -0
  23. data/lib/puppet-lint/plugins/check_comments.rb +55 -0
  24. data/lib/puppet-lint/plugins/check_conditionals.rb +65 -0
  25. data/lib/puppet-lint/plugins/check_documentation.rb +31 -0
  26. data/lib/puppet-lint/plugins/check_nodes.rb +29 -0
  27. data/lib/puppet-lint/plugins/check_resources.rb +194 -0
  28. data/lib/puppet-lint/plugins/check_strings.rb +174 -0
  29. data/lib/puppet-lint/plugins/check_variables.rb +19 -0
  30. data/lib/puppet-lint/plugins/check_whitespace.rb +170 -0
  31. data/lib/puppet-lint/tasks/puppet-lint.rb +91 -0
  32. data/lib/puppet-lint/version.rb +3 -0
  33. data/puppet-lint.gemspec +24 -0
  34. data/spec/fixtures/test/manifests/fail.pp +2 -0
  35. data/spec/fixtures/test/manifests/ignore.pp +1 -0
  36. data/spec/fixtures/test/manifests/ignore_multiple_block.pp +6 -0
  37. data/spec/fixtures/test/manifests/ignore_multiple_line.pp +2 -0
  38. data/spec/fixtures/test/manifests/ignore_reason.pp +1 -0
  39. data/spec/fixtures/test/manifests/init.pp +3 -0
  40. data/spec/fixtures/test/manifests/malformed.pp +1 -0
  41. data/spec/fixtures/test/manifests/url_interpolation.pp +12 -0
  42. data/spec/fixtures/test/manifests/warning.pp +2 -0
  43. data/spec/puppet-lint/bin_spec.rb +326 -0
  44. data/spec/puppet-lint/configuration_spec.rb +56 -0
  45. data/spec/puppet-lint/ignore_overrides_spec.rb +109 -0
  46. data/spec/puppet-lint/lexer/token_spec.rb +18 -0
  47. data/spec/puppet-lint/lexer_spec.rb +783 -0
  48. data/spec/puppet-lint/plugins/check_classes/autoloader_layout_spec.rb +105 -0
  49. data/spec/puppet-lint/plugins/check_classes/class_inherits_from_params_class_spec.rb +35 -0
  50. data/spec/puppet-lint/plugins/check_classes/inherits_across_namespaces_spec.rb +33 -0
  51. data/spec/puppet-lint/plugins/check_classes/names_containing_dash_spec.rb +45 -0
  52. data/spec/puppet-lint/plugins/check_classes/nested_classes_or_defines_spec.rb +76 -0
  53. data/spec/puppet-lint/plugins/check_classes/parameter_order_spec.rb +73 -0
  54. data/spec/puppet-lint/plugins/check_classes/right_to_left_relationship_spec.rb +25 -0
  55. data/spec/puppet-lint/plugins/check_classes/variable_scope_spec.rb +196 -0
  56. data/spec/puppet-lint/plugins/check_comments/slash_comments_spec.rb +45 -0
  57. data/spec/puppet-lint/plugins/check_comments/star_comments_spec.rb +84 -0
  58. data/spec/puppet-lint/plugins/check_conditionals/case_without_default_spec.rb +98 -0
  59. data/spec/puppet-lint/plugins/check_conditionals/selector_inside_resource_spec.rb +36 -0
  60. data/spec/puppet-lint/plugins/check_documentation/documentation_spec.rb +52 -0
  61. data/spec/puppet-lint/plugins/check_nodes/unquoted_node_name_spec.rb +146 -0
  62. data/spec/puppet-lint/plugins/check_resources/duplicate_params_spec.rb +100 -0
  63. data/spec/puppet-lint/plugins/check_resources/ensure_first_param_spec.rb +55 -0
  64. data/spec/puppet-lint/plugins/check_resources/ensure_not_symlink_target_spec.rb +89 -0
  65. data/spec/puppet-lint/plugins/check_resources/file_mode_spec.rb +113 -0
  66. data/spec/puppet-lint/plugins/check_resources/unquoted_file_mode_spec.rb +45 -0
  67. data/spec/puppet-lint/plugins/check_resources/unquoted_resource_title_spec.rb +216 -0
  68. data/spec/puppet-lint/plugins/check_strings/double_quoted_strings_spec.rb +199 -0
  69. data/spec/puppet-lint/plugins/check_strings/only_variable_string_spec.rb +114 -0
  70. data/spec/puppet-lint/plugins/check_strings/puppet_url_without_modules_spec.rb +62 -0
  71. data/spec/puppet-lint/plugins/check_strings/quoted_booleans_spec.rb +129 -0
  72. data/spec/puppet-lint/plugins/check_strings/single_quote_string_with_variables_spec.rb +17 -0
  73. data/spec/puppet-lint/plugins/check_strings/variables_not_enclosed_spec.rb +73 -0
  74. data/spec/puppet-lint/plugins/check_variables/variable_contains_dash_spec.rb +37 -0
  75. data/spec/puppet-lint/plugins/check_whitespace/2sp_soft_tabs_spec.rb +21 -0
  76. data/spec/puppet-lint/plugins/check_whitespace/80chars_spec.rb +54 -0
  77. data/spec/puppet-lint/plugins/check_whitespace/arrow_alignment_spec.rb +524 -0
  78. data/spec/puppet-lint/plugins/check_whitespace/hard_tabs_spec.rb +45 -0
  79. data/spec/puppet-lint/plugins/check_whitespace/trailing_whitespace_spec.rb +101 -0
  80. data/spec/puppet-lint_spec.rb +20 -0
  81. data/spec/spec_helper.rb +129 -0
  82. metadata +229 -0
@@ -0,0 +1,79 @@
1
+ require 'puppet-lint/optparser'
2
+
3
+ # Internal: The logic of the puppet-lint bin script, contained in a class for
4
+ # ease of testing.
5
+ class PuppetLint::Bin
6
+ # Public: Initialise a new PuppetLint::Bin.
7
+ #
8
+ # args - An Array of command line argument Strings to be passed to the option
9
+ # parser.
10
+ #
11
+ # Examples
12
+ #
13
+ # PuppetLint::Bin.new(ARGV).run
14
+ def initialize(args)
15
+ @args = args
16
+ end
17
+
18
+ # Public: Run puppet-lint as a command line tool.
19
+ #
20
+ # Returns an Integer exit code to be passed back to the shell.
21
+ def run
22
+ opts = PuppetLint::OptParser.build
23
+
24
+ begin
25
+ opts.parse!(@args)
26
+ rescue OptionParser::InvalidOption
27
+ puts "puppet-lint: #{$!.message}"
28
+ puts "puppet-lint: try 'puppet-lint --help' for more information"
29
+ return 1
30
+ end
31
+
32
+ if PuppetLint.configuration.display_version
33
+ puts "puppet-lint #{PuppetLint::VERSION}"
34
+ return 0
35
+ end
36
+
37
+ if @args[0].nil?
38
+ puts "puppet-lint: no file specified"
39
+ puts "puppet-lint: try 'puppet-lint --help' for more information"
40
+ return 1
41
+ end
42
+
43
+ begin
44
+ path = @args[0]
45
+ if File.directory?(path)
46
+ path = Dir.glob("#{path}/**/*.pp")
47
+ else
48
+ path = @args
49
+ end
50
+
51
+ if path.length > 1
52
+ PuppetLint.configuration.with_filename = true
53
+ end
54
+
55
+ return_val = 0
56
+ path.each do |f|
57
+ l = PuppetLint.new
58
+ l.file = f
59
+ l.run
60
+ l.print_problems
61
+ if l.errors? or (l.warnings? and PuppetLint.configuration.fail_on_warnings)
62
+ return_val = 1
63
+ end
64
+
65
+ if PuppetLint.configuration.fix && !l.problems.any? { |e| e[:check] == :syntax }
66
+ File.open(f, 'w') do |fd|
67
+ fd.write l.manifest
68
+ end
69
+ end
70
+ end
71
+ return return_val
72
+
73
+ rescue PuppetLint::NoCodeError
74
+ puts "puppet-lint: no file specified or specified file does not exist"
75
+ puts "puppet-lint: try 'puppet-lint --help' for more information"
76
+ return 1
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,176 @@
1
+ # Public: A class that contains and provides information for the puppet-lint
2
+ # checks.
3
+ #
4
+ # This class should not be used directly, but instead should be inherited.
5
+ #
6
+ # Examples
7
+ #
8
+ # class PuppetLint::Plugin::CheckFoo < PuppetLint::CheckPlugin
9
+ # end
10
+ class PuppetLint::CheckPlugin
11
+ # Internal: Initialise a new PuppetLint::CheckPlugin.
12
+ def initialize
13
+ @problems = []
14
+ end
15
+
16
+ # Internal: Check the manifest for problems and filter out any problems that
17
+ # should be ignored.
18
+ #
19
+ # Returns an Array of problem Hashes.
20
+ def run
21
+ check
22
+
23
+ @problems.each do |problem|
24
+ if PuppetLint::Data.ignore_overrides[problem[:check]].has_key?(problem[:line])
25
+ problem[:kind] = :ignored
26
+ problem[:reason] = PuppetLint::Data.ignore_overrides[problem[:check]][problem[:line]]
27
+ next
28
+ end
29
+ end
30
+
31
+ @problems
32
+ end
33
+
34
+ # Internal: Fix any problems the check plugin has detected.
35
+ #
36
+ # Returns an Array of problem Hashes.
37
+ def fix_problems
38
+ @problems.reject { |problem| problem[:kind] == :ignored }.each do |problem|
39
+ if self.respond_to?(:fix)
40
+ begin
41
+ fix(problem)
42
+ rescue PuppetLint::NoFix
43
+ # noop
44
+ else
45
+ problem[:kind] = :fixed
46
+ end
47
+ end
48
+ end
49
+
50
+ @problems
51
+ end
52
+
53
+ private
54
+
55
+ # Public: Provides the tokenised manifest to the check plugins.
56
+ #
57
+ # Returns an Array of PuppetLint::Lexer::Token objects.
58
+ def tokens
59
+ PuppetLint::Data.tokens
60
+ end
61
+
62
+ # Public: Provides the resource titles to the check plugins.
63
+ #
64
+ # Returns an Array of PuppetLint::Lexer::Token objects.
65
+ def title_tokens
66
+ PuppetLint::Data.title_tokens
67
+ end
68
+
69
+ # Public: Provides positional information for any resource declarations in
70
+ # the tokens array to the check plugins.
71
+ #
72
+ # Returns an Array of Hashes containing the position information.
73
+ def resource_indexes
74
+ PuppetLint::Data.resource_indexes
75
+ end
76
+
77
+ # Public: Provides positional information for any class definitions in the
78
+ # tokens array to the check plugins.
79
+ #
80
+ # Returns an Array of Hashes containing the position information.
81
+ def class_indexes
82
+ PuppetLint::Data.class_indexes
83
+ end
84
+
85
+ # Public: Provides positional information for any defined type definitions in
86
+ # the tokens array to the check plugins.
87
+ #
88
+ # Returns an Array of Hashes containing the position information.
89
+ def defined_type_indexes
90
+ PuppetLint::Data.defined_type_indexes
91
+ end
92
+
93
+ # Public: Provides positional information for any node definitions in the
94
+ # tokens array to the check plugins.
95
+ #
96
+ # Returns an Array of Hashes containing the position information.
97
+ def node_indexes
98
+ PuppetLint::Data.node_indexes
99
+ end
100
+
101
+ # Public: Provides the expanded path of the file being analysed to check
102
+ # plugins.
103
+ #
104
+ # Returns the String path.
105
+ def fullpath
106
+ PuppetLint::Data.fullpath
107
+ end
108
+
109
+ # Public: Provides the path of the file being analysed as it was provided to
110
+ # puppet-lint to the check plugins.
111
+ #
112
+ # Returns the String path.
113
+ def path
114
+ PuppetLint::Data.path
115
+ end
116
+
117
+ # Public: Provides the name of the file being analysed to the check plugins.
118
+ #
119
+ # Returns the String file name.
120
+ def filename
121
+ PuppetLint::Data.filename
122
+ end
123
+
124
+ # Public: Provides a list of formatting tokens to the check plugins.
125
+ #
126
+ # Returns an Array of Symbol token types.
127
+ def formatting_tokens
128
+ PuppetLint::Data.formatting_tokens
129
+ end
130
+
131
+ # Public: Provides a list of manifest lines to the check plugins.
132
+ #
133
+ # Returns an Array of manifest lines.
134
+ def manifest_lines
135
+ PuppetLint::Data.manifest_lines
136
+ end
137
+
138
+ # Internal: Prepare default problem report information.
139
+ #
140
+ # Returns a Hash of default problem information.
141
+ def default_info
142
+ @default_info ||= {
143
+ :check => self.class.const_get('NAME'),
144
+ :fullpath => fullpath,
145
+ :path => path,
146
+ :filename => filename,
147
+ }
148
+ end
149
+
150
+ # Public: Report a problem with the manifest being checked.
151
+ #
152
+ # kind - The Symbol problem type (:warning or :error).
153
+ # problem - A Hash containing the attributes of the problem
154
+ # :message - The String message describing the problem.
155
+ # :line - The Integer line number of the location of the problem.
156
+ # :column - The Integer column number of the location of the problem.
157
+ # :check - The Symbol name of the check that detected the problem.
158
+ #
159
+ # Returns nothing.
160
+ def notify(kind, problem)
161
+ problem[:kind] = kind
162
+ problem.merge!(default_info) { |key, v1, v2| v1 }
163
+
164
+ unless [:warning, :error, :fixed].include? kind
165
+ raise ArgumentError, "unknown value passed for kind"
166
+ end
167
+
168
+ [:message, :line, :column, :check].each do |attr|
169
+ unless problem.has_key? attr
170
+ raise ArgumentError, "problem hash must contain #{attr.inspect}"
171
+ end
172
+ end
173
+
174
+ @problems << problem
175
+ end
176
+ end
@@ -0,0 +1,91 @@
1
+ require 'puppet-lint/checkplugin'
2
+
3
+ # Internal: Various methods that orchestrate the actions of the puppet-lint
4
+ # check plugins.
5
+ class PuppetLint::Checks
6
+ # Public: Get an Array of problem Hashes.
7
+ attr_accessor :problems
8
+
9
+ # Public: Initialise a new PuppetLint::Checks object.
10
+ def initialize
11
+ @problems = []
12
+ end
13
+
14
+ # Internal: Tokenise the manifest code and prepare it for checking.
15
+ #
16
+ # path - The path to the file as passed to puppet-lint as a String.
17
+ # content - The String manifest code to be checked.
18
+ #
19
+ # Returns nothing.
20
+ def load_data(path, content)
21
+ lexer = PuppetLint::Lexer.new
22
+ PuppetLint::Data.path = path
23
+ PuppetLint::Data.manifest_lines = content.split("\n", -1)
24
+ begin
25
+ PuppetLint::Data.tokens = lexer.tokenise(content)
26
+ PuppetLint::Data.parse_control_comments
27
+ rescue PuppetLint::LexerError => e
28
+ problems << {
29
+ :kind => :error,
30
+ :check => :syntax,
31
+ :message => 'Syntax error (try running `puppet parser validate <file>`)',
32
+ :line => e.line_no,
33
+ :column => e.column,
34
+ :fullpath => PuppetLint::Data.fullpath,
35
+ :path => PuppetLint::Data.path,
36
+ :filename => PuppetLint::Data.filename,
37
+ }
38
+ PuppetLint::Data.tokens = []
39
+ end
40
+ end
41
+
42
+ # Internal: Run the lint checks over the manifest code.
43
+ #
44
+ # fileinfo - A Hash containing the following:
45
+ # :fullpath - The expanded path to the file as a String.
46
+ # :filename - The name of the file as a String.
47
+ # :path - The original path to the file as passed to puppet-lint as
48
+ # a String.
49
+ # data - The String manifest code to be checked.
50
+ #
51
+ # Returns an Array of problem Hashes.
52
+ def run(fileinfo, data)
53
+ load_data(fileinfo, data)
54
+
55
+ checks_run = []
56
+ enabled_checks.each do |check|
57
+ klass = PuppetLint.configuration.check_object[check].new
58
+ problems = klass.run
59
+
60
+ if PuppetLint.configuration.fix
61
+ checks_run << klass
62
+ else
63
+ @problems.concat(problems)
64
+ end
65
+ end
66
+
67
+ checks_run.each do |check|
68
+ @problems.concat(check.fix_problems)
69
+ end
70
+
71
+ @problems
72
+ end
73
+
74
+ # Internal: Get a list of checks that have not been disabled.
75
+ #
76
+ # Returns an Array of String check names.
77
+ def enabled_checks
78
+ @enabled_checks ||= Proc.new do
79
+ PuppetLint.configuration.checks.select { |check|
80
+ PuppetLint.configuration.send("#{check}_enabled?")
81
+ }
82
+ end.call
83
+ end
84
+
85
+ # Internal: Render the fixed manifest.
86
+ #
87
+ # Returns the manifest as a String.
88
+ def manifest
89
+ PuppetLint::Data.tokens.map { |t| t.to_manifest }.join('')
90
+ end
91
+ end
@@ -0,0 +1,153 @@
1
+ class PuppetLint
2
+ # Public: A singleton class to store the running configuration of
3
+ # puppet-lint.
4
+ class Configuration
5
+ # Internal: Add helper methods for a new check to the
6
+ # PuppetLint::Configuration object.
7
+ #
8
+ # check - The String name of the check.
9
+ #
10
+ # Returns nothing.
11
+ #
12
+ # Signature
13
+ #
14
+ # <check>_enabled?
15
+ # disable_<check>
16
+ # enable_<check>
17
+ def self.add_check(check)
18
+ # Public: Determine if the named check is enabled.
19
+ #
20
+ # Returns true if the check is enabled, otherwise return false.
21
+ define_method("#{check}_enabled?") do
22
+ settings["#{check}_disabled"] == true ? false : true
23
+ end
24
+
25
+ # Public: Disable the named check.
26
+ #
27
+ # Returns nothing.
28
+ define_method("disable_#{check}") do
29
+ settings["#{check}_disabled"] = true
30
+ end
31
+
32
+ # Public: Enable the named check.
33
+ #
34
+ # Returns nothing.
35
+ define_method("enable_#{check}") do
36
+ settings["#{check}_disabled"] = false
37
+ end
38
+ end
39
+
40
+ # Public: Catch situations where options are being set for the first time
41
+ # and create the necessary methods to get & set the option in the future.
42
+ #
43
+ # args - An Array of values to set the option to.
44
+ # method - The String name of the option.
45
+ # block - Unused.
46
+ #
47
+ # Returns nothing.
48
+ #
49
+ # Signature
50
+ #
51
+ # <option>=(value)
52
+ def method_missing(method, *args, &block)
53
+ if method.to_s =~ /^(\w+)=$/
54
+ option = $1
55
+ add_option(option.to_s) if settings[option].nil?
56
+ settings[option] = args[0]
57
+ else
58
+ nil
59
+ end
60
+ end
61
+
62
+ # Internal: Add options to the PuppetLint::Configuration object from inside
63
+ # the class.
64
+ #
65
+ # option - The String name of the option.
66
+ #
67
+ # Returns nothing.
68
+ #
69
+ # Signature
70
+ #
71
+ # <option>
72
+ # <option>=(value)
73
+ def add_option(option)
74
+ self.class.add_option(option)
75
+ end
76
+
77
+ # Public: Add an option to the PuppetLint::Configuration object from
78
+ # outside the class.
79
+ #
80
+ # option - The String name of the option.
81
+ #
82
+ # Returns nothing.
83
+ #
84
+ # Signature
85
+ #
86
+ # <option>
87
+ # <option>=(value)
88
+ def self.add_option(option)
89
+ # Public: Set the value of the named option.
90
+ #
91
+ # value - The value to set the option to.
92
+ #
93
+ # Returns nothing.
94
+ define_method("#{option}=") do |value|
95
+ settings[option] = value
96
+ end
97
+
98
+ # Public: Get the value of the named option.
99
+ #
100
+ # Returns the value of the option.
101
+ define_method(option) do
102
+ settings[option]
103
+ end
104
+ end
105
+
106
+ # Internal: Register a new check.
107
+ #
108
+ # check - The String name of the check
109
+ # klass - The Class containing the check logic.
110
+ #
111
+ # Returns nothing.
112
+ def add_check(check, klass)
113
+ self.class.add_check(check)
114
+ check_object[check] = klass
115
+ end
116
+
117
+ # Internal: Access the internal storage for settings.
118
+ #
119
+ # Returns a Hash containing all the settings.
120
+ def settings
121
+ @settings ||= {}
122
+ end
123
+
124
+ # Internal: Access the internal storage for check method blocks.
125
+ #
126
+ # Returns a Hash containing all the check blocks.
127
+ def check_object
128
+ @check_object ||= {}
129
+ end
130
+
131
+ # Public: Get a list of all the defined checks.
132
+ #
133
+ # Returns an Array of String check names.
134
+ def checks
135
+ check_object.keys
136
+ end
137
+
138
+ # Public: Clear the PuppetLint::Configuration storage and set some sane
139
+ # default values.
140
+ #
141
+ # Returns nothing.
142
+ def defaults
143
+ settings.clear
144
+ self.with_filename = false
145
+ self.fail_on_warnings = false
146
+ self.error_level = :all
147
+ self.log_format = ''
148
+ self.with_context = false
149
+ self.fix = false
150
+ self.show_ignored = false
151
+ end
152
+ end
153
+ end