puppet-retrospec 0.10.0 → 0.11.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: cbc49b480678daffff061e656b863bd070e751aa
4
- data.tar.gz: 664b47744df42f5fa4df4121ac631a443c578818
3
+ metadata.gz: 4a46b9123ebdcbabc88aea95e6d9bf8bc4d8186e
4
+ data.tar.gz: d051e9b7a2e86b5a6260382b5ce41517a058d7d6
5
5
  SHA512:
6
- metadata.gz: 3c933d5fb7ee82ea64ab460dfe40f4b6e8a79d690785ece5422109323aedf9998112f27f0d0b949a89e2dfae0edf7b28314ef5c0f6b43442a2c1dfb112575b31
7
- data.tar.gz: 8df5426ac543a838444891ca1a4cbca589d9dc228344e589975da6fab5d16eaee44674f8489e02d1325cf9b9f66938a79fdebad7013c2725b6028681bc1f06a1
6
+ metadata.gz: ea9f08b9433abd1b92cbcc4ebef5e161acba887b78dc9048b442f308d4f210bf02a11936b3593edd55f94d0c4acc19b403a9e8b6f07f790dcdf911552db2684a
7
+ data.tar.gz: d55f442ff7e53df1b2736ea9fc493da6b1fdaca921f151402a0548b95327e2bb86e875772d04a9b325b3a90402912f7fd395f28130697f0a59b75e11bc09d8c1
data/Gemfile CHANGED
@@ -1,7 +1,8 @@
1
1
  source "http://rubygems.org"
2
2
 
3
3
  gem 'trollop'
4
- gem 'retrospec', "~> 0.4.0"
4
+ gem 'retrospec', "~> 0.4"
5
+ gem 'awesome_print'
5
6
  # Include everything needed to run rake, tests, features, etc.
6
7
  group :development do
7
8
  gem "rspec", "~> 3.2"
data/Gemfile.lock CHANGED
@@ -11,6 +11,7 @@ GEM
11
11
  specs:
12
12
  CFPropertyList (2.2.8)
13
13
  addressable (2.3.8)
14
+ awesome_print (1.6.1)
14
15
  builder (3.2.2)
15
16
  coderay (1.1.0)
16
17
  descendants_tracker (0.0.4)
@@ -19,7 +20,7 @@ GEM
19
20
  facter (2.4.4)
20
21
  CFPropertyList (~> 2.2.6)
21
22
  fakefs (0.6.7)
22
- faraday (0.9.1)
23
+ faraday (0.9.2)
23
24
  multipart-post (>= 1.2, < 3)
24
25
  git (1.2.9.1)
25
26
  github_api (0.12.4)
@@ -33,7 +34,7 @@ GEM
33
34
  hashie (3.4.2)
34
35
  hiera (1.3.4)
35
36
  json_pure
36
- highline (1.7.7)
37
+ highline (1.7.8)
37
38
  jeweler (2.0.1)
38
39
  builder
39
40
  bundler (>= 1.0)
@@ -91,13 +92,14 @@ PLATFORMS
91
92
  ruby
92
93
 
93
94
  DEPENDENCIES
95
+ awesome_print
94
96
  bundler (~> 1.0)
95
97
  fakefs
96
98
  jeweler
97
99
  pry
98
100
  puppet (= 3.7.3)!
99
101
  rdoc (~> 3.12)
100
- retrospec (~> 0.4.0)
102
+ retrospec (~> 0.4)
101
103
  rspec (~> 3.2)
102
104
  trollop
103
105
  yard (~> 0.7)
data/README.md CHANGED
@@ -1,3 +1,5 @@
1
+ [![Gem Version](https://badge.fury.io/rb/puppet-retrospec.svg)](http://badge.fury.io/rb/puppet-retrospec)
2
+
1
3
  Puppet-Retrospec
2
4
  ================
3
5
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.10.0
1
+ 0.11.0
@@ -1,3 +1,4 @@
1
1
  vendor = File.join(File.dirname(File.dirname(__FILE__)),'vendor')
2
2
  $:.unshift(File.expand_path(File.join([vendor, "gems", "puppet-3.7.3", "lib"])))
3
3
  require 'retrospec/plugins/v1/plugin/puppet'
4
+ require 'awesome_print' # required for printing templates
@@ -0,0 +1,93 @@
1
+ require_relative 'facter'
2
+
3
+ module Retrospec
4
+ module Puppet
5
+ module Generators
6
+ class FactGenerator < Retrospec::Plugins::V1::Plugin
7
+
8
+ attr_reader :template_dir, :context, :module_path, :fact_name, :config_data
9
+
10
+ # retrospec will initilalize this class so its up to you
11
+ # to set any additional variables you need to get the job done.
12
+ def initialize(module_path, spec_object={})
13
+ # below is the Spec Object which serves as a context for template rendering
14
+ # you will need to initialize this object, so the erb templates can get the binding
15
+ # the SpecObject can be customized to your liking as its different for every plugin gem.
16
+ @module_path = module_path
17
+ @config_data = spec_object
18
+ @context = OpenStruct.new(:fact_name => spec_object[:name])
19
+ end
20
+
21
+ # used to display subcommand options to the cli
22
+ # the global options are passed in for your usage
23
+ # http://trollop.rubyforge.org
24
+ # all options here are available in the config passed into config object
25
+ def self.run_cli(global_opts)
26
+ sub_command_opts = Trollop::options do
27
+ banner <<-EOS
28
+ Generates a new fact with the given name
29
+
30
+ EOS
31
+ opt :name, "The name of the fact you wish to create", :type => :string, :require => :true, :short => '-n'
32
+ end
33
+ unless sub_command_opts[:name]
34
+ Trollop.educate
35
+ exit 1
36
+ end
37
+ plugin_data = global_opts.merge(sub_command_opts)
38
+ Retrospec::Puppet::Generators::FactGenerator.new(plugin_data[:module_path], plugin_data)
39
+ end
40
+
41
+ def fact_name
42
+ context[:fact_name]
43
+ end
44
+
45
+ def facter_dir
46
+ @facter_dir ||= File.join(module_path, 'lib', 'facter')
47
+ end
48
+
49
+ def facter_spec_dir
50
+ @facter_spec_dir ||= File.join(module_path, 'spec', 'unit', 'facter')
51
+ end
52
+
53
+ def fact_name_path
54
+ File.join(facter_dir, "#{fact_name}.rb")
55
+ end
56
+
57
+ # generates a fact file with the given name based on the template in the templates directory
58
+ def generate_fact_file
59
+ safe_create_template_file(fact_name_path, File.join(template_dir, 'fact.rb.retrospec.erb'), context)
60
+ generate_fact_spec_files
61
+ end
62
+
63
+ # generates spec files for each fact defined in the fact file
64
+ def generate_fact_spec_files
65
+ fact_files = Dir.glob(File.join(facter_dir, '*.rb')).sort
66
+ fact_files.each do | fact_file|
67
+ fact_file_data = Retrospec::Puppet::Generators::Facter.load_fact(fact_file)
68
+ fact_file_data.facts.each do |name, fact_data|
69
+ # because many facts can be in a single file we want to create a unique file for each fact
70
+ fact_spec_path = File.join(facter_spec_dir, "#{name}_spec.rb")
71
+ safe_create_template_file(fact_spec_path, File.join(template_dir, 'fact_spec.rb.retrospec.erb'), fact_data)
72
+ end
73
+ end
74
+ end
75
+
76
+ # the template directory located inside the your retrospec plugin gem
77
+ # you should not have to modify this unless you move the templates directory
78
+ # for now we are going to choose the correct template directory that contains the templates
79
+ def template_dir
80
+ unless @template_dir
81
+ external_templates = File.expand_path(File.join(config_data[:template_dir], 'facts', 'fact.rb.retrospec.erb'))
82
+ if File.exists?(external_templates)
83
+ @template_dir = File.join(config_data[:template_dir], 'facts')
84
+ else
85
+ @template_dir = File.expand_path(File.join(File.dirname(File.dirname(__FILE__)), 'templates', 'facts'))
86
+ end
87
+ end
88
+ @template_dir
89
+ end
90
+ end
91
+ end
92
+ end
93
+ end
@@ -0,0 +1,116 @@
1
+ require 'ostruct'
2
+
3
+ # this is required to use when processing erb templates
4
+ class OpenStruct
5
+ def get_binding
6
+ binding()
7
+ end
8
+ end
9
+
10
+ module Retrospec
11
+ module Puppet
12
+ module Generators
13
+ class Facter
14
+ # anytime a fact uses a facter lib we need to "mock" the fuction and record the value
15
+ class Core
16
+ class Execution
17
+ def self.execute(command, options={})
18
+ value = {:klass => self.to_s.gsub('Retrospec::Puppet::Generators::', ''),
19
+ :method => :execute, :value => command}
20
+ Retrospec::Puppet::Generators::Facter.exec_calls[command] = value
21
+ end
22
+ end
23
+ end
24
+
25
+ @model = OpenStruct.new(:facts => {})
26
+ @used_facts = {}
27
+ @confines = []
28
+ @methods_defined = []
29
+
30
+ def initialize(name, options, &block)
31
+ @fact_name = name
32
+ #block.call
33
+ end
34
+
35
+ def self.exec_calls
36
+ @exec_calls ||= {}
37
+ end
38
+
39
+ def self.used_facts
40
+ @used_facts ||= {}
41
+ end
42
+
43
+ def self.value(name)
44
+ used_facts[name] = {:name => name}
45
+ end
46
+
47
+ def self.fact(name)
48
+ fake_fact = OpenStruct.new(:value => '')
49
+ used_facts[name] = {:name => name}
50
+ fake_fact
51
+ end
52
+
53
+ def self.method_missing(method_sym, *arguments, &block)
54
+ @methods_defined << method_sym
55
+ end
56
+
57
+ def self.setcode(&block)
58
+ begin
59
+ block.call
60
+ rescue NameError => e
61
+ end
62
+ end
63
+
64
+ def self.confine(fact, *values)
65
+ @confines << fact
66
+ end
67
+
68
+ # loads the fact into the loader for evaluation
69
+ # and data collection
70
+ def self.load_fact(file)
71
+ @model = OpenStruct.new(:facts => {})
72
+ @used_facts = {}
73
+ @model = eval(File.read(file))
74
+ transform_data(@model)
75
+ end
76
+
77
+ # every fact will have a Facter.add functionality
78
+ # this is the startign point to collect all data
79
+ def self.add(name, options={}, &block)
80
+ @model.facts[name] = OpenStruct.new(:fact_name => name)
81
+ # calls the facter.add block
82
+ # this may call separate confine statements
83
+ @model.global_used_facts = used_facts
84
+ @used_facts = {} # clear before fact specific are evaluated
85
+ @model.global_used_execs = exec_calls
86
+ @exec_calls = {}
87
+ begin
88
+ block.call
89
+ rescue NameError => e
90
+ end
91
+ @model.facts[name].used_facts = used_facts
92
+ @model.facts[name].confines = @confines
93
+ # clear any persistant data
94
+ @confines = []
95
+ @model.defined_methods = @methods_defined
96
+ @model.facts[name].exec_calls = exec_calls
97
+ @model
98
+ end
99
+
100
+ def self.transform_data(data)
101
+ #ObenStruct.new(:)
102
+ # {:method_fact=>
103
+ # {:fact_name=>:method_fact,
104
+ # :used_facts=>{:is_virtual=>{:name=>:is_virtual}},
105
+ # :confines=>[{:kernel=>"Linux"}],
106
+ # :exec_calls=>["which lsb"]},
107
+ # :global_used_facts=>{},
108
+ # :global_used_execs=>[],
109
+ # :defined_methods=>[:default_kernel]}
110
+ data
111
+ end
112
+ end
113
+
114
+ end
115
+ end
116
+ end
@@ -0,0 +1,114 @@
1
+ require 'retrospec/plugins/v1/module_helpers'
2
+ require 'retrospec/plugins/v1'
3
+
4
+ module Retrospec
5
+ module Puppet
6
+ module Generators
7
+ class ModuleGenerator < Retrospec::Plugins::V1::Plugin
8
+
9
+ attr_reader :template_dir, :context, :module_path, :fact_name, :config_data
10
+
11
+ # retrospec will initilalize this class so its up to you
12
+ # to set any additional variables you need to get the job done.
13
+ def initialize(module_path, spec_object={})
14
+ super
15
+ # below is the Spec Object which serves as a context for template rendering
16
+ # you will need to initialize this object, so the erb templates can get the binding
17
+ # the SpecObject can be customized to your liking as its different for every plugin gem.
18
+ @template_dir = spec_object[:template_dir]
19
+ @context = OpenStruct.new(:module_name => spec_object[:name])
20
+ end
21
+
22
+ # used to display subcommand options to the cli
23
+ # the global options are passed in for your usage
24
+ # http://trollop.rubyforge.org
25
+ # all options here are available in the config passed into config object
26
+ # returns a new instance of this class
27
+ def self.run_cli(global_opts)
28
+ namespace = global_opts['plugins::puppet::namespace'] || 'namespace'
29
+ author = global_opts['plugins::puppet::author'] || 'author_name'
30
+ sub_command_opts = Trollop::options do
31
+ banner <<-EOS
32
+ Generates a new module with the given name and namespace
33
+
34
+ EOS
35
+ opt :name, "The name of the module you wish to create", :type => :string, :required => false, :short => '-n',
36
+ :default => File.basename(global_opts[:module_path])
37
+ opt :namespace, "The namespace to use only when creating a new module", :default => namespace, :required => false,
38
+ :type => :string
39
+ opt :author, "The full name of the module author", :default => author, :required => false, :short => '-a',
40
+ :type => :string
41
+ end
42
+ unless sub_command_opts[:name]
43
+ Trollop.educate
44
+ exit 1
45
+ end
46
+ plugin_data = global_opts.merge(sub_command_opts)
47
+ Retrospec::Puppet::Generators::ModuleGenerator.new(plugin_data[:module_path], plugin_data)
48
+ end
49
+
50
+ def run(manifest_dir)
51
+ unless File.exist?(manifest_dir)
52
+ init_class = File.join(manifest_dir, 'init.pp')
53
+ content = File.read(File.join(template_dir, 'manifest_file.pp'))
54
+ unless ENV['RETROSPEC_PUPPET_AUTO_GENERATE'] == 'true'
55
+ print "The module located at: #{module_path} does not exist, do you wish to create it? (y/n): "
56
+ answer = gets.chomp
57
+ unless answer =~ /y/i
58
+ exit 1
59
+ end
60
+ end
61
+
62
+ create_manifest_file(init_class, content)
63
+ generate_metadata_file(config_data[:name], config_data)
64
+ end
65
+ end
66
+
67
+ def create_manifest_file(dest, content)
68
+ # replace the name in the target file with the module_name from this class
69
+ # I would have just used a template but the context does not exist yet
70
+ new_content = content.gsub('CLASS_NAME', config_data[:name])
71
+ safe_create_file(dest, new_content)
72
+ end
73
+
74
+ def self.generate_metadata_file(mod_name, config_data)
75
+ f = Retrospec::Puppet::Generators::ModuleGenerator.new(config_data[:module_path], config_data)
76
+ f.generate_metadata_file(mod_name, config_data)
77
+ end
78
+
79
+ # generates the metadata file in the module directory
80
+ def generate_metadata_file(mod_name,config_data)
81
+ require 'puppet/module_tool/metadata'
82
+ # make sure the metadata file exists
83
+ module_path = config_data[:module_path]
84
+ author = config_data[:author] || config_data['plugins::puppet::author'] || 'your_name'
85
+ namespace = config_data[:namespace] || config_data['plugins::puppet::namespace'] || 'namespace'
86
+ metadata_file = File.join(module_path, 'metadata.json')
87
+ unless File.exists?(metadata_file)
88
+ # by default the module tool metadata checks for a namespece
89
+ if ! mod_name.include?('-')
90
+ name = "#{namespace}-#{mod_name}"
91
+ else
92
+ name = mod_name
93
+ end
94
+ begin
95
+ metadata = ::Puppet::ModuleTool::Metadata.new.update(
96
+ 'name' => name.downcase,
97
+ 'version' => '0.1.0',
98
+ 'author' => author,
99
+ 'dependencies' => [
100
+ { 'name' => 'puppetlabs-stdlib', 'version_requirement' => '>= 4.9.0' }
101
+ ]
102
+ )
103
+ rescue ArgumentError => e
104
+ puts e.message
105
+ exit -1
106
+ end
107
+ safe_create_file(metadata_file, metadata.to_json)
108
+ end
109
+ end
110
+
111
+ end
112
+ end
113
+ end
114
+ end
@@ -1,6 +1,8 @@
1
1
  require 'retrospec/plugins/v1/module_helpers'
2
2
  require 'retrospec/plugins/v1'
3
3
  require 'retrospec/config'
4
+ require_relative 'generators/fact_generator'
5
+ require_relative 'generators/module_generator'
4
6
  require_relative 'spec_object'
5
7
  require 'erb'
6
8
  require_relative 'template_helpers'
@@ -35,7 +37,7 @@ module Retrospec
35
37
  Utilities::PuppetModule.instance.module_path = module_path
36
38
  Utilities::PuppetModule.create_tmp_module_path # this is required to finish initialization
37
39
  # setting the context is require to make other methods below work. #TODO lazy create the context
38
- @context = ::Puppet::SpecObject.new(module_path, Utilities::PuppetModule.instance, config_data)
40
+ @context = ::Retrospec::Puppet::SpecObject.new(module_path, Utilities::PuppetModule.instance, config_data)
39
41
  end
40
42
 
41
43
  # if the module does not exist lets create it
@@ -44,17 +46,9 @@ module Retrospec
44
46
  # anything since it is not mandatory
45
47
  # I thought about using the the module face to perform this generation but it seems like its not
46
48
  # supported at this time, and you can't specify the path to generate the module in
47
- def new_module
48
- unless File.exist?(manifest_dir)
49
- init_class = File.join(manifest_dir, 'init.pp')
50
- content = File.read(File.join(template_dir, 'manifest_file.pp'))
51
- print "The module located at: #{module_path} does not exist, do you wish to create it? (y/n): "
52
- answer = gets.chomp
53
- unless answer =~ /y/i
54
- exit 1
55
- end
56
- create_manifest_file(init_class, content)
57
- end
49
+ def new_module(plugin_data)
50
+ f = Retrospec::Puppet::Generators::ModuleGenerator.run_cli(plugin_data)
51
+ f.run(manifest_dir)
58
52
  end
59
53
 
60
54
  # used to display subcommand options to tglobal_confighe cli
@@ -68,16 +62,15 @@ module Retrospec
68
62
  scm_branch = ENV['RETROSPEC_PUPPET_SCM_BRANCH'] || plugin_config['plugins::puppet::templates::ref'] || 'master'
69
63
  future_parser = plugin_config['plugins::puppet::enable_future_parser'] || false
70
64
  beaker_tests = plugin_config['plugins::puppet::enable_beaker_tests'] || false
71
- namespace = plugin_config['plugins::puppet::namespace'] || 'namespace'
72
65
  # a list of subcommands for this plugin
73
- sub_commands = [:new_module]
66
+ sub_commands = ['new_module', 'new_fact']
74
67
  if sub_commands.count > 0
75
68
  sub_command_help = "Subcommands:\n#{sub_commands.join("\n")}\n"
76
69
  else
77
70
  sub_command_help = ""
78
71
  end
79
72
  plugin_opts = Trollop::options do
80
- version "#{Retrospec::Puppet::VERSION} (c) Corey Osman"
73
+ version "Retrospec puppet plugin: #{Retrospec::Puppet::VERSION} (c) Corey Osman"
81
74
  banner <<-EOS
82
75
  Generates puppet rspec test code based on the classes and defines inside the manifests directory.\n
83
76
  #{sub_command_help}
@@ -87,12 +80,8 @@ Generates puppet rspec test code based on the classes and defines inside the man
87
80
  :required => false, :default => template_dir
88
81
  opt :scm_url, "SCM url for retrospec templates", :type => :string, :required => false,
89
82
  :default => scm_url
90
- opt :name, "The name of the module you wish to create", :type => :string, :require => :false, :short => '-n',
91
- :default => File.basename(global_opts[:module_path])
92
83
  opt :branch, "Branch you want to use for the retrospec template repo", :type => :string, :required => false,
93
84
  :default => scm_branch
94
- opt :namespace, "The namespace to use only when creating a new module", :default => namespace, :required => false,
95
- :type => :string
96
85
  opt :enable_beaker_tests, "Enable the creation of beaker tests", :require => false, :type => :boolean, :default => beaker_tests
97
86
  opt :enable_future_parser, "Enables the future parser only during validation", :default => future_parser, :require => false, :type => :boolean
98
87
  stop_on sub_commands
@@ -107,13 +96,15 @@ Generates puppet rspec test code based on the classes and defines inside the man
107
96
  if plugin.respond_to?(sub_command)
108
97
  case sub_command
109
98
  when :new_module
110
- plugin.send(sub_command)
99
+ plugin.send(sub_command, plugin_data)
111
100
  plugin.post_init # finish initialization
112
101
  when :run
113
102
  plugin.post_init # finish initialization
103
+ when :new_fact
104
+ plugin.new_fact(plugin_data)
114
105
  else
115
106
  plugin.post_init # finish initialization
116
- plugin.send(sub_command)
107
+ plugin.send(sub_command, plugin_data[:module_path], plugin_data)
117
108
  end
118
109
  plugin.send(:run)
119
110
  else
@@ -122,6 +113,18 @@ Generates puppet rspec test code based on the classes and defines inside the man
122
113
  end
123
114
  end
124
115
 
116
+ def new_fact(plugin_data)
117
+ f = Retrospec::Puppet::Generators::FactGenerator.run_cli(plugin_data)
118
+ post_init # finish initialization
119
+ f.generate_fact_file
120
+ end
121
+
122
+ # generates the fact spec files
123
+ def fact(module_path, config)
124
+ f = Retrospec::Puppet::Generators::FactGenerator.new(module_path, config)
125
+ f.generate_fact_spec_files
126
+ end
127
+
125
128
  # this is the main method the starts all the magic
126
129
  def run
127
130
  run_pre_hook
@@ -168,7 +171,8 @@ Generates puppet rspec test code based on the classes and defines inside the man
168
171
  def create_files
169
172
  types = context.types
170
173
  safe_create_module_files
171
- generate_metadata_file
174
+ fact(module_path, config_data)
175
+ Retrospec::Puppet::Generators::ModuleGenerator.generate_metadata_file(context.module_name, config_data)
172
176
  # a Type is nothing more than a defined type or puppet class
173
177
  # we could have named this manifest but there could be multiple types
174
178
  # in a manifest.
@@ -303,41 +307,6 @@ Generates puppet rspec test code based on the classes and defines inside the man
303
307
  '.pp'
304
308
  end
305
309
 
306
- def create_manifest_file(dest, content)
307
- # replace the name in the target file with the module_name from this class
308
- # I would have just used a template but the context does not exist yet
309
- new_content = content.gsub('CLASS_NAME', config_data[:name])
310
- safe_create_file(dest, new_content)
311
- end
312
-
313
- # generates the metadata file in the module directory
314
- def generate_metadata_file
315
- require 'puppet/module_tool/metadata'
316
- # make sure the metadata file exists
317
- metadata_file = File.join(module_path, 'metadata.json')
318
- unless File.exists?(metadata_file)
319
- # by default the module tool metadata checks for a namespece
320
- if ! config_data[:name].include?('-')
321
- name = "#{config_data[:namespace]}-#{config_data[:name]}"
322
- else
323
- name = config_data[:name]
324
- end
325
- begin
326
- metadata = ::Puppet::ModuleTool::Metadata.new.update(
327
- 'name' => name,
328
- 'version' => '0.1.0',
329
- 'author' => (config_data['plugins::puppet::author'] || nil ),
330
- 'dependencies' => [
331
- { 'name' => 'puppetlabs-stdlib', 'version_requirement' => '>= 1.0.0' }
332
- ]
333
- )
334
- rescue ArgumentError => e
335
- puts e.message
336
- exit -1
337
- end
338
- safe_create_file(metadata_file, metadata.to_json)
339
- end
340
- end
341
310
  end
342
311
  end
343
312
  end
@@ -1,65 +1,70 @@
1
1
  require 'retrospec/plugins/v1/context_object'
2
+ module Retrospec
3
+ module Puppet
4
+ # this object is passed to the templates for erb template rendering
5
+ # you can use data contained in this object in your templates
6
+ class SpecObject < Retrospec::Plugins::V1::ContextObject
2
7
 
3
- module Puppet
4
- # this object is passed to the templates for erb template rendering
5
- # you can use data contained in this object in your templates
6
- class SpecObject < Retrospec::Plugins::V1::ContextObject
8
+ attr_reader :instance, :module_path, :module_name, :all_hiera_data, :config
9
+ attr_accessor :enable_beaker_tests, :parameters, :types, :resources, :type
7
10
 
8
- attr_reader :instance, :module_path, :module_name, :all_hiera_data, :config
9
- attr_accessor :enable_beaker_tests, :parameters, :types, :resources, :type
10
11
 
12
+ def initialize(mod_path, instance_data, config_data)
13
+ @instance = instance_data
14
+ @config = config_data
15
+ @module_path = mod_path
16
+ all_hiera_data
17
+ end
11
18
 
12
- def initialize(mod_path, instance_data, config_data)
13
- @instance = instance_data
14
- @config = config_data
15
- @module_path = mod_path
16
- all_hiera_data
17
- end
18
-
19
- def module_name
20
- instance.module_name
21
- end
22
-
23
- def types
24
- instance.types
25
- end
19
+ def module_name
20
+ instance.module_name
21
+ end
26
22
 
27
- def class_hiera_data(classname)
28
- data = {}
29
- types.each do |t|
30
- next unless t.type == :hostclass #defines don't have hiera lookup values
31
- next unless t.name == classname
32
- t.arguments.each do |k, v|
33
- key = "#{t.name}::#{k}"
34
- data[key] = nil
35
- end
23
+ def types
24
+ instance.types
36
25
  end
37
- data
38
- end
39
26
 
40
- # gathers all the class parameters that could be used in hiera data mocking
41
- def all_hiera_data
42
- if @all_hiera_data.nil?
43
- @all_hiera_data = {}
27
+ def class_hiera_data(classname)
28
+ data = {}
44
29
  types.each do |t|
45
30
  next unless t.type == :hostclass #defines don't have hiera lookup values
31
+ next unless t.name == classname
46
32
  t.arguments.each do |k, v|
47
33
  key = "#{t.name}::#{k}"
48
- @all_hiera_data[key] = nil
34
+ data[key] = nil
49
35
  end
50
36
  end
37
+ data
51
38
  end
52
- @all_hiera_data
53
- end
54
39
 
55
- def enable_beaker_tests?
56
- config[:enable_beaker_tests]
57
- end
40
+ # gathers all the class parameters that could be used in hiera data mocking
41
+ def all_hiera_data
42
+ if @all_hiera_data.nil?
43
+ @all_hiera_data = {}
44
+ types.each do |t|
45
+ next unless t.type == :hostclass #defines don't have hiera lookup values
46
+ t.arguments.each do |k, v|
47
+ key = "#{t.name}::#{k}"
48
+ @all_hiera_data[key] = nil
49
+ end
50
+ end
51
+ end
52
+ @all_hiera_data
53
+ end
58
54
 
59
- # allows the user to use the variable store to resolve the variable if it exists
60
- def variable_value(key)
61
- VariableStore.resolve(key)
62
- end
55
+ def enable_beaker_tests?
56
+ config[:enable_beaker_tests]
57
+ end
63
58
 
59
+ # allows the user to use the variable store to resolve the variable if it exists
60
+ def variable_value(key)
61
+ VariableStore.resolve(key)
62
+ end
63
+
64
+ def fact_name
65
+ instance[:name]
66
+ end
67
+
68
+ end
64
69
  end
65
- end
70
+ end
@@ -1,5 +1,5 @@
1
1
  module Retrospec
2
2
  module Puppet
3
- VERSION = '0.10.0'
3
+ VERSION = '0.11.0'
4
4
  end
5
5
  end
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "puppet-retrospec"
8
- s.version = "0.10.0"
8
+ s.version = "0.11.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Corey Osman"]
12
- s.date = "2015-10-12"
12
+ s.date = "2015-10-26"
13
13
  s.description = "Retrofits and generates valid puppet rspec test code to existing modules"
14
14
  s.email = "corey@logicminds.biz"
15
15
  s.extra_rdoc_files = [
@@ -29,6 +29,9 @@ Gem::Specification.new do |s|
29
29
  "VERSION",
30
30
  "lib/retrospec-puppet.rb",
31
31
  "lib/retrospec/plugins/v1/plugin/conditional.rb",
32
+ "lib/retrospec/plugins/v1/plugin/generators/fact_generator.rb",
33
+ "lib/retrospec/plugins/v1/plugin/generators/facter.rb",
34
+ "lib/retrospec/plugins/v1/plugin/generators/module_generator.rb",
32
35
  "lib/retrospec/plugins/v1/plugin/helpers.rb",
33
36
  "lib/retrospec/plugins/v1/plugin/puppet.rb",
34
37
  "lib/retrospec/plugins/v1/plugin/puppet_module.rb",
@@ -40,6 +43,9 @@ Gem::Specification.new do |s|
40
43
  "lib/retrospec/plugins/v1/plugin/variable_store.rb",
41
44
  "lib/retrospec/plugins/v1/plugin/version.rb",
42
45
  "puppet-retrospec.gemspec",
46
+ "spec/fixtures/facts/datacenter_facts.rb",
47
+ "spec/fixtures/facts/facts_with_methods.rb",
48
+ "spec/fixtures/facts/node_role.rb",
43
49
  "spec/fixtures/fixture_modules/one_resource_module/manifests/another_resource.pp",
44
50
  "spec/fixtures/fixture_modules/one_resource_module/manifests/inherits_params.pp",
45
51
  "spec/fixtures/fixture_modules/one_resource_module/manifests/one_resource_class.pp",
@@ -559,6 +565,8 @@ Gem::Specification.new do |s|
559
565
  "spec/integration/retrospec_spec.rb",
560
566
  "spec/spec_helper.rb",
561
567
  "spec/unit/conditional_spec.rb",
568
+ "spec/unit/generators/fact_generater_spec.rb",
569
+ "spec/unit/generators/fact_spec.rb",
562
570
  "spec/unit/module_spec.rb",
563
571
  "spec/unit/plugin_spec.rb",
564
572
  "spec/unit/puppet-retrospec_spec.rb",
@@ -1822,7 +1830,8 @@ Gem::Specification.new do |s|
1822
1830
 
1823
1831
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
1824
1832
  s.add_runtime_dependency(%q<trollop>, [">= 0"])
1825
- s.add_runtime_dependency(%q<retrospec>, ["~> 0.4.0"])
1833
+ s.add_runtime_dependency(%q<retrospec>, ["~> 0.4"])
1834
+ s.add_runtime_dependency(%q<awesome_print>, [">= 0"])
1826
1835
  s.add_development_dependency(%q<rspec>, ["~> 3.2"])
1827
1836
  s.add_development_dependency(%q<puppet>, ["= 3.7.3"])
1828
1837
  s.add_development_dependency(%q<yard>, ["~> 0.7"])
@@ -1833,7 +1842,8 @@ Gem::Specification.new do |s|
1833
1842
  s.add_development_dependency(%q<fakefs>, [">= 0"])
1834
1843
  else
1835
1844
  s.add_dependency(%q<trollop>, [">= 0"])
1836
- s.add_dependency(%q<retrospec>, ["~> 0.4.0"])
1845
+ s.add_dependency(%q<retrospec>, ["~> 0.4"])
1846
+ s.add_dependency(%q<awesome_print>, [">= 0"])
1837
1847
  s.add_dependency(%q<rspec>, ["~> 3.2"])
1838
1848
  s.add_dependency(%q<puppet>, ["= 3.7.3"])
1839
1849
  s.add_dependency(%q<yard>, ["~> 0.7"])
@@ -1845,7 +1855,8 @@ Gem::Specification.new do |s|
1845
1855
  end
1846
1856
  else
1847
1857
  s.add_dependency(%q<trollop>, [">= 0"])
1848
- s.add_dependency(%q<retrospec>, ["~> 0.4.0"])
1858
+ s.add_dependency(%q<retrospec>, ["~> 0.4"])
1859
+ s.add_dependency(%q<awesome_print>, [">= 0"])
1849
1860
  s.add_dependency(%q<rspec>, ["~> 3.2"])
1850
1861
  s.add_dependency(%q<puppet>, ["= 3.7.3"])
1851
1862
  s.add_dependency(%q<yard>, ["~> 0.7"])
@@ -0,0 +1,15 @@
1
+ # this is an example of a fact file with multiple facts
2
+ Facter.add(:fact1) do
3
+ confine :kernel => 'Linux'
4
+ setcode do
5
+ 'value1'
6
+ end
7
+ end
8
+ Facter.add(:fact2) do
9
+ confine :kernel => 'Windows'
10
+ setcode do
11
+ 'value2'
12
+ Facter::Core::Execution.execute('which lsb')
13
+
14
+ end
15
+ end
@@ -0,0 +1,19 @@
1
+ # this is just an example fact that uses method logic outside the Facter.add block
2
+ def default_kernel
3
+ if Facter.value(:kernel) == 'Windows'
4
+ 'Windows'
5
+ else
6
+ 'Linux'
7
+ end
8
+ end
9
+
10
+ Facter.add(:method_fact) do
11
+ confine :kernel => 'Linux'
12
+ confine :osfamily => 'RedHat'
13
+ setcode do
14
+ is_virtual = Facter.fact(:is_virtual).value
15
+ default_kernel
16
+ Facter::Core::Execution.execute('which lsb')
17
+ end
18
+ end
19
+
@@ -0,0 +1,8 @@
1
+ # this is just an example fact that uses confines and returns a default value
2
+ Facter.add(:node_role) do
3
+ confine :kernel => 'Windows'
4
+ confine :is_virtual => true
5
+ setcode do
6
+ 'default_role'
7
+ end
8
+ end
data/spec/spec_helper.rb CHANGED
@@ -11,6 +11,10 @@ def fixtures_path
11
11
  @fixtures_path ||= File.expand_path(File.join(File.dirname(__FILE__), 'fixtures'))
12
12
  end
13
13
 
14
+ def fixtures_facts_path
15
+ @fixtures_facts_path ||= File.expand_path(File.join(fixtures_path, 'facts'))
16
+ end
17
+
14
18
  def clean_up_spec_dir(dir)
15
19
  #puts "removing directory #{dir}"
16
20
  FileUtils.rm_rf(File.join(dir, 'spec'))
@@ -2,9 +2,6 @@ require 'spec_helper'
2
2
 
3
3
  describe "conditional" do
4
4
 
5
-
6
-
7
-
8
5
  after :all do
9
6
  # enabling the removal slows down tests, but from time to time we may need to
10
7
  FileUtils.rm_rf(fixture_modules_path) if ENV['RETROSPEC_CLEAN_UP_TEST_MODULES'] =~ /true/
@@ -0,0 +1,53 @@
1
+ require 'spec_helper'
2
+
3
+ describe "fact generator" do
4
+
5
+ before :each do
6
+ FileUtils.rm_rf(facter_spec_dir)
7
+ allow(generator).to receive(:facter_dir).and_return(fixtures_facts_path)
8
+ allow(generator).to receive(:fact_name_path).and_return(File.join(module_path, 'lib', 'facter', "#{generator.fact_name}.rb"))
9
+ end
10
+
11
+ after :each do
12
+ FileUtils.rm_f(generator.fact_name_path) # ensure the file does not exist
13
+ end
14
+
15
+ let(:facter_spec_dir) do
16
+ File.join(module_path, 'spec', 'unit', 'facter')
17
+ end
18
+
19
+ let(:module_path) do
20
+ File.join(fixture_modules_path, 'tomcat')
21
+ end
22
+
23
+ let(:context) do
24
+ {:name => 'datacenter', :template_dir => File.expand_path(File.join(ENV['HOME'], '.retrospec', 'repos', 'retrospec-puppet-templates'))}
25
+ end
26
+
27
+ let(:generator) do
28
+ Retrospec::Puppet::Generators::FactGenerator.new(module_path, context )
29
+ end
30
+
31
+ it 'returns facter dir' do
32
+ expect(generator.facter_dir).to eq(fixtures_facts_path)
33
+ end
34
+
35
+ it 'returns module path' do
36
+ expect(generator.facter_spec_dir).to eq(facter_spec_dir)
37
+ end
38
+
39
+ it 'can return fact name' do
40
+ expect(generator.fact_name).to eq('datacenter')
41
+ end
42
+
43
+ it 'can generate a fact file' do
44
+ expect(generator.generate_fact_file.count).to eq(3)
45
+ expect(File.exists?(File.join(generator.facter_dir, "#{generator.fact_name}.rb")))
46
+ end
47
+
48
+ it 'can generate a spec file' do
49
+
50
+ expect(generator.generate_fact_spec_files.count).to eq(3)
51
+ end
52
+
53
+ end
@@ -0,0 +1,58 @@
1
+ require 'spec_helper'
2
+
3
+ describe "facter" do
4
+
5
+ let(:file) do
6
+ File.join(fixtures_facts_path , 'node_role.rb')
7
+ end
8
+
9
+ it 'can eval code' do
10
+ models = Retrospec::Puppet::Generators::Facter.load_fact(file)
11
+ fact_name = models.facts.keys.first
12
+ fact_data = models.facts[fact_name]
13
+ confines = fact_data.confines
14
+ model_facts = models.facts[fact_name].used_facts
15
+ global_used_facts = models.global_used_facts
16
+ expect(fact_name).to eq(:node_role)
17
+ expect(confines).to eq([{:kernel=>"Windows"}, {:is_virtual=>true}])
18
+ expect(model_facts).to eq({})
19
+ expect(global_used_facts).to eq({})
20
+ end
21
+
22
+ describe 'multiple facts' do
23
+ let(:file) do
24
+ File.join(fixtures_facts_path , 'datacenter_facts.rb')
25
+ end
26
+
27
+ it 'can eval code with multiple facts' do
28
+ models = Retrospec::Puppet::Generators::Facter.load_fact(file)
29
+ global_used_facts = models[:global_used_facts]
30
+ fact_name = models.facts.keys.first
31
+ fact_data = models.facts[fact_name]
32
+ confines = fact_data.confines
33
+ model_facts = fact_data.used_facts
34
+ expect(fact_name).to eq(:fact1)
35
+ expect(confines).to eq([{:kernel=>"Linux"}])
36
+ expect(model_facts).to eq({})
37
+ expect(global_used_facts).to eq({})
38
+ fact_name = models.facts.keys.last
39
+ fact_data = models.facts[fact_name]
40
+ confines = fact_data.confines
41
+ model_facts = fact_data.used_facts
42
+ expect(fact_name).to eq(:fact2)
43
+ expect(confines).to eq([{:kernel=>"Windows"}])
44
+ expect(model_facts).to eq({})
45
+ expect(global_used_facts).to eq({})
46
+ end
47
+ end
48
+
49
+ describe 'fact value' do
50
+ let(:file) do
51
+ File.join(fixtures_facts_path , 'facts_with_methods.rb')
52
+ end
53
+ it 'can be processed' do
54
+ Retrospec::Puppet::Generators::Facter.load_fact(file)
55
+ end
56
+ end
57
+
58
+ end
@@ -63,10 +63,13 @@ describe "puppet-retrospec" do
63
63
  it 'should create a module when it does not exist' do
64
64
  opts = {'plugins::puppet::author' => 'test_name', :module_path => '/tmp/new_module', :create => true,
65
65
  :namespace => 'retrospec', :enable_beaker_tests => false,
66
- :enable_user_templates => false, :name => 'moduletest', :template_dir => nil, :enable_future_parser => true }
66
+ :enable_user_templates => false, :name => 'moduletest',
67
+ :template_dir => File.expand_path(File.join(ENV['HOME'], '.retrospec', 'repos', 'retrospec-puppet-templates')),
68
+ :enable_future_parser => true }
69
+ ENV['RETROSPEC_PUPPET_AUTO_GENERATE'] = 'true'
67
70
  new_module = Retrospec::Plugins::V1::Puppet.new(opts[:module_path], opts)
68
71
  allow(new_module).to receive(:gets).and_return("y\n")
69
- new_module.new_module
72
+ new_module.new_module(opts)
70
73
  new_module.post_init
71
74
  new_module.run
72
75
  expect(File.exists?(File.join(new_module.manifest_dir, 'init.pp'))).to eq(true)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: puppet-retrospec
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.10.0
4
+ version: 0.11.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Corey Osman
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-10-12 00:00:00.000000000 Z
11
+ date: 2015-10-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: trollop
@@ -30,14 +30,28 @@ dependencies:
30
30
  requirements:
31
31
  - - ~>
32
32
  - !ruby/object:Gem::Version
33
- version: 0.4.0
33
+ version: '0.4'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - ~>
39
39
  - !ruby/object:Gem::Version
40
- version: 0.4.0
40
+ version: '0.4'
41
+ - !ruby/object:Gem::Dependency
42
+ name: awesome_print
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
41
55
  - !ruby/object:Gem::Dependency
42
56
  name: rspec
43
57
  requirement: !ruby/object:Gem::Requirement
@@ -170,6 +184,9 @@ files:
170
184
  - VERSION
171
185
  - lib/retrospec-puppet.rb
172
186
  - lib/retrospec/plugins/v1/plugin/conditional.rb
187
+ - lib/retrospec/plugins/v1/plugin/generators/fact_generator.rb
188
+ - lib/retrospec/plugins/v1/plugin/generators/facter.rb
189
+ - lib/retrospec/plugins/v1/plugin/generators/module_generator.rb
173
190
  - lib/retrospec/plugins/v1/plugin/helpers.rb
174
191
  - lib/retrospec/plugins/v1/plugin/puppet.rb
175
192
  - lib/retrospec/plugins/v1/plugin/puppet_module.rb
@@ -181,6 +198,9 @@ files:
181
198
  - lib/retrospec/plugins/v1/plugin/variable_store.rb
182
199
  - lib/retrospec/plugins/v1/plugin/version.rb
183
200
  - puppet-retrospec.gemspec
201
+ - spec/fixtures/facts/datacenter_facts.rb
202
+ - spec/fixtures/facts/facts_with_methods.rb
203
+ - spec/fixtures/facts/node_role.rb
184
204
  - spec/fixtures/fixture_modules/one_resource_module/manifests/another_resource.pp
185
205
  - spec/fixtures/fixture_modules/one_resource_module/manifests/inherits_params.pp
186
206
  - spec/fixtures/fixture_modules/one_resource_module/manifests/one_resource_class.pp
@@ -700,6 +720,8 @@ files:
700
720
  - spec/integration/retrospec_spec.rb
701
721
  - spec/spec_helper.rb
702
722
  - spec/unit/conditional_spec.rb
723
+ - spec/unit/generators/fact_generater_spec.rb
724
+ - spec/unit/generators/fact_spec.rb
703
725
  - spec/unit/module_spec.rb
704
726
  - spec/unit/plugin_spec.rb
705
727
  - spec/unit/puppet-retrospec_spec.rb