souschef 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
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