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 +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
|