berkshelf 0.4.0.rc4 → 0.4.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 +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
|