berkshelf 0.4.0.rc4 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +2 -0
- data/Guardfile +6 -3
- data/features/default_locations.feature +122 -0
- data/features/install.feature +20 -4
- data/features/lockfile.feature +1 -6
- data/features/update.feature +2 -3
- data/generator_files/Berksfile.erb +2 -0
- data/generator_files/gitignore.erb +6 -0
- data/lib/berkshelf.rb +6 -10
- data/lib/berkshelf/berksfile.rb +203 -14
- data/lib/berkshelf/cached_cookbook.rb +5 -1
- data/lib/berkshelf/cli.rb +4 -0
- data/lib/berkshelf/cookbook_source.rb +49 -91
- data/lib/berkshelf/cookbook_store.rb +2 -0
- data/lib/berkshelf/downloader.rb +71 -51
- data/lib/berkshelf/errors.rb +7 -3
- data/lib/berkshelf/formatters.rb +6 -6
- data/lib/berkshelf/location.rb +171 -0
- data/lib/berkshelf/locations/chef_api_location.rb +252 -0
- data/lib/berkshelf/locations/git_location.rb +76 -0
- data/lib/berkshelf/locations/path_location.rb +38 -0
- data/lib/berkshelf/locations/site_location.rb +150 -0
- data/lib/berkshelf/lockfile.rb +2 -2
- data/lib/berkshelf/resolver.rb +12 -15
- data/lib/berkshelf/uploader.rb +2 -9
- data/lib/berkshelf/version.rb +1 -1
- data/spec/fixtures/lockfile_spec/without_lock/.gitkeep +0 -0
- data/spec/support/chef_api.rb +7 -1
- data/spec/unit/berkshelf/berksfile_spec.rb +157 -12
- data/spec/unit/berkshelf/cached_cookbook_spec.rb +19 -0
- data/spec/unit/berkshelf/cookbook_generator_spec.rb +1 -0
- data/spec/unit/berkshelf/cookbook_source_spec.rb +25 -35
- data/spec/unit/berkshelf/cookbook_store_spec.rb +3 -3
- data/spec/unit/berkshelf/downloader_spec.rb +171 -43
- data/spec/unit/berkshelf/formatters_spec.rb +13 -16
- data/spec/unit/berkshelf/{cookbook_source/location_spec.rb → location_spec.rb} +10 -10
- data/spec/unit/berkshelf/{cookbook_source → locations}/chef_api_location_spec.rb +4 -4
- data/spec/unit/berkshelf/{cookbook_source → locations}/git_location_spec.rb +8 -8
- data/spec/unit/berkshelf/{cookbook_source → locations}/path_location_spec.rb +5 -5
- data/spec/unit/berkshelf/{cookbook_source → locations}/site_location_spec.rb +17 -3
- data/spec/unit/berkshelf/lockfile_spec.rb +26 -17
- data/spec/unit/berkshelf/resolver_spec.rb +6 -5
- data/spec/unit/berkshelf/uploader_spec.rb +6 -4
- metadata +27 -31
- data/lib/berkshelf/cookbook_source/chef_api_location.rb +0 -256
- data/lib/berkshelf/cookbook_source/git_location.rb +0 -78
- data/lib/berkshelf/cookbook_source/location.rb +0 -167
- data/lib/berkshelf/cookbook_source/path_location.rb +0 -40
- data/lib/berkshelf/cookbook_source/site_location.rb +0 -149
- data/lib/berkshelf/dsl.rb +0 -45
- data/lib/berkshelf/tx_result.rb +0 -12
- data/lib/berkshelf/tx_result_set.rb +0 -37
- data/spec/fixtures/lockfile_spec/without_lock/Berksfile.lock +0 -5
- data/spec/unit/berkshelf/dsl_spec.rb +0 -42
- data/spec/unit/berkshelf/tx_result_set_spec.rb +0 -77
- data/spec/unit/berkshelf/tx_result_spec.rb +0 -21
data/.gitignore
CHANGED
data/Guardfile
CHANGED
@@ -1,22 +1,25 @@
|
|
1
|
+
notification :off
|
2
|
+
interactor :coolline
|
3
|
+
|
1
4
|
guard 'spork' do
|
2
5
|
watch('Gemfile')
|
3
6
|
watch('spec/spec_helper.rb') { :rspec }
|
4
7
|
watch(%r{^features/support/}) { :cucumber }
|
5
8
|
end
|
6
9
|
|
7
|
-
guard 'yard', :
|
10
|
+
guard 'yard', stdout: '/dev/null', stderr: '/dev/null' do
|
8
11
|
watch(%r{app/.+\.rb})
|
9
12
|
watch(%r{lib/.+\.rb})
|
10
13
|
watch(%r{ext/.+\.c})
|
11
14
|
end
|
12
15
|
|
13
|
-
guard 'rspec', :
|
16
|
+
guard 'rspec', version: 2, cli: "--color --drb --format Fuubar", all_on_start: false, all_after_pass: false do
|
14
17
|
watch(%r{^spec/unit/.+_spec\.rb$})
|
15
18
|
watch(%r{^lib/(.+)\.rb$}) { |m| "spec/unit/#{m[1]}_spec.rb" }
|
16
19
|
watch('spec/spec_helper.rb') { "spec" }
|
17
20
|
end
|
18
21
|
|
19
|
-
guard 'cucumber', :
|
22
|
+
guard 'cucumber', cli: "--drb --format pretty --tags ~@no_run --tags ~@wip", all_on_start: false, all_after_pass: false do
|
20
23
|
watch(%r{^features/.+\.feature$})
|
21
24
|
watch(%r{^features/support/.+$}) { 'features' }
|
22
25
|
watch(%r{^features/step_definitions/(.+)_steps\.rb$}) { |m| Dir[File.join("**/#{m[1]}.feature")][0] || 'features' }
|
@@ -0,0 +1,122 @@
|
|
1
|
+
Feature: Berksfile default locations
|
2
|
+
As a Berkshelf user
|
3
|
+
I want to be able to define default locations in my Berksfile
|
4
|
+
So I can set the precedence of where cookbook sources are downloaded from or define an alternate location for all
|
5
|
+
cookbook sources to attempt to retrieve from
|
6
|
+
|
7
|
+
Scenario: with a default chef_api(1) and site(2) location with a cookbook source that is satisfied by the chef_api(1) location
|
8
|
+
Given I write to "Berksfile" with:
|
9
|
+
"""
|
10
|
+
chef_api :knife
|
11
|
+
site 'http://cookbooks.opscode.com/api/v1/cookbooks'
|
12
|
+
|
13
|
+
cookbook "artifact", "= 0.10.0"
|
14
|
+
"""
|
15
|
+
And the Chef server has cookbooks:
|
16
|
+
| artifact | 0.10.0 |
|
17
|
+
When I run the install command
|
18
|
+
Then the output should contain:
|
19
|
+
"""
|
20
|
+
Installing artifact (0.10.0) from chef_api:
|
21
|
+
"""
|
22
|
+
And the cookbook store should have the cookbooks:
|
23
|
+
| artifact | 0.10.0 |
|
24
|
+
And the exit status should be 0
|
25
|
+
|
26
|
+
Scenario: with a default chef_api(1) and site(2) location with a cookbook source that is not satisfied by the chef_api(1) location
|
27
|
+
Given I write to "Berksfile" with:
|
28
|
+
"""
|
29
|
+
chef_api :knife
|
30
|
+
site 'http://cookbooks.opscode.com/api/v1/cookbooks'
|
31
|
+
|
32
|
+
cookbook "artifact", "= 0.10.0"
|
33
|
+
"""
|
34
|
+
And the Chef server does not have the cookbooks:
|
35
|
+
| artifact | 0.10.0 |
|
36
|
+
When I run the install command
|
37
|
+
Then the output should contain:
|
38
|
+
"""
|
39
|
+
Installing artifact (0.10.0) from site: 'http://cookbooks.opscode.com/api/v1/cookbooks'
|
40
|
+
"""
|
41
|
+
And the cookbook store should have the cookbooks:
|
42
|
+
| artifact | 0.10.0 |
|
43
|
+
And the exit status should be 0
|
44
|
+
|
45
|
+
Scenario: with a default site(1) and chef_api(2) location with a cookbook source that is satisfied by the site(1) location
|
46
|
+
Given I write to "Berksfile" with:
|
47
|
+
"""
|
48
|
+
site 'http://cookbooks.opscode.com/api/v1/cookbooks'
|
49
|
+
chef_api :knife
|
50
|
+
|
51
|
+
cookbook "artifact", "= 0.10.0"
|
52
|
+
"""
|
53
|
+
And the Chef server has cookbooks:
|
54
|
+
| artifact | 0.10.0 |
|
55
|
+
When I run the install command
|
56
|
+
Then the output should contain:
|
57
|
+
"""
|
58
|
+
Installing artifact (0.10.0) from site: 'http://cookbooks.opscode.com/api/v1/cookbooks'
|
59
|
+
"""
|
60
|
+
And the cookbook store should have the cookbooks:
|
61
|
+
| artifact | 0.10.0 |
|
62
|
+
And the exit status should be 0
|
63
|
+
|
64
|
+
Scenario: with a default chef_api(1) location and a cookbook source that is satisfied by the chef_api(1) location but has an explicit location set
|
65
|
+
Given I write to "Berksfile" with:
|
66
|
+
"""
|
67
|
+
chef_api :knife
|
68
|
+
|
69
|
+
cookbook 'artifact', '= 0.10.0', site: 'http://cookbooks.opscode.com/api/v1/cookbooks'
|
70
|
+
"""
|
71
|
+
And the Chef server has cookbooks:
|
72
|
+
| artifact | 0.10.0 |
|
73
|
+
When I run the install command
|
74
|
+
Then the output should contain:
|
75
|
+
"""
|
76
|
+
Installing artifact (0.10.0) from site: 'http://cookbooks.opscode.com/api/v1/cookbooks'
|
77
|
+
"""
|
78
|
+
And the cookbook store should have the cookbooks:
|
79
|
+
| artifact | 0.10.0 |
|
80
|
+
And the exit status should be 0
|
81
|
+
|
82
|
+
Scenario: with a defualt chef_api(1) location and a cookbook source that is not satisfied by it
|
83
|
+
Given I write to "Berksfile" with:
|
84
|
+
"""
|
85
|
+
chef_api :knife
|
86
|
+
|
87
|
+
cookbook 'artifact', '= 0.10.0'
|
88
|
+
"""
|
89
|
+
And the Chef server does not have the cookbooks:
|
90
|
+
| artifact | 0.10.0 |
|
91
|
+
When I run the install command
|
92
|
+
Then the output should contain:
|
93
|
+
"""
|
94
|
+
Cookbook 'artifact' not found in any of the default locations
|
95
|
+
"""
|
96
|
+
And the CLI should exit with the status code for error "CookbookNotFound"
|
97
|
+
|
98
|
+
Scenario: with two duplicate locations definitions
|
99
|
+
Given I write to "Berksfile" with:
|
100
|
+
"""
|
101
|
+
site 'http://cookbooks.opscode.com/api/v1/cookbooks'
|
102
|
+
site 'http://cookbooks.opscode.com/api/v1/cookbooks'
|
103
|
+
|
104
|
+
cookbook 'artifact', '= 0.10.0'
|
105
|
+
"""
|
106
|
+
When I run the install command
|
107
|
+
Then the output should contain:
|
108
|
+
"""
|
109
|
+
A default 'site' location with the value 'http://cookbooks.opscode.com/api/v1/cookbooks' is already defined
|
110
|
+
"""
|
111
|
+
And the CLI should exit with the status code for error "DuplicateLocationDefined"
|
112
|
+
|
113
|
+
Scenario: with two locations of the same type but different values
|
114
|
+
Given I write to "Berksfile" with:
|
115
|
+
"""
|
116
|
+
site 'http://cookbooks.opscode.com/api/v1/cookbooks'
|
117
|
+
site 'http://cookbooks.opscode.com/api/v2/cookbooks'
|
118
|
+
|
119
|
+
cookbook 'artifact', '= 0.10.0'
|
120
|
+
"""
|
121
|
+
When I run the install command
|
122
|
+
Then the exit status should be 0
|
data/features/install.feature
CHANGED
@@ -65,7 +65,7 @@ Feature: install cookbooks from a Berksfile
|
|
65
65
|
"""
|
66
66
|
And the exit status should be 0
|
67
67
|
|
68
|
-
@
|
68
|
+
@no_run
|
69
69
|
Scenario: installing a Berksfile that contains a path location which contains a broken symlink
|
70
70
|
Given a Berksfile with path location sources to fixtures:
|
71
71
|
| example_cookbook_broken_link | example_cookbook_broken_link |
|
@@ -142,9 +142,9 @@ Feature: install cookbooks from a Berksfile
|
|
142
142
|
And I run the install command
|
143
143
|
Then the output should contain:
|
144
144
|
"""
|
145
|
-
Cookbook 'doesntexist' not found
|
145
|
+
Cookbook 'doesntexist' not found in any of the default locations
|
146
146
|
"""
|
147
|
-
And the CLI should exit with the status code for error "
|
147
|
+
And the CLI should exit with the status code for error "CookbookNotFound"
|
148
148
|
|
149
149
|
Scenario: running install command with the --shims flag to create a directory of shims
|
150
150
|
Given I write to "Berksfile" with:
|
@@ -162,6 +162,22 @@ Feature: install cookbooks from a Berksfile
|
|
162
162
|
"""
|
163
163
|
And the exit status should be 0
|
164
164
|
|
165
|
+
Scenario: running install command with the --shims flag and a relative path
|
166
|
+
Given I write to "Berksfile" with:
|
167
|
+
"""
|
168
|
+
cookbook "mysql", "1.2.4"
|
169
|
+
"""
|
170
|
+
When I run the install command with flags:
|
171
|
+
| --shims relativepath |
|
172
|
+
Then the following directories should exist:
|
173
|
+
| relativepath |
|
174
|
+
| relativepath/mysql |
|
175
|
+
And the output should contain:
|
176
|
+
"""
|
177
|
+
Shims written to:
|
178
|
+
"""
|
179
|
+
And the exit status should be 0
|
180
|
+
|
165
181
|
Scenario: running install with --shims when current project is a cookbook and the 'metadata' is specified
|
166
182
|
Given a cookbook named "sparkle_motion"
|
167
183
|
And the cookbook "sparkle_motion" has the file "Berksfile" with:
|
@@ -254,7 +270,7 @@ Feature: install cookbooks from a Berksfile
|
|
254
270
|
cookbook "artifact", chef_api: :knife
|
255
271
|
"""
|
256
272
|
And the Chef server has cookbooks:
|
257
|
-
| artifact | 0.10.
|
273
|
+
| artifact | 0.10.2 |
|
258
274
|
When I run the install command
|
259
275
|
Then the output should contain:
|
260
276
|
"""
|
data/features/lockfile.feature
CHANGED
@@ -7,16 +7,11 @@ Feature: Berksfile.lock
|
|
7
7
|
Scenario: Writing the Berksfile.lock
|
8
8
|
Given I write to "Berksfile" with:
|
9
9
|
"""
|
10
|
-
cookbook 'ntp'
|
11
|
-
cookbook 'mysql', git: 'https://github.com/opscode-cookbooks/mysql.git', :ref => '190c0c2267785b7b9b303369b8a64ed04364d5f9'
|
10
|
+
cookbook 'ntp', '1.1.8'
|
12
11
|
"""
|
13
12
|
When I run the install command
|
14
13
|
Then a file named "Berksfile.lock" should exist in the current directory
|
15
14
|
And the file "Berksfile.lock" should contain in the current directory:
|
16
15
|
"""
|
17
16
|
cookbook 'ntp', :locked_version => '1.1.8'
|
18
|
-
cookbook 'mysql', :git => 'https://github.com/opscode-cookbooks/mysql.git', :ref => '190c0c2267785b7b9b303369b8a64ed04364d5f9'
|
19
|
-
cookbook 'openssl', :locked_version => '1.0.0'
|
20
|
-
cookbook 'windows', :locked_version => '1.3.2'
|
21
|
-
cookbook 'chef_handler', :locked_version => '1.0.6'
|
22
17
|
"""
|
data/features/update.feature
CHANGED
@@ -6,7 +6,7 @@ Feature: update
|
|
6
6
|
Scenario: knife berkshelf update
|
7
7
|
Given I write to "Berksfile" with:
|
8
8
|
"""
|
9
|
-
cookbook "mysql"
|
9
|
+
cookbook "mysql", "1.3.0"
|
10
10
|
"""
|
11
11
|
Given I write to "Berksfile.lock" with:
|
12
12
|
"""
|
@@ -18,6 +18,5 @@ Feature: update
|
|
18
18
|
"""
|
19
19
|
cookbook 'mysql', :locked_version => '1.3.0'
|
20
20
|
cookbook 'openssl', :locked_version => '1.0.0'
|
21
|
-
cookbook '
|
22
|
-
cookbook 'chef_handler', :locked_version => '1.0.6'
|
21
|
+
cookbook 'build-essential', :locked_version => '1.1.0'
|
23
22
|
"""
|
data/lib/berkshelf.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'forwardable'
|
2
|
+
require 'uri'
|
1
3
|
require 'pathname'
|
2
4
|
require 'zlib'
|
3
5
|
require 'archive/tar/minitar'
|
@@ -20,7 +22,6 @@ module Berkshelf
|
|
20
22
|
DEFAULT_FILENAME = 'Berksfile'.freeze
|
21
23
|
|
22
24
|
autoload :Cli, 'berkshelf/cli'
|
23
|
-
autoload :DSL, 'berkshelf/dsl'
|
24
25
|
autoload :Git, 'berkshelf/git'
|
25
26
|
autoload :Berksfile, 'berkshelf/berksfile'
|
26
27
|
autoload :Lockfile, 'berkshelf/lockfile'
|
@@ -30,18 +31,17 @@ module Berkshelf
|
|
30
31
|
autoload :CookbookSource, 'berkshelf/cookbook_source'
|
31
32
|
autoload :CookbookStore, 'berkshelf/cookbook_store'
|
32
33
|
autoload :CachedCookbook, 'berkshelf/cached_cookbook'
|
33
|
-
autoload :TXResult, 'berkshelf/tx_result'
|
34
|
-
autoload :TXResultSet, 'berkshelf/tx_result_set'
|
35
34
|
autoload :Downloader, 'berkshelf/downloader'
|
36
35
|
autoload :Uploader, 'berkshelf/uploader'
|
37
36
|
autoload :Resolver, 'berkshelf/resolver'
|
38
37
|
|
38
|
+
require 'berkshelf/location'
|
39
|
+
|
39
40
|
class << self
|
40
41
|
attr_accessor :ui
|
41
|
-
|
42
|
-
attr_accessor :downloader
|
43
|
-
|
42
|
+
|
44
43
|
attr_writer :config_path
|
44
|
+
attr_writer :cookbook_store
|
45
45
|
|
46
46
|
def root
|
47
47
|
@root ||= Pathname.new(File.expand_path('../', File.dirname(__FILE__)))
|
@@ -74,10 +74,6 @@ module Berkshelf
|
|
74
74
|
@cookbook_store ||= CookbookStore.new(cookbooks_dir)
|
75
75
|
end
|
76
76
|
|
77
|
-
def downloader
|
78
|
-
@downloader ||= Downloader.new(cookbook_store)
|
79
|
-
end
|
80
|
-
|
81
77
|
def config_path
|
82
78
|
@config_path ||= DEFAULT_CONFIG
|
83
79
|
end
|
data/lib/berkshelf/berksfile.rb
CHANGED
@@ -1,9 +1,13 @@
|
|
1
1
|
module Berkshelf
|
2
2
|
# @author Jamie Winsor <jamie@vialstudios.com>
|
3
3
|
class Berksfile
|
4
|
-
|
4
|
+
extend Forwardable
|
5
5
|
|
6
6
|
class << self
|
7
|
+
# @param [String] file
|
8
|
+
# a path on disk to a Berksfile to instantiate from
|
9
|
+
#
|
10
|
+
# @return [Berksfile]
|
7
11
|
def from_file(file)
|
8
12
|
content = File.read(file)
|
9
13
|
object = new(file)
|
@@ -28,26 +32,201 @@ module Berkshelf
|
|
28
32
|
end
|
29
33
|
end
|
30
34
|
|
35
|
+
@@active_group = nil
|
36
|
+
|
37
|
+
# @return [String]
|
38
|
+
# The path on disk to the file representing this instance of Berksfile
|
31
39
|
attr_reader :filepath
|
40
|
+
|
41
|
+
# @return [Berkshelf::Downloader]
|
42
|
+
attr_reader :downloader
|
43
|
+
|
44
|
+
def_delegator :downloader, :add_location
|
45
|
+
def_delegator :downloader, :locations
|
32
46
|
|
33
47
|
def initialize(path)
|
34
48
|
@filepath = path
|
35
49
|
@sources = Hash.new
|
50
|
+
@downloader = Downloader.new(Berkshelf.cookbook_store)
|
36
51
|
end
|
37
52
|
|
38
|
-
# Add
|
39
|
-
#
|
40
|
-
#
|
53
|
+
# Add a cookbook source to the Berksfile to be retrieved and have it's dependencies recurisvely retrieved
|
54
|
+
# and resolved.
|
55
|
+
#
|
56
|
+
# @example a cookbook source that will be retrieved from one of the default locations
|
57
|
+
# cookbook 'artifact'
|
58
|
+
#
|
59
|
+
# @example a cookbook source that will be retrieved from a path on disk
|
60
|
+
# cookbook 'artifact', path: '/Users/reset/code/artifact'
|
61
|
+
#
|
62
|
+
# @example a cookbook source that will be retrieved from a remote community site
|
63
|
+
# cookbook 'artifact', site: 'http://cookbooks.opscode.com/api/v1/cookbooks'
|
64
|
+
#
|
65
|
+
# @example a cookbook source that will be retrieved from the latest API of the Opscode Community Site
|
66
|
+
# cookbook 'artifact', site: :opscode
|
67
|
+
#
|
68
|
+
# @example a cookbook source that will be retrieved from a Git server
|
69
|
+
# cookbook 'artifact', git: 'git://github.com/RiotGames/artifact-cookbook.git'
|
41
70
|
#
|
42
|
-
# @
|
43
|
-
#
|
71
|
+
# @example a cookbook source that will be retrieved from a Chef API (Chef Server)
|
72
|
+
# cookbook 'artifact', chef_api: 'https://api.opscode.com/organizations/vialstudios', node_name: 'reset', client_key: '/Users/reset/.chef/knife.rb'
|
73
|
+
#
|
74
|
+
# @example a cookbook source that will be retrieved from a Chef API using your Knife config
|
75
|
+
# cookbook 'artifact', chef_api: :knife
|
76
|
+
#
|
77
|
+
# @overload cookbook(name, version_constraint, options = {})
|
78
|
+
# @param [#to_s] name
|
79
|
+
# @param [#to_s] version_constraint
|
80
|
+
# @param [Hash] options
|
81
|
+
#
|
82
|
+
# @option options [Symbol, Array] :group
|
83
|
+
# the group or groups that the cookbook belongs to
|
84
|
+
# @option options [String, Symbol] :chef_api
|
85
|
+
# a URL to a Chef API. Alternatively the symbol :knife can be provided
|
86
|
+
# which will instantiate this location with the values found in your
|
87
|
+
# knife configuration.
|
88
|
+
# @option options [String] :site
|
89
|
+
# a URL pointing to a community API endpoint
|
90
|
+
# @option options [String] :path
|
91
|
+
# a filepath to the cookbook on your local disk
|
92
|
+
# @option options [String] :git
|
93
|
+
# the Git URL to clone
|
94
|
+
#
|
95
|
+
# @see ChefAPILocation
|
96
|
+
# @see SiteLocation
|
97
|
+
# @see PathLocation
|
98
|
+
# @see GitLocation
|
99
|
+
# @overload cookbook(name, options = {})
|
100
|
+
# @param [#to_s] name
|
101
|
+
# @param [Hash] options
|
102
|
+
#
|
103
|
+
# @option options [Symbol, Array] :group
|
104
|
+
# the group or groups that the cookbook belongs to
|
105
|
+
# @option options [String, Symbol] :chef_api
|
106
|
+
# a URL to a Chef API. Alternatively the symbol :knife can be provided
|
107
|
+
# which will instantiate this location with the values found in your
|
108
|
+
# knife configuration.
|
109
|
+
# @option options [String] :site
|
110
|
+
# a URL pointing to a community API endpoint
|
111
|
+
# @option options [String] :path
|
112
|
+
# a filepath to the cookbook on your local disk
|
113
|
+
# @option options [String] :git
|
114
|
+
# the Git URL to clone
|
115
|
+
#
|
116
|
+
# @see ChefAPILocation
|
117
|
+
# @see SiteLocation
|
118
|
+
# @see PathLocation
|
119
|
+
# @see GitLocation
|
120
|
+
def cookbook(*args)
|
121
|
+
options = args.last.is_a?(Hash) ? args.pop : Hash.new
|
122
|
+
name, constraint = args
|
123
|
+
|
124
|
+
options[:group] = Array(options[:group])
|
125
|
+
|
126
|
+
if @@active_group
|
127
|
+
options[:group] += @@active_group
|
128
|
+
end
|
129
|
+
|
130
|
+
add_source(name, constraint, options)
|
131
|
+
end
|
132
|
+
|
133
|
+
|
134
|
+
def group(*args)
|
135
|
+
@@active_group = args
|
136
|
+
yield
|
137
|
+
@@active_group = nil
|
138
|
+
end
|
139
|
+
|
140
|
+
# Use a Cookbook metadata file to determine additional cookbook sources to retrieve. All
|
141
|
+
# sources found in the metadata will use the default locations set in the Berksfile (if any are set)
|
142
|
+
# or the default locations defined by Berkshelf.
|
143
|
+
#
|
144
|
+
# @param [Hash] options
|
145
|
+
#
|
146
|
+
# @option options [String] :path
|
147
|
+
# path to the metadata file
|
148
|
+
def metadata(options = {})
|
149
|
+
path = options[:path] || File.dirname(filepath)
|
150
|
+
|
151
|
+
metadata_file = Berkshelf.find_metadata(path)
|
152
|
+
|
153
|
+
unless metadata_file
|
154
|
+
raise CookbookNotFound, "No 'metadata.rb' found at #{path}"
|
155
|
+
end
|
156
|
+
|
157
|
+
metadata = Chef::Cookbook::Metadata.new
|
158
|
+
metadata.from_file(metadata_file.to_s)
|
159
|
+
|
160
|
+
name = if metadata.name.empty? || metadata.name.nil?
|
161
|
+
File.basename(File.dirname(metadata_file))
|
162
|
+
else
|
163
|
+
metadata.name
|
164
|
+
end
|
165
|
+
|
166
|
+
constraint = "= #{metadata.version}"
|
167
|
+
|
168
|
+
add_source(name, constraint, path: File.dirname(metadata_file))
|
169
|
+
end
|
170
|
+
|
171
|
+
# Add a 'Site' default location which will be used to resolve cookbook sources that do not
|
172
|
+
# contain an explicit location.
|
173
|
+
#
|
174
|
+
# @note
|
175
|
+
# specifying the symbol :opscode as the value of the site default location is an alias for the
|
176
|
+
# latest API of the Opscode Community Site.
|
177
|
+
#
|
178
|
+
# @example
|
179
|
+
# site :opscode
|
180
|
+
# site "http://cookbooks.opscode.com/api/v1/cookbooks"
|
181
|
+
#
|
182
|
+
# @param [String, Symbol] value
|
183
|
+
#
|
184
|
+
# @return [Hash]
|
185
|
+
def site(value)
|
186
|
+
add_location(:site, value)
|
187
|
+
end
|
188
|
+
|
189
|
+
# Add a 'Chef API' default location which will be used to resolve cookbook sources that do not
|
190
|
+
# contain an explicit location.
|
191
|
+
#
|
192
|
+
# @note
|
193
|
+
# specifying the symbol :knife as the value of the chef_api default location will attempt to use the
|
194
|
+
# contents of your user's Knife.rb to find the Chef API to interact with.
|
195
|
+
#
|
196
|
+
# @example using the symbol :knife to add a Chef API default location
|
197
|
+
# chef_api :knife
|
198
|
+
#
|
199
|
+
# @example using a URL, node_name, and client_key to add a Chef API default location
|
200
|
+
# chef_api "https://api.opscode.com/organizations/vialstudios", node_name: "reset", client_key: "/Users/reset/.chef/knife.rb"
|
201
|
+
#
|
202
|
+
# @param [String, Symbol] value
|
203
|
+
# @param [Hash] options
|
204
|
+
#
|
205
|
+
# @return [Hash]
|
206
|
+
def chef_api(value, options = {})
|
207
|
+
add_location(:chef_api, value, options)
|
208
|
+
end
|
209
|
+
|
210
|
+
# Add a source of the given name and constraint to the array of sources.
|
211
|
+
#
|
212
|
+
# @param [String] name
|
213
|
+
# the name of the source to add
|
214
|
+
# @param [String, Solve::Constraint] constraint
|
215
|
+
# the constraint to lock the source to
|
216
|
+
# @param [Hash] options
|
217
|
+
#
|
218
|
+
# @raise [DuplicateSourceDefined] if a source is added whose name conflicts
|
219
|
+
# with a source who has already been added.
|
44
220
|
#
|
45
221
|
# @return [Array<Berkshelf::CookbookSource]
|
46
|
-
def add_source(
|
47
|
-
if has_source?(
|
48
|
-
raise DuplicateSourceDefined, "Berksfile contains two sources named '#{
|
222
|
+
def add_source(name, constraint = nil, options = {})
|
223
|
+
if has_source?(name)
|
224
|
+
raise DuplicateSourceDefined, "Berksfile contains two sources named '#{name}'. Remove one and try again."
|
49
225
|
end
|
50
|
-
|
226
|
+
|
227
|
+
options[:constraint] = constraint
|
228
|
+
|
229
|
+
@sources[name] = CookbookSource.new(name, options)
|
51
230
|
end
|
52
231
|
|
53
232
|
# @param [#to_s] source
|
@@ -97,7 +276,7 @@ module Berkshelf
|
|
97
276
|
# }
|
98
277
|
def groups
|
99
278
|
{}.tap do |groups|
|
100
|
-
|
279
|
+
sources.each do |source|
|
101
280
|
source.groups.each do |group|
|
102
281
|
groups[group] ||= []
|
103
282
|
groups[group] << source
|
@@ -122,7 +301,11 @@ module Berkshelf
|
|
122
301
|
# Path to a directory of shims each pointing to a Cookbook Version that is
|
123
302
|
# part of the dependency solution. Each shim is a hard link on disk.
|
124
303
|
def install(options = {})
|
125
|
-
resolver = Resolver.new(
|
304
|
+
resolver = Resolver.new(
|
305
|
+
self.downloader,
|
306
|
+
sources: sources(exclude: options[:without])
|
307
|
+
)
|
308
|
+
|
126
309
|
solution = resolver.resolve
|
127
310
|
if options[:shims]
|
128
311
|
write_shims(options[:shims], solution)
|
@@ -154,7 +337,7 @@ module Berkshelf
|
|
154
337
|
|
155
338
|
solution.each do |cb|
|
156
339
|
Berkshelf.formatter.upload cb.cookbook_name, cb.version, chef_server_url
|
157
|
-
uploader.upload
|
340
|
+
uploader.upload(cb, options)
|
158
341
|
end
|
159
342
|
end
|
160
343
|
|
@@ -166,7 +349,10 @@ module Berkshelf
|
|
166
349
|
#
|
167
350
|
# @return [Array<Berkshelf::CachedCookbooks]
|
168
351
|
def resolve(options = {})
|
169
|
-
Resolver.new(
|
352
|
+
Resolver.new(
|
353
|
+
self.downloader,
|
354
|
+
sources: sources(exclude: options[:without])
|
355
|
+
).resolve
|
170
356
|
end
|
171
357
|
|
172
358
|
# Write a collection of hard links to the given path representing the given
|
@@ -182,6 +368,7 @@ module Berkshelf
|
|
182
368
|
# @param [Pathname, String] path
|
183
369
|
# @param [Array<Berkshelf::CachedCookbook>] cached_cookbooks
|
184
370
|
def write_shims(path, cached_cookbooks)
|
371
|
+
path = File.expand_path(path)
|
185
372
|
actual_path = nil
|
186
373
|
|
187
374
|
if descendant_directory?(path, Dir.pwd)
|
@@ -207,6 +394,8 @@ module Berkshelf
|
|
207
394
|
#
|
208
395
|
# @param [String] content
|
209
396
|
#
|
397
|
+
# @raise [BerksfileReadError] if Berksfile contains bad content
|
398
|
+
#
|
210
399
|
# @return [Berksfile]
|
211
400
|
def load(content)
|
212
401
|
begin
|