puppet-retrospec 1.0.0 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +52 -0
  3. data/.gitlab-ci.yml +1 -0
  4. data/.overcommit.yml +33 -0
  5. data/.rubocop.yml +17 -3
  6. data/.rubocop_todo.yml +744 -0
  7. data/CHANGELOG.md +3 -1
  8. data/Gemfile +1 -4
  9. data/Gemfile.lock +34 -62
  10. data/README.md +2 -2
  11. data/Rakefile +3 -21
  12. data/lib/retrospec/plugins/v1/plugin/generators/fact_generator.rb +5 -5
  13. data/lib/retrospec/plugins/v1/plugin/generators/function_generator.rb +62 -18
  14. data/lib/retrospec/plugins/v1/plugin/generators/parsers/native_function.rb +58 -0
  15. data/lib/retrospec/plugins/v1/plugin/puppet.rb +1 -1
  16. data/lib/retrospec/plugins/v1/plugin/version.rb +1 -1
  17. data/puppet-retrospec.gemspec +5 -1648
  18. data/spec/fixtures/fixture_modules/sample_module/lib/puppet/functions/awesome_parser.rb +14 -0
  19. data/spec/fixtures/functions/abs.pp +4 -0
  20. data/spec/unit/generators/acceptance_generator_spec.rb +10 -14
  21. data/spec/unit/generators/definition_generator_spec.rb +4 -8
  22. data/spec/unit/generators/fact_generater_spec.rb +6 -7
  23. data/spec/unit/generators/function_generator_spec.rb +83 -17
  24. data/spec/unit/generators/function_spec.rb +1 -3
  25. data/spec/unit/generators/hostclass_generator_spec.rb +7 -10
  26. data/spec/unit/generators/node_generator_spec.rb +4 -7
  27. data/spec/unit/generators/parsers/fact_spec.rb +7 -10
  28. data/spec/unit/generators/parsers/provider_spec.rb +5 -5
  29. data/spec/unit/generators/parsers/type_spec.rb +8 -9
  30. data/spec/unit/generators/provider_generator_spec.rb +1 -2
  31. data/spec/unit/generators/report_generator_spec.rb +5 -7
  32. data/spec/unit/generators/resource_base_generator_spec.rb +3 -5
  33. data/spec/unit/generators/schema_generator_spec.rb +28 -32
  34. data/spec/unit/generators/serializers/rspec_dumper_spec.rb +35 -38
  35. data/spec/unit/generators/type_generator_spec.rb +116 -116
  36. data/spec/unit/plugin_spec.rb +15 -22
  37. data/spec/unit/puppet-retrospec_spec.rb +3 -5
  38. data/spec/unit/spec_object_spec.rb +17 -20
  39. metadata +9 -4
data/CHANGELOG.md CHANGED
@@ -1,3 +1,5 @@
1
+ ## 1.1.0
2
+ * fixes gh-62 - add support for creating native puppet fuctions
1
3
  ## 1.0.0
2
4
  This is a major release which vendors the latest puppet version. The core parser
3
5
  was rewritten to use the new puppet parser and opens up a bunch of new possibilities
@@ -8,7 +10,7 @@
8
10
  * Fixes gh-56 - variable_value: rendering values with escapes creates invalid tests
9
11
  * Fixes gh-15 - nested conditionals are not discovered
10
12
  * Fixes gh-54 - Vendored puppet 3.7 doesn't work on newer rubies
11
-
13
+
12
14
  ## 0.12.2
13
15
  * fixes issue with ruby193 and openstruct
14
16
  * fix unit tests from failing on missing hook file
data/Gemfile CHANGED
@@ -11,6 +11,7 @@ group :development do
11
11
  end
12
12
 
13
13
  group :test do
14
+ gem 'rubocop'
14
15
  gem 'rspec', '~> 3.2'
15
16
  gem 'puppet', '4.5.2', :path => 'vendor/gems/puppet-4.5.2'
16
17
  gem 'rake'
@@ -19,7 +20,3 @@ group :test do
19
20
  gem 'fakefs', :require => 'fakefs/safe'
20
21
  gem 'rspec', '~> 3.2'
21
22
  end
22
-
23
- group :build do
24
- gem 'jeweler'
25
- end
data/Gemfile.lock CHANGED
@@ -10,84 +10,56 @@ GEM
10
10
  remote: http://rubygems.org/
11
11
  specs:
12
12
  CFPropertyList (2.2.8)
13
- addressable (2.3.8)
14
- awesome_print (1.6.1)
15
- builder (3.2.2)
16
- coderay (1.1.0)
17
- descendants_tracker (0.0.4)
18
- thread_safe (~> 0.3, >= 0.3.1)
13
+ ast (2.3.0)
14
+ awesome_print (1.7.0)
15
+ coderay (1.1.1)
19
16
  diff-lcs (1.2.5)
20
- facets (3.0.0)
17
+ facets (3.1.0)
21
18
  facter (2.4.6)
22
19
  CFPropertyList (~> 2.2.6)
23
- fakefs (0.6.7)
24
- faraday (0.9.2)
25
- multipart-post (>= 1.2, < 3)
26
- git (1.2.9.1)
27
- github_api (0.12.4)
28
- addressable (~> 2.3)
29
- descendants_tracker (~> 0.0.4)
30
- faraday (~> 0.8, < 0.10)
31
- hashie (>= 3.4)
32
- multi_json (>= 1.7.5, < 2.0)
33
- nokogiri (~> 1.6.6)
34
- oauth2
35
- hashie (3.4.2)
36
- hiera (3.1.2)
20
+ fakefs (0.9.0)
21
+ hiera (3.2.0)
37
22
  json_pure
38
- highline (1.7.8)
39
- jeweler (2.0.1)
40
- builder
41
- bundler (>= 1.0)
42
- git (>= 1.2.5)
43
- github_api
44
- highline (>= 1.6.15)
45
- nokogiri (>= 1.5.10)
46
- rake
47
- rdoc
48
23
  json (1.8.3)
49
- json_pure (1.8.3)
50
- jwt (1.5.1)
24
+ json_pure (2.0.2)
51
25
  method_source (0.8.2)
52
- mini_portile (0.6.2)
53
- multi_json (1.11.2)
54
- multi_xml (0.5.5)
55
- multipart-post (2.0.0)
56
- nokogiri (1.6.6.2)
57
- mini_portile (~> 0.6.0)
58
- oauth2 (1.0.0)
59
- faraday (>= 0.8, < 0.10)
60
- jwt (~> 1.0)
61
- multi_json (~> 1.3)
62
- multi_xml (~> 0.5)
63
- rack (~> 1.2)
64
- pry (0.10.2)
26
+ parser (2.3.1.2)
27
+ ast (~> 2.2)
28
+ powerpack (0.1.1)
29
+ pry (0.10.4)
65
30
  coderay (~> 1.1.0)
66
31
  method_source (~> 0.8.1)
67
32
  slop (~> 3.4)
68
- rack (1.6.4)
69
- rake (10.4.2)
33
+ rainbow (2.1.0)
34
+ rake (11.2.2)
70
35
  rdoc (3.12.2)
71
36
  json (~> 1.4)
72
37
  retrospec (0.4.0)
73
38
  trollop
74
- rspec (3.3.0)
75
- rspec-core (~> 3.3.0)
76
- rspec-expectations (~> 3.3.0)
77
- rspec-mocks (~> 3.3.0)
78
- rspec-core (3.3.2)
79
- rspec-support (~> 3.3.0)
80
- rspec-expectations (3.3.1)
39
+ rspec (3.5.0)
40
+ rspec-core (~> 3.5.0)
41
+ rspec-expectations (~> 3.5.0)
42
+ rspec-mocks (~> 3.5.0)
43
+ rspec-core (3.5.1)
44
+ rspec-support (~> 3.5.0)
45
+ rspec-expectations (3.5.0)
81
46
  diff-lcs (>= 1.2.0, < 2.0)
82
- rspec-support (~> 3.3.0)
83
- rspec-mocks (3.3.2)
47
+ rspec-support (~> 3.5.0)
48
+ rspec-mocks (3.5.0)
84
49
  diff-lcs (>= 1.2.0, < 2.0)
85
- rspec-support (~> 3.3.0)
86
- rspec-support (3.3.0)
50
+ rspec-support (~> 3.5.0)
51
+ rspec-support (3.5.0)
52
+ rubocop (0.42.0)
53
+ parser (>= 2.3.1.1, < 3.0)
54
+ powerpack (~> 0.1)
55
+ rainbow (>= 1.99.1, < 3.0)
56
+ ruby-progressbar (~> 1.7)
57
+ unicode-display_width (~> 1.0, >= 1.0.1)
58
+ ruby-progressbar (1.8.1)
87
59
  slop (3.6.0)
88
- thread_safe (0.3.5)
89
60
  trollop (2.1.2)
90
- yard (0.8.7.6)
61
+ unicode-display_width (1.1.0)
62
+ yard (0.9.5)
91
63
 
92
64
  PLATFORMS
93
65
  ruby
@@ -97,13 +69,13 @@ DEPENDENCIES
97
69
  bundler (~> 1.0)
98
70
  facets
99
71
  fakefs
100
- jeweler
101
72
  pry
102
73
  puppet (= 4.5.2)!
103
74
  rake
104
75
  rdoc (~> 3.12)
105
76
  retrospec (~> 0.4)
106
77
  rspec (~> 3.2)
78
+ rubocop
107
79
  trollop
108
80
  yard (~> 0.7)
109
81
 
data/README.md CHANGED
@@ -52,14 +52,14 @@ TOC Created by [gh-md-toc](https://github.com/ekalinin/github-markdown-toc)
52
52
 
53
53
  ## News
54
54
  ### 6-28-16
55
- Version 1.0.0 is release with full support for puppet 4.x code.
55
+ Version 1.0.0 is released with full support for puppet 4.x code.
56
56
  ### 1-18-16
57
57
  A slew of new features has been added with the 0.12 update. If you already use retrospec to retrofit your modules, now you can use retrospec to generate some of the more advanced puppet module customizations such as:
58
58
 
59
59
  - custom facts
60
60
  - providers
61
61
  - custom types
62
- - functions (v3 and v4)
62
+ - functions (v3,v4, and native)
63
63
  - parameter schemas
64
64
 
65
65
  This has been a feature in the making since Puppetconf 2015. I would have finished this sooner but was sucked in
data/Rakefile CHANGED
@@ -2,34 +2,16 @@
2
2
 
3
3
  require 'rubygems'
4
4
  require 'bundler'
5
+ require "bundler/gem_tasks"
6
+ require "rake/testtask"
5
7
  begin
6
- Bundler.setup(:default, :development)
8
+ Bundler.setup(:default, :development, :test)
7
9
  rescue Bundler::BundlerError => e
8
10
  $stderr.puts e.message
9
11
  $stderr.puts 'Run `bundle install` to install missing gems'
10
12
  exit e.status_code
11
13
  end
12
14
  require 'rake'
13
- begin
14
- require_relative 'lib/retrospec/plugins/v1/plugin/version'
15
- require 'jeweler'
16
- plugin_version = "#{Retrospec::Puppet::VERSION}"
17
- Jeweler::Tasks.new do |gem|
18
- # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
19
- gem.name = 'puppet-retrospec'
20
- gem.version = "#{plugin_version}"
21
- gem.homepage = 'http://github.com/nwops/puppet-retrospec'
22
- gem.license = 'MIT'
23
- gem.summary = %(Generates puppet rspec test code based on the classes and defines inside the manifests directory. Aims to reduce some of the boilerplate coding with default test patterns.)
24
- gem.description = %(Retrofits and generates valid puppet rspec test code to existing modules)
25
- gem.email = 'corey@logicminds.biz'
26
- gem.authors = ['Corey Osman']
27
- # dependencies defined in Gemfile
28
- end
29
- Jeweler::RubygemsDotOrgTasks.new
30
- rescue LoadError
31
- # do need jeweler for all tasks
32
- end
33
15
  require 'rspec/core'
34
16
  require 'rspec/core/rake_task'
35
17
  RSpec::Core::RakeTask.new(:spec) do |spec|
@@ -87,11 +87,11 @@ Generates a new fact with the given name
87
87
  def template_dir
88
88
  unless @template_dir
89
89
  external_templates = File.expand_path(File.join(config_data[:template_dir], 'facts', 'fact.rb.retrospec.erb'))
90
- if File.exist?(external_templates)
91
- @template_dir = File.join(config_data[:template_dir], 'facts')
92
- else
93
- @template_dir = File.expand_path(File.join(File.dirname(File.dirname(__FILE__)), 'templates', 'facts'))
94
- end
90
+ @template_dir = if File.exist?(external_templates)
91
+ File.join(config_data[:template_dir], 'facts')
92
+ else
93
+ File.expand_path(File.join(File.dirname(File.dirname(__FILE__)), 'templates', 'facts'))
94
+ end
95
95
  end
96
96
  @template_dir
97
97
  end
@@ -1,11 +1,10 @@
1
1
  require_relative 'parsers/function'
2
-
2
+ require_relative 'parsers/native_function'
3
3
  module Retrospec
4
4
  module Puppet
5
5
  module Generators
6
6
  class FunctionGenerator < Retrospec::Plugins::V1::Plugin
7
7
  attr_reader :template_dir, :context
8
-
9
8
  # retrospec will initilalize this class so its up to you
10
9
  # to set any additional variables you need to get the job done.
11
10
  def initialize(module_path, spec_object = {})
@@ -14,7 +13,8 @@ module Retrospec
14
13
  # you will need to initialize this object, so the erb templates can get the binding
15
14
  # the SpecObject can be customized to your liking as its different for every plugin gem.
16
15
  @context = OpenStruct.new(:name => spec_object[:name], :return_type => spec_object[:return_type],
17
- :function_type => spec_object[:type], :test_type => spec_object[:test_type])
16
+ :function_type => spec_object[:type],
17
+ :test_type => spec_object[:test_type])
18
18
  end
19
19
 
20
20
  # Puppet currently has two versions of functions (v3, v4). At the time of writing v4 is still new
@@ -24,7 +24,8 @@ module Retrospec
24
24
  # By default this method looks inside the user supplied template dir for existence of a template and if true returns that base path, if
25
25
  # false returns the template directory inside the gem location which is mainly used for development only.
26
26
  def template_dir
27
- external_templates = File.expand_path(File.join(config_data[:template_dir], 'functions',function_type, 'function_template.rb.retrospec.erb'))
27
+ external_templates = File.expand_path(File.join(config_data[:template_dir], 'functions',
28
+ function_type, "function_template#{function_ext}.retrospec.erb"))
28
29
  if File.exist?(external_templates)
29
30
  File.join(config_data[:template_dir], 'functions', function_type)
30
31
  else
@@ -32,7 +33,7 @@ module Retrospec
32
33
  end
33
34
  end
34
35
 
35
- # returns v3 or v4 to specify the function type
36
+ # returns v3,v4, native to specify the function type
36
37
  def function_type
37
38
  context.function_type
38
39
  end
@@ -43,8 +44,8 @@ module Retrospec
43
44
  # all options here are available in the config passed into config object
44
45
  # returns the parameters
45
46
  def self.run_cli(global_opts, args=ARGV)
46
- func_types = ['v3', 'v4']
47
- func_type = global_opts['plugins::puppet::default_function_version'] || 'v3'
47
+ func_types = ['v3', 'v4', 'native']
48
+ func_type = global_opts['plugins::puppet::default_function_version'] || 'v4'
48
49
  test_type = global_opts['plugins::puppet::default_function_test_type'] || 'rspec'
49
50
  sub_command_opts = Trollop.options(args) do
50
51
  banner <<-EOS
@@ -52,7 +53,7 @@ Generates a new function with the given name.
52
53
 
53
54
  EOS
54
55
  opt :name, 'The name of the function you wish to create', :type => :string, :required => true, :short => '-n'
55
- opt :type, 'The version type of the function (v3, v4)', :type => :string, :required => false, :short => '-t',
56
+ opt :type, "The version type of the function (#{func_types.join(',')})", :type => :string, :required => false, :short => '-t',
56
57
  :default => func_type
57
58
  opt :test_type, 'The type of test file to create (rspec, ruby)', :default => test_type, :type => :string, :short => '-u'
58
59
  opt :return_type, 'The return type of the function (rvalue, statement)', :type => :string, :required => false,
@@ -74,10 +75,13 @@ Generates a new function with the given name.
74
75
 
75
76
  # returns the function directory to create the the function in
76
77
  def function_dir
77
- if function_type == 'v3'
78
+ case function_type
79
+ when 'v3'
78
80
  v3_function_dir
79
- else
81
+ when 'v4'
80
82
  v4_function_dir
83
+ when 'native'
84
+ native_function_dir
81
85
  end
82
86
  end
83
87
 
@@ -91,9 +95,18 @@ Generates a new function with the given name.
91
95
  @v4_function_dir || File.join(module_path, 'lib', 'puppet', 'functions')
92
96
  end
93
97
 
98
+ def native_function_dir
99
+ @native_function_dir || File.join(module_path, 'functions')
100
+ end
101
+
94
102
  # returns the path to the function using the function directory
95
103
  def function_path
96
- File.join(function_dir, "#{function_name}.rb")
104
+ path = File.join(function_dir, function_name.to_s)
105
+ path + function_ext
106
+ end
107
+
108
+ def function_ext
109
+ function_type == 'native' ? '.pp' : '.rb'
97
110
  end
98
111
 
99
112
  # returns the name of the function
@@ -101,9 +114,13 @@ Generates a new function with the given name.
101
114
  context.name
102
115
  end
103
116
 
117
+ def function_file_path
118
+ File.join(template_dir, "function_template#{function_ext}.retrospec.erb")
119
+ end
120
+
104
121
  # generates the function file based on the template and context
105
122
  def generate_function_file
106
- safe_create_template_file(function_path, File.join(template_dir, 'function_template.rb.retrospec.erb'), context)
123
+ safe_create_template_file(function_path, function_file_path, context)
107
124
  function_path
108
125
  end
109
126
 
@@ -111,13 +128,20 @@ Generates a new function with the given name.
111
128
  # because this can vary between test types and function types
112
129
  # there are many supporting functions to determine which directory to use
113
130
  def spec_file_dir
114
- if function_type == 'v3'
131
+ case function_type
132
+ when 'v3'
115
133
  v3_spec_dir
116
- else
134
+ when 'v4'
117
135
  v4_spec_dir
136
+ when 'native'
137
+ native_spec_dir
118
138
  end
119
139
  end
120
140
 
141
+ def native_spec_dir
142
+ File.join(module_path, 'spec', 'functions')
143
+ end
144
+
121
145
  # returns the path to the v3 spec directory if using using rspec test type
122
146
  # the spec/functions is returned
123
147
  def v3_spec_dir
@@ -138,12 +162,28 @@ Generates a new function with the given name.
138
162
  end
139
163
  end
140
164
 
141
- # returns an array of functions found in either the v3 or v4 directories
165
+ # @return [Array] an array of functions found in either the v3,v4, native directories
142
166
  def discovered_functions
143
- Dir.glob([File.join(v3_function_dir, '*.rb'), File.join(v4_function_dir, '*.rb')]).sort
167
+ Dir.glob([File.join(v3_function_dir, '*.rb'),
168
+ File.join(v4_function_dir, '*.rb'), File.join(native_function_dir, '*.pp')]).sort
169
+ end
170
+
171
+ # @return [Boolean] true if the function file is a native function
172
+ def native_function?(function_file)
173
+ # mod_name/functions
174
+ File.basename(Pathname.new(function_file).parent) == 'functions' &&
175
+ File.extname(function_file) == '.pp'
176
+ end
177
+
178
+ # @return [Boolean] true if the function file is a v4 function
179
+ def v4_function?(function_file)
180
+ # mod_name/lib/puppet/functions
181
+ File.basename(Pathname.new(function_file).parent.parent) == 'functions'
144
182
  end
145
183
 
146
- def is_v3_function?(function_file)
184
+ # @return [Boolean] true if the function file is a v3 function
185
+ def v3_function?(function_file)
186
+ # mod_name/lib/puppet/parser/functions
147
187
  File.basename(Pathname.new(function_file).parent.parent) == 'parser'
148
188
  end
149
189
 
@@ -161,9 +201,13 @@ Generates a new function with the given name.
161
201
  spec_files = []
162
202
  discovered_functions.each do |file|
163
203
  begin
164
- if is_v3_function?(file)
204
+ if v3_function?(file)
165
205
  context.function_type = 'v3'
166
206
  file_data = Retrospec::Puppet::Parser::Functions.load_function(file)
207
+ elsif native_function?(file)
208
+ context.test_type = 'rspec'
209
+ context.function_type = 'native'
210
+ file_data = Parsers::NativeFunction.load_function(file)
167
211
  else
168
212
  context.function_type = 'v4'
169
213
  file_data = Retrospec::Puppet::Functions.load_function(file)
@@ -0,0 +1,58 @@
1
+ require_relative '../serializers/rspec_dumper'
2
+ require 'ostruct'
3
+ module Parsers
4
+ class NativeFunction
5
+ attr_reader :manifest_file
6
+
7
+ def initialize(file)
8
+ @manifest_file = file
9
+ end
10
+
11
+ # @param [String] - path to the function file
12
+ # @return [OpenStruct] - a object with name and parameters
13
+ def self.load_function(file)
14
+ f = new(file)
15
+ @model = OpenStruct.new(:name => f.definition.name,
16
+ :parameters => f.parameter_list,
17
+ :parameter_names => f.parameter_list.keys)
18
+ @model
19
+ end
20
+
21
+ def ast
22
+ unless @ast
23
+ raise ArgumentError, 'please set the manifest file' if manifest_file.nil?
24
+ parser = ::Puppet::Pops::Parser::EvaluatingParser.new
25
+ result = parser.parse_file(manifest_file)
26
+ @ast = result.current
27
+ end
28
+ @ast
29
+ end
30
+
31
+ def dumper
32
+ @dumper ||= Retrospec::Puppet::RspecDumper.new
33
+ end
34
+
35
+ def definition
36
+ ast.body
37
+ end
38
+
39
+ # return a manifest body object
40
+ def body
41
+ ast.body.body
42
+ end
43
+
44
+ def parameters
45
+ ast.body.parameters
46
+ end
47
+
48
+ def function_name
49
+ body.name
50
+ end
51
+
52
+ def parameter_list
53
+ list = {}
54
+ parameters.each { |p| list[p.name.to_sym] = p.value }
55
+ list
56
+ end
57
+ end
58
+ end