berkshelf 1.0.0.rc3 → 1.0.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.
data/.gitignore CHANGED
@@ -20,3 +20,4 @@ tmp
20
20
  /spec/fixtures/vcr_cassettes
21
21
  /features/config.yml
22
22
  *.sw[op]
23
+ \.\#*
@@ -8,32 +8,35 @@ Feature: cookbook command
8
8
  Then I should have a new cookbook skeleton "sparkle_motion"
9
9
  And the exit status should be 0
10
10
 
11
- Scenario: creating a new cookbook skeleton with Foodcritic support
11
+ Scenario Outline: creating a new cookbook skeleton with affirmative options
12
12
  When I run the cookbook command to create "sparkle_motion" with options:
13
- | --foodcritic |
14
- Then I should have a new cookbook skeleton "sparkle_motion" with Foodcritic support
13
+ | --<option> |
14
+ Then I should have a new cookbook skeleton "sparkle_motion" with <feature> support
15
15
  And the exit status should be 0
16
16
 
17
- Scenario: creating a new cookbook skeleton with SCMVersion support
18
- When I run the cookbook command to create "sparkle_motion" with options:
19
- | --scmversion |
20
- Then I should have a new cookbook skeleton "sparkle_motion" with SCMVersion support
21
- And the exit status should be 0
17
+ Examples:
18
+ | option | feature |
19
+ | foodcritic | Foodcritic |
20
+ | scmversion | SCMVersion |
21
+ | no-bundler | no Bundler |
22
+ | skip-git | no Git |
23
+ | skip-vagrant | no Vagrant |
22
24
 
23
- Scenario: creating a new cookbook skeleton without Bundler support
25
+ Scenario Outline: creating a new cookbook skeleton with options without the supporting gem installed
24
26
  When I run the cookbook command to create "sparkle_motion" with options:
25
- | --no-bundler |
26
- Then I should have a new cookbook skeleton "sparkle_motion" without Bundler support
27
+ | --<option> |
28
+ Then I should have a new cookbook skeleton "sparkle_motion" with <feature> support
29
+ And the output should contain a warning to suggest supporting the option "<option>" by installing "<gem>"
27
30
  And the exit status should be 0
28
31
 
29
- Scenario: creating a new cookbook skeleton without Git support
30
- When I run the cookbook command to create "sparkle_motion" with options:
31
- | --skip-git |
32
- Then I should have a new cookbook skeleton "sparkle_motion" without Git support
33
- And the exit status should be 0
32
+ Examples:
33
+ | option | feature | gem |
34
+ | foodcritic | Foodcritic | foodcritic |
35
+ | scmversion | SCMVersion | thor-scmversion |
36
+ # | no-bundler | no Bundler | bundler |
37
+
38
+ @pending
39
+ Scenario: creating a new cookbook skeleton with bundler support without bundler installed
40
+ Given pending "Bundler is used in tests, so it always appears available. Need to mock out the Gem::Specification.find_by_name, but aruba is out of process testing."
41
+
34
42
 
35
- Scenario: creating a new cookbook skeleton without Vagrant support
36
- When I run the cookbook command to create "sparkle_motion" with options:
37
- | --skip-vagrant |
38
- Then I should have a new cookbook skeleton "sparkle_motion" without Vagrant support
39
- And the exit status should be 0
@@ -79,6 +79,72 @@ Feature: install cookbooks from a Berksfile
79
79
  """
80
80
  And the exit status should be 0
81
81
 
82
+ Scenario: installing a Berksfile that contains a GitHub location
83
+ Given I write to "Berksfile" with:
84
+ """
85
+ cookbook "artifact", github: "RiotGames/artifact-cookbook", ref: "0.9.8"
86
+ """
87
+ When I run the install command
88
+ Then the cookbook store should have the git cookbooks:
89
+ | artifact | 0.9.8 | c0a0b456a4716a81645bef1369f5fd1a4e62ce6d |
90
+ And the output should contain:
91
+ """
92
+ Installing artifact (0.9.8) from github: 'RiotGames/artifact-cookbook' with branch: '0.9.8'
93
+ """
94
+ And the exit status should be 0
95
+
96
+ Scenario Outline: installing a Berksfile that contains a Github location and the default protocol
97
+ Given I write to "Berksfile" with:
98
+ """
99
+ cookbook "artifact", github: "RiotGames/artifact-cookbook", ref: "0.9.8"<command postfix>
100
+ """
101
+ When I run the install command
102
+ Then the cookbook store should have the git cookbooks:
103
+ | artifact | 0.9.8 | c0a0b456a4716a81645bef1369f5fd1a4e62ce6d |
104
+ And the output should contain:
105
+ """
106
+ Installing artifact (0.9.8) from github: 'RiotGames/artifact-cookbook' with branch: '0.9.8'
107
+ """
108
+ And the exit status should be 0
109
+
110
+ Examples:
111
+ | command postfix |
112
+ | , protocol: "git" |
113
+ | |
114
+
115
+ Scenario Outline: installing a Berksfile that contains a Github location and specific protocol
116
+ Given I write to "Berksfile" with:
117
+ """
118
+ cookbook "artifact", github: "RiotGames/artifact-cookbook", ref: "0.9.8", protocol: "<protocol>"
119
+ """
120
+ When I run the install command
121
+ Then the cookbook store should have the git cookbooks:
122
+ | artifact | 0.9.8 | c0a0b456a4716a81645bef1369f5fd1a4e62ce6d |
123
+ And the output should contain:
124
+ """
125
+ Installing artifact (0.9.8) from github: 'RiotGames/artifact-cookbook' with branch: '0.9.8' over protocol: '<protocol>'
126
+ """
127
+ And the exit status should be 0
128
+
129
+ Examples:
130
+ | protocol |
131
+ # GitHub over ssh requires push authorization. Nonpushers will
132
+ # get a test failure here.
133
+ # | ssh |
134
+ | https |
135
+
136
+ Scenario: installing a Berksfile that contains a Github location and an unsupported protocol
137
+ Given I write to "Berksfile" with:
138
+ """
139
+ cookbook "artifact", github: "RiotGames/artifact-cookbook", ref: "0.9.8", protocol: "somethingabsurd"
140
+ """
141
+ When I run the install command
142
+ Then the output should contain:
143
+ """
144
+ 'somethingabsurd' is not a supported Git protocol for the 'github' location key. Please use 'git' instead.
145
+ """
146
+ And the exit status should be 110
147
+
82
148
  Scenario: installing a Berksfile that contains an explicit site location
83
149
  Given I write to "Berksfile" with:
84
150
  """
@@ -143,7 +143,7 @@ Then /^I should have a new cookbook skeleton "(.*?)" with SCMVersion support$/ d
143
143
  }
144
144
  end
145
145
 
146
- Then /^I should have a new cookbook skeleton "(.*?)" without Bundler support$/ do |name|
146
+ Then /^I should have a new cookbook skeleton "(.*?)" with no Bundler support$/ do |name|
147
147
  cb_path = Pathname.new(current_dir).join(name)
148
148
  cb_path.should have_structure {
149
149
  directory "attributes"
@@ -171,13 +171,13 @@ Then /^I should have a new cookbook skeleton "(.*?)" without Bundler support$/ d
171
171
  }
172
172
  end
173
173
 
174
- Then /^I should have a new cookbook skeleton "(.*?)" without Git support$/ do |name|
174
+ Then /^I should have a new cookbook skeleton "(.*?)" with no Git support$/ do |name|
175
175
  Pathname.new(current_dir).join(name).should have_structure {
176
176
  no_file ".gitignore"
177
177
  }
178
178
  end
179
179
 
180
- Then /^I should have a new cookbook skeleton "(.*?)" without Vagrant support$/ do |name|
180
+ Then /^I should have a new cookbook skeleton "(.*?)" with no Vagrant support$/ do |name|
181
181
  Pathname.new(current_dir).join(name).should have_structure {
182
182
  file "Gemfile" do
183
183
  does_not_contain "gem 'vagrant'"
@@ -0,0 +1,11 @@
1
+ Given /^the gem "(.*)" is not installed$/ do |gem_name|
2
+ # Because aruba is out of process, need to figure out how to mock the Gem::Specification.find_by_name call to pretend gems are not available.
3
+ end
4
+
5
+ Then /^the output should contain a warning to suggest supporting the option "(.*?)" by installing "(.*?)"$/ do |option, gem_name|
6
+ step "the output should contain \"This cookbook was generated with --#{option}, however, #{gem_name} is not installed.\nTo make use of --#{option}: gem install #{gem_name}\""
7
+ end
8
+
9
+ Then /^the output should contain a warning to suggest supporting the default for "(.*?)" by installing "(.*?)"$/ do |option, gem_name|
10
+ step "the output should contain \"By default, this cookbook was generated to support #{gem_name}, however, #{gem_name} is not installed.\nTo skip support for #{gem_name}, use --#{option}\"\nTo install #{gem_name}: gem install #{gem_name}"
11
+ end
@@ -0,0 +1,3 @@
1
+ Given /^pending\s+"([^\"]+)"$/ do |msg|
2
+ pending
3
+ end
@@ -13,11 +13,24 @@ Spork.prefork do
13
13
 
14
14
  ENV["BERKSHELF_PATH"] = File.join(APP_ROOT, "tmp", "berkshelf")
15
15
  ENV["BERKSHELF_CHEF_CONFIG"] = File.join(APP_ROOT, "tmp", "knife.rb")
16
+
17
+ # Workaround for RSA Fingerprint prompt in Travis CI
18
+ git_ssh_path = '/tmp/git_ssh.sh'
19
+ unless File.exist? git_ssh_path
20
+ git_ssh = File.new(git_ssh_path, 'w+')
21
+ git_ssh.puts "ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no $1 $2"
22
+ git_ssh.chmod 0775
23
+ git_ssh.flush
24
+ git_ssh.close
25
+ end
26
+
27
+ ENV["GIT_SSH"] = git_ssh_path
28
+
16
29
 
17
30
  Dir[File.join(APP_ROOT, "spec/support/**/*.rb")].each {|f| require f}
18
31
 
19
32
  Around do |scenario, block|
20
- VCR.use_cassette(scenario.title) do
33
+ VCR.use_cassette(scenario.name) do
21
34
  block.call
22
35
  end
23
36
  end
@@ -41,7 +41,7 @@ module Berkshelf
41
41
  end
42
42
 
43
43
  FileUtils.remove_dir(path, force: true)
44
- File.rename(scratch, path)
44
+ FileUtils.mv(scratch, path)
45
45
 
46
46
  path
47
47
  end
@@ -66,6 +66,9 @@ module Berkshelf
66
66
  File.read(path) if File.exists?(path)
67
67
  end
68
68
 
69
+ # Instantiate and return or just return the currently instantiated Berkshelf
70
+ # configuration
71
+ #
69
72
  # @return [Config]
70
73
  def instance
71
74
  @instance ||= if file
@@ -74,6 +77,14 @@ module Berkshelf
74
77
  new
75
78
  end
76
79
  end
80
+
81
+ # Reload the currently instantiated Berkshelf configuration
82
+ #
83
+ # @return [Config]
84
+ def reload
85
+ @instance = nil
86
+ self.instance
87
+ end
77
88
  end
78
89
 
79
90
  # @param [String] path
@@ -57,6 +57,20 @@ module Berkshelf
57
57
  end
58
58
  end
59
59
 
60
+ class UnknownGitHubProtocol < BerkshelfError
61
+ status_code(110)
62
+ attr_reader :protocol
63
+
64
+ # @param [String] protocol
65
+ def initialize(protocol)
66
+ @protocol = protocol
67
+ end
68
+
69
+ def to_s
70
+ "'#{self.protocol}' is not a supported Git protocol for the 'github' location key. Please use 'git' instead."
71
+ end
72
+ end
73
+
60
74
  class GitNotFound < BerkshelfError
61
75
  status_code(110)
62
76
 
@@ -1,5 +1,6 @@
1
1
  module Berkshelf
2
2
  # @author Jamie Winsor <jamie@vialstudios.com>
3
+ # @author Josiah Kiehl <josiah@skirmisher.net>
3
4
  class InitGenerator < BaseGenerator
4
5
  def initialize(*args)
5
6
  super(*args)
@@ -47,8 +48,10 @@ module Berkshelf
47
48
  type: :hash,
48
49
  default: Config.instance
49
50
 
51
+ # Generate the cookbook
50
52
  def generate
51
53
  validate_configuration
54
+ check_option_support
52
55
 
53
56
  template "Berksfile.erb", target.join("Berksfile")
54
57
 
@@ -86,6 +89,10 @@ module Berkshelf
86
89
 
87
90
  private
88
91
 
92
+ # Read the cookbook name from the metadata.rb
93
+ #
94
+ # @return [String]
95
+ # name of the cookbook
89
96
  def cookbook_name
90
97
  @cookbook_name ||= begin
91
98
  metadata = Chef::Cookbook::Metadata.new
@@ -97,10 +104,59 @@ module Berkshelf
97
104
  end
98
105
  end
99
106
 
107
+ # Assert valid configuration
108
+ #
109
+ # @raise [InvalidConfiguration] if the configuration is invalid
110
+ #
111
+ # @return [nil]
100
112
  def validate_configuration
101
113
  unless Config.instance.valid?
102
114
  raise InvalidConfiguration.new Config.instance.errors
103
115
  end
104
116
  end
117
+
118
+
119
+ # Check for supporting gems for provided options
120
+ #
121
+ # @return [Boolean]
122
+ def check_option_support
123
+ assert_option_supported(:foodcritic) &&
124
+ assert_option_supported(:scmversion, 'thor-scmversion') &&
125
+ assert_default_supported(:no_bundler, 'bundler')
126
+ # Vagrant is a dependency of Berkshelf; it will always appear available to the Berkshelf process.
127
+ end
128
+
129
+ # Warn if the supporting gem for an option is not installed
130
+ #
131
+ # @return [Boolean]
132
+ def assert_option_supported(option, gem_name = option.to_s)
133
+ if options[option]
134
+ begin
135
+ Gem::Specification.find_by_name(gem_name)
136
+ rescue Gem::LoadError
137
+ Berkshelf.ui.warn "This cookbook was generated with --#{option}, however, #{gem_name} is not installed."
138
+ Berkshelf.ui.warn "To make use of --#{option}: gem install #{gem_name}"
139
+ return false
140
+ end
141
+ end
142
+ true
143
+ end
144
+
145
+ # Warn if the supporting gem for a default is not installed
146
+ #
147
+ # @return [Boolean]
148
+ def assert_default_supported(option, gem_name = option.to_s)
149
+ unless options[option]
150
+ begin
151
+ Gem::Specification.find_by_name(gem_name)
152
+ rescue Gem::LoadError
153
+ Berkshelf.ui.warn "By default, this cookbook was generated to support #{gem_name}, however, #{gem_name} is not installed."
154
+ Berkshelf.ui.warn "To skip support for #{gem_name}, use --#{option}"
155
+ Berkshelf.ui.warn "To install #{gem_name}: gem install #{gem_name}"
156
+ return false
157
+ end
158
+ end
159
+ true
160
+ end
105
161
  end
106
162
  end
@@ -0,0 +1,60 @@
1
+ module Berkshelf
2
+ # @author Josiah Kiehl <josiah@skirmisher.net>
3
+ class GithubLocation < GitLocation
4
+ DEFAULT_PROTOCOL = 'git'
5
+
6
+ set_location_key :github
7
+ set_valid_options :protocol
8
+
9
+ attr_accessor :protocol
10
+ attr_accessor :repo_identifier
11
+
12
+ # Wraps GitLocation allowing the short form GitHub repo identifier
13
+ # to be used in place of the complete repo url.
14
+ #
15
+ # @see GitLocation#initialize for parameter documentation
16
+ #
17
+ # @option options [String] :github
18
+ # the GitHub repo identifier to clone
19
+ # @option options [String] :protocol
20
+ # the protocol with which to communicate with GitHub
21
+ def initialize(name, version_constraint, options = {})
22
+ @repo_identifier = options.delete(:github)
23
+ @protocol = options.delete(:protocol) || DEFAULT_PROTOCOL
24
+ options[:git] = github_url
25
+ super
26
+ end
27
+
28
+ # Returns the appropriate GitHub url given the specified protocol
29
+ #
30
+ # @raise [UnknownGitHubProtocol] if the specified protocol is not supported.
31
+ #
32
+ # @return [String]
33
+ # GitHub url
34
+ def github_url
35
+ case protocol.to_s
36
+ when 'ssh'
37
+ "git@github.com:#{repo_identifier}.git"
38
+ when 'https'
39
+ "https://github.com/#{repo_identifier}.git"
40
+ when 'git'
41
+ "git://github.com/#{repo_identifier}.git"
42
+ else
43
+ raise UnknownGitHubProtocol.new(protocol)
44
+ end
45
+ end
46
+
47
+ def to_s
48
+ s = "#{self.class.location_key}: '#{repo_identifier}'"
49
+ s << " with branch: '#{branch}'" if branch
50
+ s << " over protocol: '#{protocol}'" unless default_protocol?
51
+ s
52
+ end
53
+
54
+ private
55
+
56
+ def default_protocol?
57
+ @protocol == DEFAULT_PROTOCOL
58
+ end
59
+ end
60
+ end
@@ -23,6 +23,12 @@ module Berkshelf
23
23
  super(status, message, log_status)
24
24
  end
25
25
 
26
+ def warn(message, color = :yellow)
27
+ return if quiet?
28
+
29
+ say(message, color)
30
+ end
31
+
26
32
  def error(message, color = :red)
27
33
  return if quiet?
28
34
 
@@ -1,3 +1,3 @@
1
1
  module Berkshelf
2
- VERSION = "1.0.0.rc3"
2
+ VERSION = "1.0.0"
3
3
  end
metadata CHANGED
@@ -1,8 +1,8 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: berkshelf
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0.rc3
5
- prerelease: 6
4
+ version: 1.0.0
5
+ prerelease:
6
6
  platform: ruby
7
7
  authors:
8
8
  - Jamie Winsor
@@ -225,7 +225,9 @@ files:
225
225
  - features/step_definitions/cli_steps.rb
226
226
  - features/step_definitions/configure_cli_steps.rb
227
227
  - features/step_definitions/filesystem_steps.rb
228
+ - features/step_definitions/gem_steps.rb
228
229
  - features/step_definitions/json_steps.rb
230
+ - features/step_definitions/utility_steps.rb
229
231
  - features/support/env.rb
230
232
  - features/update.feature
231
233
  - features/upload_command.feature
@@ -268,6 +270,7 @@ files:
268
270
  - lib/berkshelf/location.rb
269
271
  - lib/berkshelf/locations/chef_api_location.rb
270
272
  - lib/berkshelf/locations/git_location.rb
273
+ - lib/berkshelf/locations/github_location.rb
271
274
  - lib/berkshelf/locations/path_location.rb
272
275
  - lib/berkshelf/locations/site_location.rb
273
276
  - lib/berkshelf/lockfile.rb
@@ -353,9 +356,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
353
356
  required_rubygems_version: !ruby/object:Gem::Requirement
354
357
  none: false
355
358
  requirements:
356
- - - ! '>'
359
+ - - ! '>='
357
360
  - !ruby/object:Gem::Version
358
- version: 1.3.1
361
+ version: '0'
362
+ segments:
363
+ - 0
364
+ hash: -4545769235326806267
359
365
  requirements: []
360
366
  rubyforge_project:
361
367
  rubygems_version: 1.8.23
@@ -377,7 +383,9 @@ test_files:
377
383
  - features/step_definitions/cli_steps.rb
378
384
  - features/step_definitions/configure_cli_steps.rb
379
385
  - features/step_definitions/filesystem_steps.rb
386
+ - features/step_definitions/gem_steps.rb
380
387
  - features/step_definitions/json_steps.rb
388
+ - features/step_definitions/utility_steps.rb
381
389
  - features/support/env.rb
382
390
  - features/update.feature
383
391
  - features/upload_command.feature