souschef 0.4.0

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 (43) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +22 -0
  3. data/Gemfile +4 -0
  4. data/LICENSE.txt +22 -0
  5. data/README.md +177 -0
  6. data/Rakefile +1 -0
  7. data/bin/souschef +33 -0
  8. data/data/chefspec/chefspec.erb +6 -0
  9. data/data/chefspec/spec_helper.rb +8 -0
  10. data/data/gemfile.yml +23 -0
  11. data/data/license.erb +3 -0
  12. data/data/metadata.erb +7 -0
  13. data/data/rakefile.erb +39 -0
  14. data/data/readme.erb +47 -0
  15. data/data/recipe/recipe.erb +6 -0
  16. data/data/rubocop/rubocop.yml +19 -0
  17. data/data/serverspec/serverspec.erb +2 -0
  18. data/data/serverspec/serverspec_helper.rb +10 -0
  19. data/data/testkitchen/kitchen.default.erb +22 -0
  20. data/lib/souschef.rb +16 -0
  21. data/lib/souschef/berkshelf.rb +93 -0
  22. data/lib/souschef/config.rb +20 -0
  23. data/lib/souschef/configure/file.rb +46 -0
  24. data/lib/souschef/gemfile.rb +42 -0
  25. data/lib/souschef/print.rb +40 -0
  26. data/lib/souschef/runner.rb +104 -0
  27. data/lib/souschef/scaffold.rb +145 -0
  28. data/lib/souschef/template.rb +26 -0
  29. data/lib/souschef/template/base.rb +69 -0
  30. data/lib/souschef/template/chefspec.rb +26 -0
  31. data/lib/souschef/template/license.rb +25 -0
  32. data/lib/souschef/template/metadata.rb +30 -0
  33. data/lib/souschef/template/rakefile.rb +23 -0
  34. data/lib/souschef/template/readme.rb +24 -0
  35. data/lib/souschef/template/rubocop.rb +22 -0
  36. data/lib/souschef/template/serverspec.rb +27 -0
  37. data/lib/souschef/testkitchen.rb +135 -0
  38. data/lib/souschef/testkitchen/docker.rb +97 -0
  39. data/lib/souschef/testkitchen/solusvm.rb +101 -0
  40. data/lib/souschef/testkitchen/virtualbox.rb +66 -0
  41. data/lib/souschef/version.rb +4 -0
  42. data/souschef.gemspec +33 -0
  43. metadata +254 -0
@@ -0,0 +1,26 @@
1
+ require 'souschef/template/base'
2
+ require 'souschef/template/metadata'
3
+ require 'souschef/template/license'
4
+ require 'souschef/template/readme'
5
+ require 'souschef/template/rubocop'
6
+ require 'souschef/template/chefspec'
7
+ require 'souschef/template/serverspec'
8
+ require 'souschef/template/rakefile'
9
+
10
+ module Souschef
11
+ # Creates various files from predefined templates
12
+ class Template
13
+ # Public - Create needed standardised files
14
+ #
15
+ # Returns nil
16
+ def self.run(opts)
17
+ Souschef::Template::Rubocop.new(opts).create
18
+ Souschef::Template::Chefspec.new(opts).create
19
+ Souschef::Template::Serverspec.new(opts).create
20
+ Souschef::Template::Metadata.new(opts).create
21
+ Souschef::Template::License.new(opts).create
22
+ Souschef::Template::Readme.new(opts).create
23
+ Souschef::Template::Rakefile.new(opts).create
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,69 @@
1
+ module Souschef
2
+ class Template
3
+ # Base class containing reusable functions
4
+ class Base
5
+ attr_accessor :path, :ots
6
+
7
+ def initialize(opts)
8
+ @opts = opts
9
+ @path = opts[:path]
10
+ end
11
+
12
+ private
13
+
14
+ # Private - Return location of a custom template file if it exists, or
15
+ # return the default version
16
+ #
17
+ # Return String
18
+ def datafile_path(file)
19
+ local_profile = "~/.souschef/#{@opts[:profile]}/#{file}"
20
+ profile = File.expand_path(local_profile, __FILE__)
21
+
22
+ if File.exist?(profile)
23
+ profile
24
+ else
25
+ p = "../../../../data/#{file}"
26
+ File.expand_path(p, __FILE__)
27
+ end
28
+ end
29
+
30
+ # Private - Print out message if verbose option is selected
31
+ #
32
+ # Return nil
33
+ def info(msg)
34
+ Souschef::Print.info(msg) if @opts[:verbose]
35
+ end
36
+
37
+ # Private - Return path to the file inside cookbook directory
38
+ #
39
+ # Return String
40
+ def cookbook_file_path(file)
41
+ File.join(@path, file)
42
+ end
43
+
44
+ # Private - Write data to the desired file
45
+ #
46
+ # Returns nil
47
+ def write_file(file, data)
48
+ File.open(file, 'w') { |fd| fd.write(data) }
49
+ end
50
+
51
+ # Private - Load ERB template
52
+ #
53
+ # file - String file name
54
+ #
55
+ # Returns String
56
+ def load_erb_file(file)
57
+ File.read(datafile_path(file))
58
+ end
59
+
60
+ # Private - Creates spec/ directory if missing
61
+ #
62
+ # Return nil
63
+ def create_spec_dir(spec_dir)
64
+ info "Create #{spec_dir} directory"
65
+ Dir.mkdir(spec_dir)
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,26 @@
1
+ module Souschef
2
+ class Template
3
+ # Create spechelper for Chefspec
4
+ class Chefspec < Souschef::Template::Base
5
+ def initialize(opts)
6
+ super(opts)
7
+ end
8
+ # Public - Create spec/spec_helper.rb file
9
+ #
10
+ # cookbook - String Cookbook name
11
+ #
12
+ # Returns nil
13
+ def create
14
+ spec_dir = File.join(@path, 'spec')
15
+
16
+ tmpl = ERB.new(load_erb_file('chefspec/spec_helper.rb'))
17
+ data = tmpl.result(binding)
18
+
19
+ create_spec_dir(spec_dir) unless File.directory?(spec_dir)
20
+
21
+ info 'Creating Chefspec helper'
22
+ write_file(cookbook_file_path('spec/spec_helper.rb'), data)
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,25 @@
1
+ module Souschef
2
+ class Template
3
+ # Create standard LICENSE
4
+ class License < Souschef::Template::Base
5
+ def initialize(opts)
6
+ super(opts)
7
+ end
8
+
9
+ # Public - Create a valid License file
10
+ #
11
+ # cookbook - String Cookbook name
12
+ #
13
+ # Returns nil
14
+ def create
15
+ tmpl = ERB.new(load_erb_file('license.erb'))
16
+ @year = Time.now.year
17
+ @maintainer = @opts[:souschef][:maintainer]
18
+ data = tmpl.result(binding)
19
+
20
+ info 'Updating LICENSE file'
21
+ write_file(cookbook_file_path('LICENSE'), data)
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,30 @@
1
+ # Souschef
2
+ module Souschef
3
+ class Template
4
+ # Creates a well defined maetadata.rb
5
+ class Metadata < Souschef::Template::Base
6
+ attr_accessor :cookbook
7
+
8
+ def initialize(opts)
9
+ super(opts)
10
+ end
11
+
12
+ # Public - Create file start
13
+ #
14
+ # cookbook - String cookbook name
15
+ #
16
+ # Returns nil
17
+ def create
18
+ tmpl = ERB.new(load_erb_file('metadata.erb'))
19
+ @cookbook = @opts[:cookbook]
20
+ @maintainer = @opts[:souschef][:maintainer]
21
+ @maintainer_email = @opts[:souschef][:maintainer_email]
22
+ @license = @opts[:souschef][:license]
23
+ data = tmpl.result(binding)
24
+
25
+ info 'Updating metadata.rb'
26
+ write_file(cookbook_file_path('metadata.rb'), data)
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,23 @@
1
+ module Souschef
2
+ class Template
3
+ # Add Rakefile for testing support
4
+ class Rakefile < Souschef::Template::Base
5
+ def initialize(opts)
6
+ super(opts)
7
+ end
8
+
9
+ # Public - Create a Rakefile from our Template
10
+ #
11
+ # cookbook - String Cookbook name
12
+ #
13
+ # Returns nil
14
+ def create
15
+ tmpl = ERB.new(load_erb_file('rakefile.erb'))
16
+ data = tmpl.result(binding)
17
+
18
+ info 'Setting up Rakefile'
19
+ write_file(cookbook_file_path('Rakefile'), data)
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,24 @@
1
+ module Souschef
2
+ class Template
3
+ # Updates README.md inside cookbook folder
4
+ class Readme < Souschef::Template::Base
5
+ def initialize(opts)
6
+ super(opts)
7
+ end
8
+
9
+ # Public - Create standardised README
10
+ #
11
+ # Return nil
12
+ def create
13
+ tmpl = ERB.new(load_erb_file('readme.erb'))
14
+ @cookbook = @opts[:cookbook]
15
+ @maintainer = @opts[:souschef][:maintainer]
16
+ @maintainer_email = @opts[:souschef][:maintainer_email]
17
+ data = tmpl.result(binding)
18
+
19
+ info 'Updating README file'
20
+ write_file(cookbook_file_path('README.md'), data)
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,22 @@
1
+ module Souschef
2
+ class Template
3
+ # Configure Rubocop configuratiopn
4
+ class Rubocop < Souschef::Template::Base
5
+ def initialize(opts)
6
+ super(opts)
7
+ end
8
+ # Public - Create a .rubocop file
9
+ #
10
+ # cookbook - String Cookbook name
11
+ #
12
+ # Returns nil
13
+ def create
14
+ tmpl = ERB.new(load_erb_file('rubocop/rubocop.yml'))
15
+ data = tmpl.result(binding)
16
+
17
+ info 'Setting up Rubocop configuration'
18
+ write_file(cookbook_file_path('.rubocop.yml'), data)
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,27 @@
1
+ module Souschef
2
+ class Template
3
+ # Serverspec configurator
4
+ class Serverspec < Souschef::Template::Base
5
+ def initialize(opts)
6
+ super(opts)
7
+ end
8
+ # Public - Create serverspec helper
9
+ #
10
+ # cookbook - String Cookbook name
11
+ #
12
+ # Returns nil
13
+ def create
14
+ spec_dir = File.join(@path, 'test', 'integration', 'default',
15
+ 'serverspec')
16
+ spec_helper = File.join(spec_dir, 'spec_helper.rb')
17
+
18
+ tmpl = ERB.new(load_erb_file('serverspec/serverspec_helper.rb'))
19
+ data = tmpl.result(binding)
20
+
21
+ create_spec_dir(spec_dir) unless File.directory?(spec_dir)
22
+ info 'Creating Serverspec helper'
23
+ write_file(spec_helper, data)
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,135 @@
1
+ require 'souschef/testkitchen/docker'
2
+ require 'souschef/testkitchen/solusvm'
3
+ require 'souschef/testkitchen/virtualbox'
4
+
5
+ module Souschef
6
+ # TestKitchen generator
7
+ class Testkitchen
8
+ attr_accessor :files, :cookbook, :opts, :metadata
9
+
10
+ def initialize(opts)
11
+ @opts = opts
12
+ @cookbook = opts[:cookbook]
13
+ @file = kitchen_driver_file
14
+ metadata_info
15
+ end
16
+
17
+ # Public - Write down TestKitchen configuration
18
+ #
19
+ # Returns nil
20
+ def configure
21
+ if @opts[:docker]
22
+ Souschef::Print.info 'Creating Docker configuration .kitchen.local.yml'
23
+ write(:docker, Souschef::Testkitchen::Docker.new(@cookbook).yaml)
24
+ end
25
+ if @opts[:solusvm]
26
+ Souschef::Print.info 'Creating SolusVM configuraton .kitchen.local.yml'
27
+ write(:solusvm, Souschef::Testkitchen::Solusvm.new(@cookbook).yaml)
28
+ end
29
+
30
+ Souschef::Print.info 'Creating Vagrant configuration in .kitchen.yml'
31
+ write(:virtualbox, Souschef::Testkitchen::Virtualbox.new(@cookbook).yaml)
32
+ end
33
+
34
+ # Public - Copy the already generated files from the data/ directory
35
+ #
36
+ # Returns nil
37
+ def setup
38
+ templates = ['default']
39
+ templates << @opts[:testkitchen] if @opts[:testkitchen]
40
+
41
+ templates.each { |type| create_file(type) }
42
+ end
43
+
44
+ private
45
+
46
+ # Private - Read metadata file
47
+ #
48
+ # Return Hash
49
+ def metadata_info
50
+ @metadata = Chef::Cookbook::Metadata.new
51
+ @metadata.from_file(File.join(@opts[:path], 'metadata.rb'))
52
+ end
53
+
54
+ # Private - Creates the TestKitchen YML file based on the provided template
55
+ #
56
+ # Returns nil
57
+ def create_file(type)
58
+ cb_file, source_file = get_locations(type)
59
+
60
+ File.open(cb_file, 'w') { |f| f.write(process_template(source_file)) }
61
+
62
+ if @opts[:verbose]
63
+ Souschef::Print.info "Creating Testkitchen #{type} configuration"
64
+ end
65
+ rescue TypeError
66
+ Souschef::Print.error 'SKipping'
67
+ end
68
+
69
+ # Private - Return location of cookbook file and source template file
70
+ #
71
+ # Return Array
72
+ def get_locations(type)
73
+ case type
74
+ when 'default'
75
+ cb_file = File.join(@opts[:path], '.kitchen.yml')
76
+ source_file = template_location(type)
77
+ else
78
+ cb_file = File.join(@opts[:path], '.kitchen.local.yml')
79
+ source_file = template_location(type)
80
+ end
81
+
82
+ [cb_file, source_file]
83
+ end
84
+
85
+ # Private - Generate the .kitchen.yml file based on our cookbook
86
+ #
87
+ # Returns String
88
+ def process_template(source_file)
89
+ rfile = ERB.new(File.read(source_file))
90
+ @cookbook = @metadata.name
91
+
92
+ rfile.result(binding)
93
+ end
94
+
95
+ # Private - Return location of the preconfigured .kitchen*.yml files
96
+ #
97
+ # Returns String
98
+ def template_location(type)
99
+ local = File.expand_path(
100
+ "~/.souschef/#{@opts[:profile]}/testkitchen/kitchen.#{type}.erb",
101
+ __FILE__)
102
+
103
+ bundled = File.expand_path(
104
+ "../../../data/testkitchen/kitchen.#{type}.erb", __FILE__)
105
+
106
+ if !File.exist?(local) && !File.exist?(bundled)
107
+ if @opts[:verbose]
108
+ Souschef::Print.error "Missing custom configuration for TestKitchen \
109
+ #{@opts[:testkitchen]} configuration"
110
+ end
111
+ else
112
+ File.exist?(local) ? local : bundled
113
+ end
114
+ end
115
+
116
+ # Private - Return full locations for files
117
+ #
118
+ # Returns Hash
119
+ def kitchen_driver_file
120
+ { virtualbox: File.join(@opts[:path], '.kitchen.yml'),
121
+ docker: File.join(@opts[:path], '.kitchen.local.yml'),
122
+ solusvm: File.join(@opts[:path], '.kitchen.local.yml')
123
+ }
124
+ end
125
+
126
+ # Private - Write down the configuration file
127
+ #
128
+ # Returns nile
129
+ def write(driver, data)
130
+ fd = File.open(kitchen_driver_file[driver], 'w')
131
+ fd.write(data)
132
+ fd.close unless fd.nil?
133
+ end
134
+ end
135
+ end
@@ -0,0 +1,97 @@
1
+ module Souschef
2
+ class Testkitchen
3
+ # Testkitchen Docker configuration
4
+ class Docker
5
+ attr_accessor :config, :cookbook
6
+
7
+ def initialize(cookbook)
8
+ @cookbook = cookbook
9
+ populate_configuration
10
+ end
11
+
12
+ # Public - Return YAML formatted data
13
+ #
14
+ # Returns String
15
+ def yaml
16
+ @config.to_yaml
17
+ end
18
+
19
+ private
20
+
21
+ # Private - Populate @config
22
+ #
23
+ # Returns nil
24
+ def populate_configuration
25
+ @config = { 'driver' => define_driver,
26
+ 'provisioner' => define_provisioner,
27
+ 'platforms' => define_platforms,
28
+ 'suits' => define_suits }
29
+ end
30
+
31
+ # Private - Define driver section
32
+ #
33
+ # Returns Hash
34
+ def define_driver
35
+ { 'name' => 'docker',
36
+ 'privileged' => true
37
+ }
38
+ end
39
+
40
+ # Private - Define provisioner
41
+ #
42
+ # Returns Hash
43
+ def define_provisioner
44
+ { 'name' => 'chef_zero',
45
+ 'require_chef_omnibus' => 'latest' }
46
+ end
47
+
48
+ # Private - Define platforms configuration
49
+ #
50
+ # Returns Array
51
+ def define_platforms
52
+ if define_run_list['run_list'].empty?
53
+ [define_centos_5, define_centos_6]
54
+ else
55
+ [define_centos_5, define_centos_6, define_run_list]
56
+ end
57
+ end
58
+
59
+ # Private - Define CentOS 5.10 platforms
60
+ #
61
+ # Returns Hash
62
+ def define_centos_5
63
+ { 'name' => 'centos-5.10',
64
+ 'driver_config' => { 'image' => 'akrasic/centos5',
65
+ 'platform' => 'centos',
66
+ 'use_sudo' => false,
67
+ 'privileged' => true } }
68
+ end
69
+
70
+ # Private - Define CentOS 6.4 platform
71
+ #
72
+ # Returns Hash
73
+ def define_centos_6
74
+ { 'name' => 'centos-6.4',
75
+ 'driver_config' => { 'image' => 'centos:6.4',
76
+ 'platform' => 'centos',
77
+ 'use_sudo' => false,
78
+ 'privileged' => true } }
79
+ end
80
+
81
+ # Private - Define Runlist for platforms
82
+ #
83
+ # Returs Hash
84
+ def define_run_list
85
+ { 'run_list' => '' }
86
+ end
87
+
88
+ # Private - Define suits
89
+ #
90
+ # Returns Hash
91
+ def define_suits
92
+ [{ 'name' => 'default',
93
+ 'run_list' => ["recipe[#{@cookbook}::default]"] }]
94
+ end
95
+ end
96
+ end
97
+ end