puppet-syntax 2.0.0 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,15 +1,27 @@
1
1
  ---
2
2
  language: ruby
3
+ # Workaround https://github.com/bundler/bundler/issues/3558
4
+ before_install: gem install bundler
3
5
  script: bundle exec rake
4
6
  rvm:
5
7
  - 1.9.3
8
+ - 2.1.6
6
9
  env:
7
10
  - PUPPET_VERSION="~> 3.0.0"
8
11
  - PUPPET_VERSION="~> 3.1.0"
9
12
  - PUPPET_VERSION="~> 3.2.0"
10
13
  - PUPPET_VERSION="~> 3.4.0"
11
14
  - PUPPET_VERSION="~> 3.7.3"
15
+ - PUPPET_VERSION="~> 4.2.0"
16
+ - PUPPET_VERSION="~> 4.3.0"
12
17
  - PUPPET_VERSION=">= 0"
13
18
  matrix:
19
+ exclude:
20
+ - rvm: 2.1.6
21
+ env: PUPPET_VERSION="~> 3.2.0"
22
+ - rvm: 2.1.6
23
+ env: PUPPET_VERSION="~> 3.1.0"
24
+ - rvm: 2.1.6
25
+ env: PUPPET_VERSION="~> 3.0.0"
14
26
  allow_failures:
15
27
  - env: PUPPET_VERSION=">= 0"
data/CHANGELOG CHANGED
@@ -1,3 +1,10 @@
1
+ 2016-01-18 Release 2.1.0
2
+ - Support Puppet 4. Many thanks to @DavidS
3
+ - Support validation of EPP templates. Thanks to @trlinkin
4
+ - Test improvements and refactoring, including Travis CI tests against Puppet 4. Thanks to @trlinkin
5
+ - Don't error when a tag metaparameter is present. Thank you @dhardy92
6
+ - Report the filename of invalid hiera data files. Thanks @danzilio
7
+
1
8
  2015-02-25 Release 2.0.0
2
9
  - Removed support for Puppet version 2.7.x
3
10
  - New option, fail_on_deprecation_notices, which defaults to true (compatible
@@ -10,6 +10,6 @@ module PuppetSyntax
10
10
  @fail_on_deprecation_notices = true
11
11
 
12
12
  class << self
13
- attr_accessor :exclude_paths, :future_parser, :hieradata_paths, :fail_on_deprecation_notices
13
+ attr_accessor :exclude_paths, :future_parser, :hieradata_paths, :fail_on_deprecation_notices, :epp_only
14
14
  end
15
15
  end
@@ -11,7 +11,7 @@ module PuppetSyntax
11
11
  begin
12
12
  YAML.load_file(hiera_file)
13
13
  rescue Exception => error
14
- errors << error
14
+ errors << "ERROR: Failed to parse #{hiera_file}: #{error}"
15
15
  end
16
16
  end
17
17
 
@@ -36,6 +36,11 @@ module PuppetSyntax
36
36
  e =~ /^You cannot collect( exported resources)? without storeconfigs being set/
37
37
  }
38
38
 
39
+ # tag parameter in class raise warnings notice in output that prevent from succeed
40
+ output.reject! { |e|
41
+ e =~ /^tag is a metaparam; this value will inherit to all contained resources in the /
42
+ }
43
+
39
44
  deprecations = output.select { |e|
40
45
  e =~ /^Deprecation notice:|is deprecated/
41
46
  }
@@ -48,7 +53,7 @@ module PuppetSyntax
48
53
 
49
54
  private
50
55
  def validate_manifest(file)
51
- Puppet[:parser] = 'future' if PuppetSyntax.future_parser
56
+ Puppet[:parser] = 'future' if PuppetSyntax.future_parser and Puppet::PUPPETVERSION.to_i < 4
52
57
  Puppet::Face[:parser, :current].validate(file)
53
58
  end
54
59
  end
@@ -30,6 +30,12 @@ to puppetlabs_spec_helper >= 0.8.0 which now uses puppet-syntax.
30
30
 
31
31
  desc 'Syntax check Puppet manifests'
32
32
  task :manifests do |t|
33
+ if Puppet::PUPPETVERSION.to_i >= 4 and PuppetSyntax.future_parser
34
+ info <<-EOS
35
+ [INFO] Puppet 4 has been detected and `future_parser` has been set to
36
+ 'true'. The `future_parser setting will be ignored.
37
+ EOS
38
+ end
33
39
  $stderr.puts "---> #{t.name}"
34
40
  files = FileList["**/*.pp"]
35
41
  files.reject! { |f| File.directory?(f) }
@@ -1,4 +1,5 @@
1
1
  require 'erb'
2
+ require 'puppet'
2
3
  require 'stringio'
3
4
 
4
5
  module PuppetSyntax
@@ -10,19 +11,11 @@ module PuppetSyntax
10
11
  $stderr = warnings = StringIO.new()
11
12
  errors = []
12
13
 
13
- filelist.each do |erb_file|
14
- begin
15
- erb = ERB.new(File.read(erb_file), nil, '-')
16
- erb.filename = erb_file
17
- erb.result
18
- rescue NameError
19
- # This is normal because we don't have the variables that would
20
- # ordinarily be bound by the parent Puppet manifest.
21
- rescue TypeError
22
- # This is normal because we don't have the variables that would
23
- # ordinarily be bound by the parent Puppet manifest.
24
- rescue SyntaxError => error
25
- errors << error
14
+ filelist.each do |file|
15
+ if File.extname(file) == '.epp' or PuppetSyntax.epp_only
16
+ errors.concat validate_epp(file)
17
+ else
18
+ errors.concat validate_erb(file)
26
19
  end
27
20
  end
28
21
 
@@ -32,5 +25,42 @@ module PuppetSyntax
32
25
 
33
26
  errors
34
27
  end
28
+
29
+ def validate_epp(filename)
30
+ if Puppet::PUPPETVERSION.to_i < 4
31
+ raise "Cannot validate EPP without Puppet 4"
32
+ end
33
+
34
+ require 'puppet/pops'
35
+ errors = []
36
+ begin
37
+ parser = Puppet::Pops::Parser::EvaluatingParser::EvaluatingEppParser.new()
38
+ parser.parse_file(filename)
39
+ rescue => detail
40
+ errors << detail
41
+ end
42
+
43
+ errors
44
+ end
45
+
46
+ def validate_erb(filename)
47
+ errors = []
48
+
49
+ begin
50
+ erb = ERB.new(File.read(filename), nil, '-')
51
+ erb.filename = filename
52
+ erb.result
53
+ rescue NameError => error
54
+ # This is normal because we don't have the variables that would
55
+ # ordinarily be bound by the parent Puppet manifest.
56
+ rescue TypeError
57
+ # This is normal because we don't have the variables that would
58
+ # ordinarily be bound by the parent Puppet manifest.
59
+ rescue SyntaxError => error
60
+ errors << error
61
+ end
62
+
63
+ errors
64
+ end
35
65
  end
36
66
  end
@@ -1,3 +1,3 @@
1
1
  module PuppetSyntax
2
- VERSION = "2.0.0"
2
+ VERSION = "2.1.0"
3
3
  end
@@ -0,0 +1,5 @@
1
+ class tag_parameter_test ($tag=undef){
2
+ notify { 'tag_should pass':
3
+ message => 'with flying colours',
4
+ }
5
+ }
@@ -0,0 +1,3 @@
1
+ This is plain text
2
+ <% This is not valid EPP %>
3
+ This is also plain text
@@ -0,0 +1,3 @@
1
+ This is plain text
2
+ <% } %>
3
+ This is also plain text
@@ -0,0 +1,3 @@
1
+ <%# VALID COMMENT %>
2
+ <% $valid = 'valid' -%>
3
+ This is a <%= $valid %> template.
@@ -0,0 +1,3 @@
1
+ <%# VALID COMMENT %>
2
+ <% $valid = 'valid' -%>
3
+ This is a <%= $valid %> template.
@@ -14,14 +14,9 @@ describe PuppetSyntax::Hiera do
14
14
  end
15
15
 
16
16
  it "should return an error from invalid YAML" do
17
- case RUBY_VERSION
18
- when /1.8/
19
- files = fixture_hiera('hiera_bad_18.yaml')
20
- expected = /syntax error on line 3, col -1: `'/
21
- else
22
- files = fixture_hiera('hiera_bad.yaml')
23
- expected = /scanning a directive at line 1 column 1/
24
- end
17
+ hiera_yaml = RUBY_VERSION =~ /1.8/ ? 'hiera_bad_18.yaml' : 'hiera_bad.yaml'
18
+ files = fixture_hiera(hiera_yaml)
19
+ expected = /ERROR: Failed to parse #{files[0]}:/
25
20
  res = subject.check(files)
26
21
  expect(res.size).to be == 1
27
22
  expect(res.first).to match(expected)
@@ -16,13 +16,27 @@ describe PuppetSyntax::Manifests do
16
16
  expect(has_errors).to eq(false)
17
17
  end
18
18
 
19
+ it 'should return nothing from a valid file with a class using tag parameter' do
20
+ files = fixture_manifests('tag_notice.pp')
21
+ output, has_errors = subject.check(files)
22
+
23
+ expect(output).to eq([])
24
+ expect(has_errors).to eq(false)
25
+ end
26
+
19
27
  it 'should return an error from an invalid file' do
20
28
  files = fixture_manifests('fail_error.pp')
21
29
  output, has_errors = subject.check(files)
22
30
 
23
- expect(output.size).to eq(1)
24
- expect(output[0]).to match(/Syntax error at .*:3$/)
25
- expect(has_errors).to eq(true)
31
+ if Puppet::PUPPETVERSION.to_i >= 4
32
+ expect(output.size).to eq(3)
33
+ expect(output[2]).to match(/Found 2 errors. Giving up/)
34
+ expect(has_errors).to eq(true)
35
+ else
36
+ expect(output.size).to eq(1)
37
+ expect(output[0]).to match(/Syntax error at .*:3$/)
38
+ expect(has_errors).to eq(true)
39
+ end
26
40
  end
27
41
 
28
42
  it 'should return a warning from an invalid file' do
@@ -30,9 +44,10 @@ describe PuppetSyntax::Manifests do
30
44
  output, has_errors = subject.check(files)
31
45
 
32
46
  expect(output.size).to eq(2)
33
- expect(output[0]).to match(/Unrecognised escape sequence '\\\[' .* at line 3$/)
34
- expect(output[1]).to match(/Unrecognised escape sequence '\\\]' .* at line 3$/)
35
47
  expect(has_errors).to eq(true)
48
+
49
+ expect(output[0]).to match(/Unrecogni(s|z)ed escape sequence '\\\['/)
50
+ expect(output[1]).to match(/Unrecogni(s|z)ed escape sequence '\\\]'/)
36
51
  end
37
52
 
38
53
  it 'should ignore warnings about storeconfigs' do
@@ -56,18 +71,37 @@ describe PuppetSyntax::Manifests do
56
71
  files = fixture_manifests(['fail_error.pp', 'fail_warning.pp'])
57
72
  output, has_errors = subject.check(files)
58
73
 
59
- expect(output.size).to eq(3)
60
- expect(output[0]).to match(/Syntax error at '\}' .*:3$/)
61
- expect(output[1]).to match(/Unrecognised escape sequence '\\\[' .* at line 3$/)
62
- expect(output[2]).to match(/Unrecognised escape sequence '\\\]' .* at line 3$/)
63
74
  expect(has_errors).to eq(true)
75
+ if Puppet::PUPPETVERSION.to_i >= 4
76
+ expect(output.size).to eq(5)
77
+ expect(output[0]).to match(/This Name has no effect. A Host Class Definition can not end with a value-producing expression without other effect at \S*\/fail_error.pp:2:32$/)
78
+ expect(output[1]).to match(/This Name has no effect. A value(-producing expression without other effect may only be placed last in a block\/sequence| was produced and then forgotten.*) at \S*\/fail_error.pp:2:3$/)
79
+ expect(output[2]).to match('Found 2 errors. Giving up')
80
+ expect(output[3]).to match(/Unrecogni(s|z)ed escape sequence '\\\['/)
81
+ expect(output[4]).to match(/Unrecogni(s|z)ed escape sequence '\\\]'/)
82
+ else
83
+ expect(output.size).to eq(3)
84
+ expect(output[0]).to match(/Syntax error at '\}' .*:3$/)
85
+ expect(output[1]).to match(/Unrecogni(s|z)ed escape sequence '\\\['/)
86
+ expect(output[2]).to match(/Unrecogni(s|z)ed escape sequence '\\\]'/)
87
+ end
64
88
  end
65
89
 
66
90
  describe 'deprecation notices' do
67
- # These tests should fail in Puppet 4, but we need to wait for the release
68
- # before we'll know exactly how to test it.
69
- if Puppet::Util::Package.versioncmp(Puppet.version, '3.7') >= 0
70
- context 'on puppet >= 3.7' do
91
+ case Puppet.version.to_f
92
+ when 4.0..4.99
93
+ context 'on puppet 4.0.0 and above' do
94
+ it 'should instead be failures' do
95
+ files = fixture_manifests('deprecation_notice.pp')
96
+ output, has_errors = subject.check(files)
97
+
98
+ expect(has_errors).to eq(true)
99
+ expect(output.size).to eq(1)
100
+ expect(output[0]).to match (/Node inheritance is not supported in Puppet >= 4.0.0/)
101
+ end
102
+ end
103
+ when 3.7, 3.8
104
+ context 'on puppet 3.7 and 3.8' do
71
105
  it 'should return deprecation notices as warnings' do
72
106
  files = fixture_manifests('deprecation_notice.pp')
73
107
  output, has_errors = subject.check(files)
@@ -78,7 +112,7 @@ describe PuppetSyntax::Manifests do
78
112
  expect(output[1]).to match(/Deprecation notice:/)
79
113
  end
80
114
  end
81
- elsif Puppet::Util::Package.versioncmp(Puppet.version, '3.5') >= 0
115
+ when 3.5, 3.6
82
116
  context 'on puppet 3.5 and 3.6' do
83
117
  it 'should return deprecation notices as warnings' do
84
118
  files = fixture_manifests('deprecation_notice.pp')
@@ -89,8 +123,8 @@ describe PuppetSyntax::Manifests do
89
123
  expect(output[0]).to match(/The use of 'import' is deprecated/)
90
124
  end
91
125
  end
92
- elsif Puppet::Util::Package.versioncmp(Puppet.version, '3.5') < 0
93
- context 'on puppet < 3.5' do
126
+ when 3.0..3.4
127
+ context 'on puppet 3.0 to 3.4' do
94
128
  it 'should not print deprecation notices' do
95
129
  files = fixture_manifests('deprecation_notice.pp')
96
130
  output, has_errors = subject.check(files)
@@ -104,15 +138,27 @@ describe PuppetSyntax::Manifests do
104
138
 
105
139
  describe 'future_parser' do
106
140
  context 'future_parser = false (default)' do
107
- it 'should fail without setting future option to true on future manifest' do
108
- expect(PuppetSyntax.future_parser).to eq(false)
141
+ if Puppet::Util::Package.versioncmp(Puppet.version, '4.0') < 0
142
+ it 'should fail without setting future option to true on future manifest on Puppet < 4.0.0' do
143
+ expect(PuppetSyntax.future_parser).to eq(false)
109
144
 
110
- files = fixture_manifests(['future_syntax.pp'])
111
- output, has_errors = subject.check(files)
145
+ files = fixture_manifests(['future_syntax.pp'])
146
+ output, has_errors = subject.check(files)
112
147
 
113
- expect(output.size).to eq(1)
114
- expect(output[0]).to match(/Syntax error at '='; expected '\}' .*:2$/)
115
- expect(has_errors).to eq(true)
148
+ expect(output.size).to eq(1)
149
+ expect(output[0]).to match(/Syntax error at '='; expected '\}' .*:2$/)
150
+ expect(has_errors).to eq(true)
151
+ end
152
+ else
153
+ it 'should succeed on Puppet >= 4.0.0' do
154
+ expect(PuppetSyntax.future_parser).to eq(false)
155
+
156
+ files = fixture_manifests(['future_syntax.pp'])
157
+ output, has_errors = subject.check(files)
158
+
159
+ expect(output.size).to eq(0)
160
+ expect(has_errors).to eq(false)
161
+ end
116
162
  end
117
163
  end
118
164
 
@@ -121,8 +167,8 @@ describe PuppetSyntax::Manifests do
121
167
  PuppetSyntax.future_parser = true
122
168
  }
123
169
 
124
- if Puppet::Util::Package.versioncmp(Puppet.version, '3.2') >= 0
125
- context 'Puppet >= 3.2' do
170
+ if Puppet::Util::Package.versioncmp(Puppet.version, '3.2') >= 0 and Puppet::PUPPETVERSION.to_i < 4
171
+ context 'Puppet >= 3.2 < 4' do
126
172
  it 'should pass with future option set to true on future manifest' do
127
173
  files = fixture_manifests(['future_syntax.pp'])
128
174
  output, has_errors = subject.check(files)
@@ -131,7 +177,7 @@ describe PuppetSyntax::Manifests do
131
177
  expect(has_errors).to eq(false)
132
178
  end
133
179
  end
134
- context 'Puppet >= 3.7' do
180
+ context 'Puppet >= 3.7 < 4' do
135
181
  # Certain elements of the future parser weren't added until 3.7
136
182
  if Puppet::Util::Package.versioncmp(Puppet.version, '3.7') >= 0
137
183
  it 'should fail on what were deprecation notices in the non-future parser' do
@@ -144,7 +190,7 @@ describe PuppetSyntax::Manifests do
144
190
  end
145
191
  end
146
192
  end
147
- else
193
+ elsif Puppet::Util::Package.versioncmp(Puppet.version, '3.2') < 0
148
194
  context 'Puppet < 3.2' do
149
195
  it 'should return an error that the parser option is not supported' do
150
196
  files = fixture_manifests(['future_syntax.pp'])
@@ -1,4 +1,5 @@
1
1
  require 'spec_helper'
2
+ require 'puppet-syntax/tasks/puppet-syntax'
2
3
 
3
4
  describe 'PuppetSyntax rake tasks' do
4
5
  it 'should generate FileList of manifests relative to Rakefile' do
@@ -59,4 +59,72 @@ describe PuppetSyntax::Templates do
59
59
 
60
60
  expect(res).to match([])
61
61
  end
62
+
63
+ if Puppet::PUPPETVERSION.to_i < 4
64
+ context 'on Puppet < 4.0.0' do
65
+ it 'should throw an exception when parsing EPP files' do
66
+ file = fixture_templates('pass.epp')
67
+ expect{ subject.check(file) }.to raise_error(/Cannot validate EPP without Puppet 4/)
68
+ end
69
+
70
+ context "when the 'epp_only' options is set" do
71
+ before(:each) {
72
+ PuppetSyntax.epp_only = true
73
+ }
74
+
75
+ it 'should throw an exception for any file' do
76
+ file = fixture_templates('pass.erb')
77
+ expect{ subject.check(file) }.to raise_error(/Cannot validate EPP without Puppet 4/)
78
+ end
79
+ end
80
+ end
81
+ end
82
+
83
+ if Puppet::PUPPETVERSION.to_i >= 4
84
+ context 'on Puppet >= 4.0.0' do
85
+ it 'should return nothing from a valid file' do
86
+ files = fixture_templates('pass.epp')
87
+ res = subject.check(files)
88
+
89
+ expect(res).to match([])
90
+ end
91
+
92
+ it 'should catch SyntaxError' do
93
+ files = fixture_templates('fail_error.epp')
94
+ res = subject.check(files)
95
+
96
+ expect(res.size).to eq(1)
97
+ expect(res[0]).to match(/This Type-Name has no effect/)
98
+ end
99
+
100
+ it 'should read more than one valid file' do
101
+ files = fixture_templates(['pass.epp', 'pass_also.epp'])
102
+ res = subject.check(files)
103
+
104
+ expect(res).to match([])
105
+ end
106
+
107
+ it 'should continue after finding an error in the first file' do
108
+ files = fixture_templates(['fail_error.epp', 'fail_error_also.epp'])
109
+ res = subject.check(files)
110
+
111
+ expect(res.size).to eq(2)
112
+ expect(res[0]).to match(/This Type-Name has no effect/)
113
+ expect(res[1]).to match(/Syntax error at '}' at \S*\/fail_error_also.epp:2:4/)
114
+ end
115
+
116
+ context "when the 'epp_only' options is set" do
117
+ before(:each) {
118
+ PuppetSyntax.epp_only = true
119
+ }
120
+
121
+ it 'should process an ERB as EPP and find an error' do
122
+ files = fixture_templates('pass.erb')
123
+ res = subject.check(files)
124
+
125
+ expect(res.size).to eq(1)
126
+ end
127
+ end
128
+ end
129
+ end
62
130
  end
@@ -29,4 +29,9 @@ describe PuppetSyntax do
29
29
  expect(PuppetSyntax.fail_on_deprecation_notices).to eq(false)
30
30
  end
31
31
 
32
+ it 'should support forcing EPP only templates' do
33
+ PuppetSyntax.epp_only = true
34
+ expect(PuppetSyntax.epp_only).to eq(true)
35
+ end
36
+
32
37
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: puppet-syntax
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0
4
+ version: 2.1.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2015-02-26 00:00:00.000000000 Z
12
+ date: 2016-01-18 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rake
@@ -90,9 +90,14 @@ files:
90
90
  - spec/fixtures/test_module/manifests/future_syntax.pp
91
91
  - spec/fixtures/test_module/manifests/pass.pp
92
92
  - spec/fixtures/test_module/manifests/pass_storeconfigs.pp
93
+ - spec/fixtures/test_module/manifests/tag_notice.pp
94
+ - spec/fixtures/test_module/templates/fail_error.epp
93
95
  - spec/fixtures/test_module/templates/fail_error.erb
96
+ - spec/fixtures/test_module/templates/fail_error_also.epp
94
97
  - spec/fixtures/test_module/templates/fail_warning.erb
98
+ - spec/fixtures/test_module/templates/pass.epp
95
99
  - spec/fixtures/test_module/templates/pass.erb
100
+ - spec/fixtures/test_module/templates/pass_also.epp
96
101
  - spec/fixtures/test_module/templates/pass_unbound_var.erb
97
102
  - spec/fixtures/test_module/templates/typeerror_shouldwin.erb
98
103
  - spec/puppet-syntax/hiera_spec.rb
@@ -116,7 +121,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
116
121
  version: '0'
117
122
  segments:
118
123
  - 0
119
- hash: 2080509366784508245
124
+ hash: 1512611786751491860
120
125
  required_rubygems_version: !ruby/object:Gem::Requirement
121
126
  none: false
122
127
  requirements:
@@ -125,7 +130,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
125
130
  version: '0'
126
131
  segments:
127
132
  - 0
128
- hash: 2080509366784508245
133
+ hash: 1512611786751491860
129
134
  requirements: []
130
135
  rubyforge_project:
131
136
  rubygems_version: 1.8.23.2
@@ -142,9 +147,14 @@ test_files:
142
147
  - spec/fixtures/test_module/manifests/future_syntax.pp
143
148
  - spec/fixtures/test_module/manifests/pass.pp
144
149
  - spec/fixtures/test_module/manifests/pass_storeconfigs.pp
150
+ - spec/fixtures/test_module/manifests/tag_notice.pp
151
+ - spec/fixtures/test_module/templates/fail_error.epp
145
152
  - spec/fixtures/test_module/templates/fail_error.erb
153
+ - spec/fixtures/test_module/templates/fail_error_also.epp
146
154
  - spec/fixtures/test_module/templates/fail_warning.erb
155
+ - spec/fixtures/test_module/templates/pass.epp
147
156
  - spec/fixtures/test_module/templates/pass.erb
157
+ - spec/fixtures/test_module/templates/pass_also.epp
148
158
  - spec/fixtures/test_module/templates/pass_unbound_var.erb
149
159
  - spec/fixtures/test_module/templates/typeerror_shouldwin.erb
150
160
  - spec/puppet-syntax/hiera_spec.rb