berkshelf 0.4.0.rc1 → 0.4.0.rc2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (32) hide show
  1. data/bin/berks +6 -1
  2. data/features/cookbook_command.feature +39 -0
  3. data/features/step_definitions/cli_steps.rb +8 -0
  4. data/features/step_definitions/filesystem_steps.rb +120 -1
  5. data/features/support/env.rb +1 -1
  6. data/lib/berkshelf.rb +16 -4
  7. data/lib/berkshelf/base_generator.rb +20 -0
  8. data/lib/berkshelf/berksfile.rb +18 -10
  9. data/lib/berkshelf/cli.rb +36 -18
  10. data/lib/berkshelf/cookbook_generator.rb +112 -0
  11. data/lib/berkshelf/cookbook_source/git_location.rb +1 -0
  12. data/lib/berkshelf/dsl.rb +7 -1
  13. data/lib/berkshelf/generator_files/Gemfile.erb +12 -0
  14. data/lib/berkshelf/generator_files/README.md.erb +13 -0
  15. data/lib/berkshelf/generator_files/Thorfile.erb +11 -0
  16. data/lib/berkshelf/generator_files/Vagrantfile.erb +63 -0
  17. data/lib/berkshelf/generator_files/chefignore +1 -0
  18. data/lib/berkshelf/generator_files/default_recipe.erb +6 -0
  19. data/lib/berkshelf/generator_files/gitignore.erb +6 -0
  20. data/lib/berkshelf/generator_files/licenses/apachev2.erb +13 -0
  21. data/lib/berkshelf/generator_files/licenses/gplv2.erb +15 -0
  22. data/lib/berkshelf/generator_files/licenses/gplv3.erb +14 -0
  23. data/lib/berkshelf/generator_files/licenses/mit.erb +20 -0
  24. data/lib/berkshelf/generator_files/licenses/reserved.erb +3 -0
  25. data/lib/berkshelf/generator_files/metadata.rb.erb +12 -0
  26. data/lib/berkshelf/init_generator.rb +69 -12
  27. data/lib/berkshelf/version.rb +1 -1
  28. data/spec/unit/berkshelf/berksfile_spec.rb +20 -20
  29. data/spec/unit/berkshelf/cookbook_generator_spec.rb +79 -0
  30. data/spec/unit/berkshelf/git_spec.rb +9 -9
  31. data/spec/unit/berkshelf/init_generator_spec.rb +107 -7
  32. metadata +20 -2
@@ -52,6 +52,7 @@ module Berkshelf
52
52
  end
53
53
 
54
54
  cb_path = File.join(destination, "#{self.name}-#{Git.rev_parse(tmp_clone)}")
55
+ FileUtils.rm_rf(cb_path)
55
56
  FileUtils.mv(tmp_clone, cb_path, force: true)
56
57
 
57
58
  cached = CachedCookbook.from_store_path(cb_path)
@@ -15,7 +15,7 @@ module Berkshelf
15
15
  end
16
16
 
17
17
  def metadata(options = {})
18
- path = options[:path] || File.expand_path('.')
18
+ path = options[:path] || File.dirname(filepath)
19
19
 
20
20
  metadata_file = Berkshelf.find_metadata(path)
21
21
 
@@ -35,5 +35,11 @@ module Berkshelf
35
35
  source = CookbookSource.new(name, path: File.dirname(metadata_file))
36
36
  add_source(source)
37
37
  end
38
+
39
+ private
40
+
41
+ def filepath
42
+ File.join(File.expand_path('.'), "DSLFile")
43
+ end
38
44
  end
39
45
  end
@@ -0,0 +1,12 @@
1
+ source "http://rubygems.org"
2
+
3
+ gem 'berkshelf'
4
+ <% if options[:foodcritic] -%>
5
+ gem 'thor-foodcritic'
6
+ <% end -%>
7
+ <% if options[:scmversion] -%>
8
+ gem 'thor-scmversion'
9
+ <% end -%>
10
+ <% if options[:vagrant] -%>
11
+ gem 'vagrant', '~> 1.0.3'
12
+ <% end -%>
@@ -0,0 +1,13 @@
1
+ # <%= name %> cookbook
2
+
3
+ # Requirements
4
+
5
+ # Usage
6
+
7
+ # Attributes
8
+
9
+ # Recipes
10
+
11
+ # Author
12
+
13
+ Author:: <%= maintainer %> (<<%= maintainer_email %>>)
@@ -0,0 +1,11 @@
1
+ # encoding: utf-8
2
+
3
+ require 'bundler'
4
+ require 'bundler/setup'
5
+ <% if options[:foodcritic] -%>
6
+ require 'thor/foodcritic'
7
+ <% end -%>
8
+ <% if options[:scmversion] -%>
9
+ require 'thor/scmversion'
10
+ <% end -%>
11
+ require 'berkshelf/thor'
@@ -0,0 +1,63 @@
1
+ Vagrant::Config.run do |config|
2
+ # All Vagrant configuration is done here. The most common configuration
3
+ # options are documented and commented below. For a complete reference,
4
+ # please see the online documentation at vagrantup.com.
5
+
6
+ config.vm.host_name = "<%= cookbook_name %>-berkshelf"
7
+
8
+ # CentOS 6.3
9
+ config.vm.box = "Berkshelf-CentOS-6.3-x86_64-minimal"
10
+ config.vm.box_url = "https://dl.dropbox.com/u/31081437/Berkshelf-CentOS-6.3-x86_64-minimal.box"
11
+
12
+ # Boot with a GUI so you can see the screen. (Default is headless)
13
+ # config.vm.boot_mode = :gui
14
+
15
+ # Assign this VM to a host-only network IP, allowing you to access it
16
+ # via the IP. Host-only networks can talk to the host machine as well as
17
+ # any other machines on the same network, but cannot be accessed (through this
18
+ # network interface) by any external networks.
19
+ config.vm.network :hostonly, "33.33.33.10"
20
+
21
+ # Assign this VM to a bridged network, allowing you to connect directly to a
22
+ # network using the host's network device. This makes the VM appear as another
23
+ # physical device on your network.
24
+ # config.vm.network :bridged
25
+
26
+ # Forward a port from the guest to the host, which allows for outside
27
+ # computers to access the VM, whereas host only networking does not.
28
+ # config.vm.forward_port 80, 8080
29
+
30
+ # Share an additional folder to the guest VM. The first argument is
31
+ # an identifier, the second is the path on the guest to mount the
32
+ # folder, and the third is the path on the host to the actual folder.
33
+ # config.vm.share_folder "v-data", "/vagrant_data", "../data"
34
+
35
+ config.ssh.max_tries = 40
36
+ config.ssh.timeout = 120
37
+
38
+ config.vm.provision :chef_solo do |chef|
39
+ chef.cookbooks_path = ["cookbooks"]
40
+
41
+ chef.json = {
42
+ :mysql => {
43
+ :server_root_password => 'rootpass',
44
+ :server_debian_password => 'debpass',
45
+ :server_repl_password => 'replpass'
46
+ }
47
+ }
48
+
49
+ chef.run_list = [
50
+ "recipe[<%= cookbook_name %>::default]"
51
+ ]
52
+ end
53
+
54
+ # config.vm.provision :chef_client do |chef|
55
+ # chef.chef_server_url = 'https://api.opscode.com/organizations/vialstudios'
56
+ # chef.validation_client_name = 'vialstudios-validator'
57
+ # chef.validation_key_path = '/Users/reset/.chef/vialstudios-validator.pem'
58
+ #
59
+ # chef.run_list = [
60
+ # "recipe[<%= cookbook_name %>::default]"
61
+ # ]
62
+ # end
63
+ end
@@ -46,3 +46,4 @@ features/*
46
46
  # Berkshelf
47
47
  Berksfile
48
48
  Berksfile.lock
49
+ cookbooks/*
@@ -0,0 +1,6 @@
1
+ #
2
+ # Cookbook Name:: <%= name %>
3
+ # Recipe:: default
4
+ #
5
+ <%= commented(license) %>
6
+ #
@@ -0,0 +1,6 @@
1
+ Berksfile.lock
2
+ Gemfile.lock
3
+ /cookbooks
4
+ <% if options[:scmversion] -%>
5
+ VERSION
6
+ <% end -%>
@@ -0,0 +1,13 @@
1
+ Copyright (C) <%= copyright_year %> <%= maintainer %>
2
+
3
+ Licensed under the Apache License, Version 2.0 (the "License");
4
+ you may not use this file except in compliance with the License.
5
+ You may obtain a copy of the License at
6
+
7
+ http://www.apache.org/licenses/LICENSE-2.0
8
+
9
+ Unless required by applicable law or agreed to in writing, software
10
+ distributed under the License is distributed on an "AS IS" BASIS,
11
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ See the License for the specific language governing permissions and
13
+ limitations under the License.
@@ -0,0 +1,15 @@
1
+ Copyright (C) <%= copyright_year %> <%= maintainer %>
2
+
3
+ This program is free software; you can redistribute it and/or modify
4
+ it under the terms of the GNU General Public License as published by
5
+ the Free Software Foundation; either version 2 of the License, or
6
+ (at your option) any later version.
7
+
8
+ This program is distributed in the hope that it will be useful,
9
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
+ GNU General Public License for more details.
12
+
13
+ You should have received a copy of the GNU General Public License along
14
+ with this program; if not, write to the Free Software Foundation, Inc.,
15
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
@@ -0,0 +1,14 @@
1
+ Copyright (C) <%= copyright_year %> <%= maintainer %>
2
+
3
+ This program is free software: you can redistribute it and/or modify
4
+ it under the terms of the GNU General Public License as published by
5
+ the Free Software Foundation, either version 3 of the License, or
6
+ (at your option) any later version.
7
+
8
+ This program is distributed in the hope that it will be useful,
9
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
+ GNU General Public License for more details.
12
+
13
+ You should have received a copy of the GNU General Public License
14
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
@@ -0,0 +1,20 @@
1
+ Copyright (C) <%= copyright_year %> <%= maintainer %>
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,3 @@
1
+ Copyright (C) <%= copyright_year %> <%= maintainer %>
2
+
3
+ All rights reserved - Do Not Redistribute
@@ -0,0 +1,12 @@
1
+ name "<%= name %>"
2
+ maintainer "<%= maintainer %>"
3
+ maintainer_email "<%= maintainer_email %>"
4
+ license "<%= license_name %>"
5
+ description "Installs/Configures <%= name %>"
6
+ long_description IO.read(File.join(File.dirname(__FILE__), 'README.md'))
7
+ <% if options[:scmversion] -%>
8
+ version IO.read(File.join(File.dirname(__FILE__), 'VERSION')) rescue "0.0.1"
9
+ <% else -%>
10
+ version "0.0.1"
11
+ <% end -%>
12
+
@@ -1,15 +1,12 @@
1
- require 'thor/group'
2
-
3
1
  module Berkshelf
4
2
  # @author Jamie Winsor <jamie@vialstudios.com>
5
- class InitGenerator < Thor::Group
6
- class << self
7
- def source_root
8
- File.expand_path(File.join(File.dirname(__FILE__), "generator_files"))
3
+ class InitGenerator < BaseGenerator
4
+ def initialize(*)
5
+ super
6
+ if @options[:cookbook_name]
7
+ @cookbook_name = @options[:cookbook_name]
9
8
  end
10
9
  end
11
-
12
- include Thor::Actions
13
10
 
14
11
  argument :path,
15
12
  type: :string,
@@ -23,14 +20,74 @@ module Berkshelf
23
20
  type: :boolean,
24
21
  default: false
25
22
 
26
- def generate
27
- target_path = File.expand_path(path)
23
+ class_option :vagrant,
24
+ type: :boolean,
25
+ default: false
26
+
27
+ class_option :git,
28
+ type: :boolean,
29
+ default: false
30
+
31
+ class_option :foodcritic,
32
+ type: :boolean,
33
+ default: false
34
+
35
+ class_option :scmversion,
36
+ type: :boolean,
37
+ default: false
38
+
39
+ class_option :no_bundler,
40
+ type: :boolean,
41
+ default: false
28
42
 
29
- template "Berksfile.erb", File.join(target_path, "Berksfile")
43
+ class_option :cookbook_name,
44
+ type: :string
45
+
46
+ def generate
47
+ template "Berksfile.erb", target.join("Berksfile")
30
48
 
31
49
  if options[:chefignore]
32
- copy_file "chefignore", File.join(target_path, "chefignore")
50
+ copy_file "chefignore", target.join("chefignore")
51
+ end
52
+
53
+ if options[:git] || options[:scmversion]
54
+ template "gitignore.erb", target.join(".gitignore")
55
+ unless File.exists?(target.join(".git"))
56
+ inside target do
57
+ run "git init"
58
+ end
59
+ end
60
+ end
61
+
62
+ if options[:foodcritic] || options[:scmversion]
63
+ template "Thorfile.erb", target.join("Thorfile")
64
+ end
65
+
66
+ if options[:scmversion]
67
+ create_file target.join("VERSION"), "0.0.1"
68
+ end
69
+
70
+ unless options[:no_bundler]
71
+ template "Gemfile.erb", target.join("Gemfile")
72
+ end
73
+
74
+ if options[:vagrant]
75
+ template "Vagrantfile.erb", target.join("Vagrantfile")
76
+ ::Berkshelf::Cli.new([], berksfile: target.join("Berksfile"), shims: target.join("cookbooks")).invoke(:install)
33
77
  end
34
78
  end
79
+
80
+ private
81
+
82
+ def cookbook_name
83
+ @cookbook_name ||= begin
84
+ metadata = Chef::Cookbook::Metadata.new
85
+
86
+ metadata.from_file(target.join("metadata.rb").to_s)
87
+ metadata.name.empty? ? File.basename(target) : metadata.name
88
+ rescue IOError
89
+ File.basename(target)
90
+ end
91
+ end
35
92
  end
36
93
  end
@@ -1,3 +1,3 @@
1
1
  module Berkshelf
2
- VERSION = "0.4.0.rc1"
2
+ VERSION = "0.4.0.rc2"
3
3
  end
@@ -2,31 +2,17 @@ require 'spec_helper'
2
2
 
3
3
  module Berkshelf
4
4
  describe Berksfile do
5
- describe "ClassMethods" do
6
- subject { Berksfile }
7
-
8
- let(:content) do
5
+ let(:content) do
9
6
  <<-EOF
10
7
  cookbook 'ntp', '<= 1.0.0'
11
8
  cookbook 'mysql'
12
9
  cookbook 'nginx', '< 0.101.2'
13
10
  cookbook 'ssh_known_hosts2', :git => 'https://github.com/erikh/chef-ssh_known_hosts2.git'
14
11
  EOF
15
- end
16
-
17
- describe "#read" do
18
- it "reads the content of a Berksfile and adds the sources to the Shelf" do
19
- cbfile = subject.read(content)
20
-
21
- ['ntp', 'mysql', 'nginx', 'ssh_known_hosts2'].each do |name|
22
- cbfile.should have_source(name)
23
- end
24
- end
25
-
26
- it "returns an instance of Berksfile" do
27
- subject.read(content).should be_a(Berksfile)
28
- end
29
- end
12
+ end
13
+
14
+ describe "ClassMethods" do
15
+ subject { Berksfile }
30
16
 
31
17
  describe "#from_file" do
32
18
  let(:cookbook_file) { fixtures_path.join('lockfile_spec', 'with_lock', 'Berksfile') }
@@ -77,7 +63,7 @@ EOF
77
63
  let(:source_two) { double('source_two', name: "mysql") }
78
64
 
79
65
  subject do
80
- cbf = Berksfile.new
66
+ cbf = Berksfile.new(tmp_path.join("Berksfile"))
81
67
  cbf.add_source(source_one)
82
68
  cbf.add_source(source_two)
83
69
  cbf
@@ -205,5 +191,19 @@ EOF
205
191
  linked_path_two.should be_cookbook
206
192
  end
207
193
  end
194
+
195
+ describe "#load" do
196
+ it "reads the content of a Berksfile and adds the sources to the Shelf" do
197
+ subject.load(content)
198
+
199
+ ['ntp', 'mysql', 'nginx', 'ssh_known_hosts2'].each do |name|
200
+ subject.should have_source(name)
201
+ end
202
+ end
203
+
204
+ it "returns an instance of Berksfile" do
205
+ subject.load(content).should be_a(Berksfile)
206
+ end
207
+ end
208
208
  end
209
209
  end
@@ -0,0 +1,79 @@
1
+ require 'spec_helper'
2
+
3
+ module Berkshelf
4
+ describe CookbookGenerator do
5
+ subject { CookbookGenerator }
6
+
7
+ let(:name) { "sparkle_motion" }
8
+ let(:target) { tmp_path.join(name) }
9
+
10
+ context "with default options" do
11
+ before do
12
+ generator = subject.new([name, target])
13
+ capture(:stdout) { generator.invoke_all }
14
+ end
15
+
16
+ specify do
17
+ target.should have_structure {
18
+ directory "attributes"
19
+ directory "definitions"
20
+ directory "files" do
21
+ directory "default"
22
+ end
23
+ directory "libraries"
24
+ directory "providers"
25
+ directory "recipes" do
26
+ file "default.rb" do
27
+ contains "# Cookbook Name:: sparkle_motion"
28
+ contains "# Recipe:: default"
29
+ contains "# Copyright (C) #{Time.now.year} YOUR_NAME"
30
+ contains "# All rights reserved - Do Not Redistribute"
31
+ end
32
+ end
33
+ directory "resources"
34
+ directory "templates" do
35
+ directory "default"
36
+ end
37
+ file "LICENSE" do
38
+ contains "Copyright (C) #{Time.now.year} YOUR_NAME"
39
+ contains "All rights reserved - Do Not Redistribute"
40
+ end
41
+ file "README.md" do
42
+ contains "# sparkle_motion cookbook"
43
+ contains "Author:: YOUR_NAME (<YOUR_EMAIL>)"
44
+ end
45
+ file "metadata.rb" do
46
+ contains "name \"sparkle_motion\""
47
+ contains "maintainer \"YOUR_NAME\""
48
+ contains "maintainer_email \"YOUR_EMAIL\""
49
+ contains "license \"All rights reserved\""
50
+ contains "description \"Installs/Configures sparkle_motion\""
51
+ end
52
+ file "Berksfile" do
53
+ contains "metadata"
54
+ end
55
+ file "Gemfile"
56
+ file "chefignore"
57
+ }
58
+ end
59
+ end
60
+
61
+ context "given a value for the maintainer_email option" do
62
+ before do
63
+ @email = "jamie@vialstudios.com"
64
+ generator = subject.new([name, target], maintainer_email: @email)
65
+ capture(:stdout) { generator.invoke_all }
66
+ end
67
+
68
+ it "generates a metadata.rb with a default value for maintainer_email" do
69
+ email = @email
70
+
71
+ target.should have_structure {
72
+ file "metadata.rb" do
73
+ contains "maintainer_email \"#{email}\""
74
+ end
75
+ }
76
+ end
77
+ end
78
+ end
79
+ end