berkshelf 1.0.0.rc3 → 1.0.0

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