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 +1 -0
- data/features/cookbook_command.feature +24 -21
- data/features/install.feature +66 -0
- data/features/step_definitions/filesystem_steps.rb +3 -3
- data/features/step_definitions/gem_steps.rb +11 -0
- data/features/step_definitions/utility_steps.rb +3 -0
- data/features/support/env.rb +14 -1
- data/lib/berkshelf/berksfile.rb +1 -1
- data/lib/berkshelf/config.rb +11 -0
- data/lib/berkshelf/errors.rb +14 -0
- data/lib/berkshelf/init_generator.rb +56 -0
- data/lib/berkshelf/locations/github_location.rb +60 -0
- data/lib/berkshelf/ui.rb +6 -0
- data/lib/berkshelf/version.rb +1 -1
- metadata +12 -4
data/.gitignore
CHANGED
@@ -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
|
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
|
-
|
|
14
|
-
Then I should have a new cookbook skeleton "sparkle_motion" with
|
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
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
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
|
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
|
-
|
|
26
|
-
Then I should have a new cookbook skeleton "sparkle_motion"
|
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
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
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
|
data/features/install.feature
CHANGED
@@ -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 "(.*?)"
|
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 "(.*?)"
|
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 "(.*?)"
|
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
|
data/features/support/env.rb
CHANGED
@@ -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.
|
33
|
+
VCR.use_cassette(scenario.name) do
|
21
34
|
block.call
|
22
35
|
end
|
23
36
|
end
|
data/lib/berkshelf/berksfile.rb
CHANGED
data/lib/berkshelf/config.rb
CHANGED
@@ -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
|
data/lib/berkshelf/errors.rb
CHANGED
@@ -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
|
data/lib/berkshelf/ui.rb
CHANGED
data/lib/berkshelf/version.rb
CHANGED
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
|
5
|
-
prerelease:
|
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:
|
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
|