berkshelf 0.3.3 → 0.3.7
Sign up to get free protection for your applications and to get access to all the features.
- data/Guardfile +1 -1
- data/features/install.feature +129 -2
- data/features/lockfile.feature +1 -1
- data/features/step_definitions/filesystem_steps.rb +12 -0
- data/features/update.feature +1 -1
- data/features/upload_command.feature +1 -1
- data/lib/berkshelf/berksfile.rb +4 -1
- data/lib/berkshelf/cached_cookbook.rb +36 -9
- data/lib/berkshelf/cli.rb +2 -2
- data/lib/berkshelf/cookbook_source.rb +26 -63
- data/lib/berkshelf/cookbook_source/git_location.rb +21 -10
- data/lib/berkshelf/cookbook_source/location.rb +50 -0
- data/lib/berkshelf/cookbook_source/path_location.rb +13 -5
- data/lib/berkshelf/cookbook_source/site_location.rb +14 -4
- data/lib/berkshelf/cookbook_store.rb +34 -16
- data/lib/berkshelf/core_ext/string.rb +12 -0
- data/lib/berkshelf/downloader.rb +0 -4
- data/lib/berkshelf/errors.rb +41 -1
- data/lib/berkshelf/git.rb +83 -14
- data/lib/berkshelf/resolver.rb +85 -66
- data/lib/berkshelf/version.rb +1 -1
- data/spec/fixtures/cookbooks/example_cookbook-0.5.0/metadata.rb +1 -0
- data/spec/fixtures/cookbooks/example_metadata_name/metadata.rb +2 -0
- data/spec/fixtures/cookbooks/example_metadata_no_name/metadata.rb +1 -0
- data/spec/fixtures/cookbooks/example_no_metadata/recipes/default.rb +1 -0
- data/spec/support/chef_api.rb +42 -0
- data/spec/unit/berkshelf/cached_cookbook_spec.rb +55 -11
- data/spec/unit/berkshelf/cookbook_source/git_location_spec.rb +65 -15
- data/spec/unit/berkshelf/cookbook_source/location_spec.rb +42 -0
- data/spec/unit/berkshelf/cookbook_source/path_location_spec.rb +22 -5
- data/spec/unit/berkshelf/cookbook_source/site_location_spec.rb +32 -13
- data/spec/unit/berkshelf/cookbook_source_spec.rb +24 -33
- data/spec/unit/berkshelf/cookbook_store_spec.rb +47 -7
- data/spec/unit/berkshelf/git_spec.rb +97 -12
- data/spec/unit/berkshelf/resolver_spec.rb +72 -48
- data/spec/unit/berkshelf/uploader_spec.rb +12 -4
- metadata +13 -7
- data/spec/fixtures/cookbooks/invalid_ruby_files-1.0.0/recipes/default.rb +0 -1
- data/spec/fixtures/cookbooks/invalid_template_files-1.0.0/templates/default/broken.erb +0 -1
data/Guardfile
CHANGED
@@ -16,7 +16,7 @@ guard 'rspec', :version => 2, :cli => "--color --drb --format Fuubar", :all_on_s
|
|
16
16
|
watch('spec/spec_helper.rb') { "spec" }
|
17
17
|
end
|
18
18
|
|
19
|
-
guard 'cucumber', :cli => "--drb --format pretty --tags ~@
|
19
|
+
guard 'cucumber', :cli => "--drb --format pretty --tags ~@no_run", :all_on_start => false, :all_after_pass => false, :notification => false do
|
20
20
|
watch(%r{^features/.+\.feature$})
|
21
21
|
watch(%r{^features/support/.+$}) { 'features' }
|
22
22
|
watch(%r{^features/step_definitions/(.+)_steps\.rb$}) { |m| Dir[File.join("**/#{m[1]}.feature")][0] || 'features' }
|
data/features/install.feature
CHANGED
@@ -3,7 +3,7 @@ Feature: install cookbooks from a Berksfile
|
|
3
3
|
I want to be able to run knife berkshelf install to install my cookbooks
|
4
4
|
So that I don't have to download my cookbooks and their dependencies manually
|
5
5
|
|
6
|
-
Scenario:
|
6
|
+
Scenario: installing a Berksfile that contains a source with a default location
|
7
7
|
Given I write to "Berksfile" with:
|
8
8
|
"""
|
9
9
|
cookbook "mysql", "1.2.4"
|
@@ -17,6 +17,83 @@ Feature: install cookbooks from a Berksfile
|
|
17
17
|
Installing mysql (1.2.4) from site: 'http://cookbooks.opscode.com/api/v1/cookbooks'
|
18
18
|
Installing openssl (1.0.0) from site: 'http://cookbooks.opscode.com/api/v1/cookbooks'
|
19
19
|
"""
|
20
|
+
And the exit status should be 0
|
21
|
+
|
22
|
+
Scenario: installing a Berksfile that contains the cookbook explicitly desired by a source
|
23
|
+
Given the cookbook store has the cookbooks:
|
24
|
+
| mysql | 1.2.4 |
|
25
|
+
And I write to "Berksfile" with:
|
26
|
+
"""
|
27
|
+
cookbook "mysql", "= 1.2.4"
|
28
|
+
"""
|
29
|
+
When I run the install command
|
30
|
+
Then the output should contain:
|
31
|
+
"""
|
32
|
+
Using mysql (1.2.4)
|
33
|
+
"""
|
34
|
+
And the exit status should be 0
|
35
|
+
|
36
|
+
Scenario: installing a Berksfile that contains a source with dependencies, all of which already have been installed
|
37
|
+
Given the cookbook store contains a cookbook "mysql" "1.2.4" with dependencies:
|
38
|
+
| openssl | = 1.0.0 |
|
39
|
+
| windows | = 1.3.0 |
|
40
|
+
| chef_handler | = 1.0.6 |
|
41
|
+
And the cookbook store has the cookbooks:
|
42
|
+
| openssl | 1.0.0 |
|
43
|
+
| windows | 1.3.0 |
|
44
|
+
And I write to "Berksfile" with:
|
45
|
+
"""
|
46
|
+
cookbook "mysql", "~> 1.2.0"
|
47
|
+
"""
|
48
|
+
When I run the install command
|
49
|
+
Then the output should contain:
|
50
|
+
"""
|
51
|
+
Using mysql (1.2.4)
|
52
|
+
Using openssl (1.0.0)
|
53
|
+
Using windows (1.3.0)
|
54
|
+
Installing chef_handler (1.0.6) from site:
|
55
|
+
"""
|
56
|
+
And the exit status should be 0
|
57
|
+
|
58
|
+
Scenario: installing a Berksfile that contains a path location
|
59
|
+
Given a Berksfile with path location sources to fixtures:
|
60
|
+
| example_cookbook | example_cookbook-0.5.0 |
|
61
|
+
When I run the install command
|
62
|
+
Then the output should contain:
|
63
|
+
"""
|
64
|
+
Using example_cookbook (0.5.0) at path:
|
65
|
+
"""
|
66
|
+
And the exit status should be 0
|
67
|
+
|
68
|
+
Scenario: installing a Berksfile that contains a Git location
|
69
|
+
Given I write to "Berksfile" with:
|
70
|
+
"""
|
71
|
+
cookbook "artifact", git: "git://github.com/RiotGames/artifact-cookbook.git", ref: "0.9.8"
|
72
|
+
"""
|
73
|
+
When I run the install command
|
74
|
+
Then the cookbook store should have the cookbooks:
|
75
|
+
| artifact | 0.9.8 |
|
76
|
+
And the output should contain:
|
77
|
+
"""
|
78
|
+
Installing artifact (0.9.8) from git: 'git://github.com/RiotGames/artifact-cookbook.git' with branch: '0.9.8'
|
79
|
+
"""
|
80
|
+
And the exit status should be 0
|
81
|
+
|
82
|
+
Scenario: installing a Berksfile that contains an explicit site location
|
83
|
+
Given I write to "Berksfile" with:
|
84
|
+
"""
|
85
|
+
cookbook "mysql", "1.2.4", site: "http://cookbooks.opscode.com/api/v1/cookbooks"
|
86
|
+
"""
|
87
|
+
When I run the install command
|
88
|
+
Then the cookbook store should have the cookbooks:
|
89
|
+
| mysql | 1.2.4 |
|
90
|
+
| openssl | 1.0.0 |
|
91
|
+
And the output should contain:
|
92
|
+
"""
|
93
|
+
Installing mysql (1.2.4) from site: 'http://cookbooks.opscode.com/api/v1/cookbooks'
|
94
|
+
Installing openssl (1.0.0) from site: 'http://cookbooks.opscode.com/api/v1/cookbooks'
|
95
|
+
"""
|
96
|
+
And the exit status should be 0
|
20
97
|
|
21
98
|
Scenario: running install when current project is a cookbook and the 'metadata' is specified
|
22
99
|
Given a cookbook named "sparkle_motion"
|
@@ -54,7 +131,6 @@ Feature: install cookbooks from a Berksfile
|
|
54
131
|
"""
|
55
132
|
And the CLI should exit with the status code for error "DownloadFailure"
|
56
133
|
|
57
|
-
@wip
|
58
134
|
Scenario: running install command with the --shims flag to create a directory of shims
|
59
135
|
Given I write to "Berksfile" with:
|
60
136
|
"""
|
@@ -70,3 +146,54 @@ Feature: install cookbooks from a Berksfile
|
|
70
146
|
Shims written to:
|
71
147
|
"""
|
72
148
|
And the exit status should be 0
|
149
|
+
|
150
|
+
Scenario: installing a Berksfile that has a Git location source with an invalid Git URI
|
151
|
+
Given I write to "Berksfile" with:
|
152
|
+
"""
|
153
|
+
cookbook "nginx", git: "/something/on/disk"
|
154
|
+
"""
|
155
|
+
When I run the install command
|
156
|
+
Then the output should contain:
|
157
|
+
"""
|
158
|
+
'/something/on/disk' is not a valid Git URI.
|
159
|
+
"""
|
160
|
+
And the CLI should exit with the status code for error "InvalidGitURI"
|
161
|
+
|
162
|
+
Scenario: installing when there are sources with duplicate names defined
|
163
|
+
Given I write to "Berksfile" with:
|
164
|
+
"""
|
165
|
+
cookbook "artifact"
|
166
|
+
cookbook "artifact"
|
167
|
+
"""
|
168
|
+
When I run the install command
|
169
|
+
Then the output should contain:
|
170
|
+
"""
|
171
|
+
Berksfile contains two sources named 'artifact'. Remove one and try again.
|
172
|
+
"""
|
173
|
+
And the CLI should exit with the status code for error "DuplicateSourceDefined"
|
174
|
+
|
175
|
+
Scenario: installing when a git source defines a branch that does not satisfy the version constraint
|
176
|
+
Given I write to "Berksfile" with:
|
177
|
+
"""
|
178
|
+
cookbook "artifact", "= 0.9.8", git: "git://github.com/RiotGames/artifact-cookbook.git", ref: "0.10.0"
|
179
|
+
"""
|
180
|
+
When I run the install command
|
181
|
+
Then the output should contain:
|
182
|
+
"""
|
183
|
+
A cookbook satisfying 'artifact' (= 0.9.8) not found at git: 'git://github.com/RiotGames/artifact-cookbook.git' with branch: '0.10.0'
|
184
|
+
"""
|
185
|
+
And the CLI should exit with the status code for error "ConstraintNotSatisfied"
|
186
|
+
|
187
|
+
Scenario: when a git location source is defined and a cookbook of the same name is already cached in the cookbook store
|
188
|
+
Given I write to "Berksfile" with:
|
189
|
+
"""
|
190
|
+
cookbook "artifact", git: "git://github.com/RiotGames/artifact-cookbook.git", ref: "0.10.0"
|
191
|
+
"""
|
192
|
+
And the cookbook store has the cookbooks:
|
193
|
+
| artifact | 0.10.0 |
|
194
|
+
When I run the install command
|
195
|
+
Then the output should contain:
|
196
|
+
"""
|
197
|
+
Installing artifact (0.10.0) from git: 'git://github.com/RiotGames/artifact-cookbook.git' with branch: '0.10.0'
|
198
|
+
"""
|
199
|
+
And the exit status should be 0
|
data/features/lockfile.feature
CHANGED
@@ -17,6 +17,6 @@ Feature: Berksfile.lock
|
|
17
17
|
cookbook 'ntp', :locked_version => '1.1.8'
|
18
18
|
cookbook 'mysql', :git => 'https://github.com/opscode-cookbooks/mysql.git', :ref => '190c0c2267785b7b9b303369b8a64ed04364d5f9'
|
19
19
|
cookbook 'openssl', :locked_version => '1.0.0'
|
20
|
-
cookbook 'chef_handler', :locked_version => '1.0.6'
|
21
20
|
cookbook 'windows', :locked_version => '1.3.0'
|
21
|
+
cookbook 'chef_handler', :locked_version => '1.0.6'
|
22
22
|
"""
|
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'aruba/api'
|
2
2
|
|
3
3
|
World(Aruba::Api)
|
4
|
+
World(Berkshelf::RSpec::ChefAPI)
|
4
5
|
|
5
6
|
Given /^a cookbook named "(.*?)"$/ do |name|
|
6
7
|
steps %{
|
@@ -21,6 +22,17 @@ Given /^the cookbook "(.*?)" has the file "(.*?)" with:$/ do |cookbook_name, fil
|
|
21
22
|
write_file(File.join(cookbook_name, file_name), content)
|
22
23
|
end
|
23
24
|
|
25
|
+
Given /^the cookbook store has the cookbooks:$/ do |cookbooks|
|
26
|
+
cookbooks.raw.each do |name, version|
|
27
|
+
generate_cookbook(cookbook_store, name, version)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
Given /^the cookbook store contains a cookbook "(.*?)" "(.*?)" with dependencies:$/ do |name, version, dependencies|
|
32
|
+
generate_cookbook(cookbook_store, name, version, dependencies: dependencies.raw)
|
33
|
+
end
|
34
|
+
|
35
|
+
|
24
36
|
Then /^the cookbook store should have the cookbooks:$/ do |cookbooks|
|
25
37
|
cookbooks.raw.each do |name, version|
|
26
38
|
cookbook_store.should have_structure {
|
data/features/update.feature
CHANGED
@@ -18,6 +18,6 @@ Feature: update
|
|
18
18
|
"""
|
19
19
|
cookbook 'mysql', :locked_version => '1.2.6'
|
20
20
|
cookbook 'openssl', :locked_version => '1.0.0'
|
21
|
-
cookbook 'chef_handler', :locked_version => '1.0.6'
|
22
21
|
cookbook 'windows', :locked_version => '1.3.0'
|
22
|
+
cookbook 'chef_handler', :locked_version => '1.0.6'
|
23
23
|
"""
|
@@ -3,7 +3,7 @@ Feature: upload command
|
|
3
3
|
I need a way to upload cookbooks to a Chef server that I have installed into my Bookshelf
|
4
4
|
So they are available to Chef clients
|
5
5
|
|
6
|
-
@
|
6
|
+
@no_run @slow_process
|
7
7
|
Scenario: running the upload command when the Sources in the Berksfile are already installed
|
8
8
|
Given I write to "Berksfile" with:
|
9
9
|
"""
|
data/lib/berkshelf/berksfile.rb
CHANGED
@@ -47,7 +47,9 @@ module Berkshelf
|
|
47
47
|
#
|
48
48
|
# @return [Array<Berkshelf::CookbookSource]
|
49
49
|
def add_source(source)
|
50
|
-
|
50
|
+
if has_source?(source)
|
51
|
+
raise DuplicateSourceDefined, "Berksfile contains two sources named '#{source.name}'. Remove one and try again."
|
52
|
+
end
|
51
53
|
@sources[source.to_s] = source
|
52
54
|
end
|
53
55
|
|
@@ -186,6 +188,7 @@ module Berkshelf
|
|
186
188
|
FileUtils.mkdir_p(path)
|
187
189
|
cached_cookbooks.each do |cached_cookbook|
|
188
190
|
destination = File.expand_path(File.join(path, cached_cookbook.cookbook_name))
|
191
|
+
FileUtils.rm_rf(destination)
|
189
192
|
begin
|
190
193
|
FileUtils.ln_r(cached_cookbook.path, destination, force: true)
|
191
194
|
rescue ArgumentError
|
@@ -5,22 +5,48 @@ module Berkshelf
|
|
5
5
|
# @author Jamie Winsor <jamie@vialstudios.com>
|
6
6
|
class CachedCookbook
|
7
7
|
class << self
|
8
|
-
#
|
8
|
+
# Creates a new instance of Berkshelf::CachedCookbook from a path on disk that
|
9
|
+
# contains a Cookbook. The name of the Cookbook will be determined first by the
|
10
|
+
# name attribute of the metadata.rb file if it is present. If the name attribute
|
11
|
+
# has not been set the Cookbook name will be determined by the basename of the
|
12
|
+
# given filepath.
|
13
|
+
#
|
14
|
+
# @param [#to_s] path
|
15
|
+
# a path on disk to the location of a Cookbook
|
16
|
+
#
|
17
|
+
# @return [Berkshelf::CachedCookbook]
|
18
|
+
def from_path(path)
|
19
|
+
path = Pathname.new(path)
|
20
|
+
metadata = Chef::Cookbook::Metadata.new
|
21
|
+
|
22
|
+
begin
|
23
|
+
metadata.from_file(path.join("metadata.rb").to_s)
|
24
|
+
rescue IOError
|
25
|
+
raise CookbookNotFound, "No 'metadata.rb' file found at: '#{path}'"
|
26
|
+
end
|
27
|
+
|
28
|
+
name = metadata.name.empty? ? File.basename(path) : metadata.name
|
29
|
+
|
30
|
+
new(name, path, metadata)
|
31
|
+
end
|
32
|
+
|
33
|
+
# @param [#to_s] path
|
9
34
|
# a path on disk to the location of a Cookbook downloaded by the Downloader
|
10
35
|
#
|
11
36
|
# @return [CachedCookbook]
|
12
37
|
# an instance of CachedCookbook initialized by the contents found at the
|
13
38
|
# given path.
|
14
|
-
def
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
cached_name = matchdata[1]
|
39
|
+
def from_store_path(path)
|
40
|
+
path = Pathname.new(path)
|
41
|
+
cached_name = File.basename(path.to_s).slice(DIRNAME_REGEXP, 1)
|
42
|
+
return nil if cached_name.nil?
|
19
43
|
|
20
44
|
metadata = Chef::Cookbook::Metadata.new
|
21
45
|
|
22
|
-
|
46
|
+
begin
|
23
47
|
metadata.from_file(path.join("metadata.rb").to_s)
|
48
|
+
rescue IOError
|
49
|
+
raise CookbookNotFound, "No 'metadata.rb' file found at: '#{path}'"
|
24
50
|
end
|
25
51
|
|
26
52
|
new(cached_name, path, metadata)
|
@@ -37,7 +63,7 @@ module Berkshelf
|
|
37
63
|
end
|
38
64
|
end
|
39
65
|
|
40
|
-
DIRNAME_REGEXP = /^(.+)-(
|
66
|
+
DIRNAME_REGEXP = /^(.+)-(.+)$/
|
41
67
|
CHEF_TYPE = "cookbook_version".freeze
|
42
68
|
CHEF_JSON_CLASS = "Chef::CookbookVersion".freeze
|
43
69
|
|
@@ -67,7 +93,8 @@ module Berkshelf
|
|
67
93
|
# }
|
68
94
|
attr_reader :manifest
|
69
95
|
|
70
|
-
|
96
|
+
def_delegator :@metadata, :version
|
97
|
+
def_delegator :@metadata, :dependencies
|
71
98
|
|
72
99
|
def initialize(name, path, metadata)
|
73
100
|
@cookbook_name = name
|
data/lib/berkshelf/cli.rb
CHANGED
@@ -8,7 +8,6 @@ module Berkshelf
|
|
8
8
|
super
|
9
9
|
# JW TODO: Replace Chef::Knife::UI with our own UI class
|
10
10
|
::Berkshelf.ui = Chef::Knife::UI.new(STDOUT, STDERR, STDIN, {})
|
11
|
-
load_config
|
12
11
|
@options = options.dup # unfreeze frozen options Hash from Thor
|
13
12
|
rescue BerkshelfError => e
|
14
13
|
Berkshelf.ui.fatal e
|
@@ -24,7 +23,7 @@ module Berkshelf
|
|
24
23
|
|
25
24
|
class_option :config,
|
26
25
|
type: :string,
|
27
|
-
default: File.expand_path("~/.chef/knife.rb"),
|
26
|
+
default: File.expand_path(ENV["CHEF_CONFIG"] || "~/.chef/knife.rb"),
|
28
27
|
desc: "Path to Knife or Chef configuration to use.",
|
29
28
|
aliases: "-c",
|
30
29
|
banner: "PATH"
|
@@ -96,6 +95,7 @@ module Berkshelf
|
|
96
95
|
desc: "Upload all cookbooks even if a frozen one exists on the target Chef Server"
|
97
96
|
desc "upload", "Upload the Cookbooks specified by a Berksfile or a Berksfile.lock to a Chef Server."
|
98
97
|
def upload
|
98
|
+
load_config
|
99
99
|
berksfile = ::Berkshelf::Berksfile.from_file(options[:berksfile])
|
100
100
|
berksfile.upload(Chef::Config[:chef_server_url], options)
|
101
101
|
rescue BerkshelfError => e
|
@@ -1,18 +1,9 @@
|
|
1
1
|
module Berkshelf
|
2
2
|
# @author Jamie Winsor <jamie@vialstudios.com>
|
3
3
|
class CookbookSource
|
4
|
-
|
5
|
-
attr_reader :name
|
6
|
-
|
7
|
-
def initialize(name)
|
8
|
-
@name = name
|
9
|
-
end
|
10
|
-
|
11
|
-
def download(destination)
|
12
|
-
raise NotImplementedError, "Function must be implemented on includer"
|
13
|
-
end
|
14
|
-
end
|
4
|
+
extend Forwardable
|
15
5
|
|
6
|
+
autoload :Location, 'berkshelf/cookbook_source/location'
|
16
7
|
autoload :SiteLocation, 'berkshelf/cookbook_source/site_location'
|
17
8
|
autoload :GitLocation, 'berkshelf/cookbook_source/git_location'
|
18
9
|
autoload :PathLocation, 'berkshelf/cookbook_source/path_location'
|
@@ -20,49 +11,52 @@ module Berkshelf
|
|
20
11
|
LOCATION_KEYS = [:git, :path, :site]
|
21
12
|
|
22
13
|
attr_reader :name
|
14
|
+
alias_method :to_s, :name
|
15
|
+
|
23
16
|
attr_reader :version_constraint
|
24
17
|
attr_reader :groups
|
25
18
|
attr_reader :location
|
26
|
-
|
19
|
+
attr_accessor :cached_cookbook
|
27
20
|
|
28
|
-
|
29
|
-
|
30
|
-
# @
|
31
|
-
#
|
32
|
-
#
|
21
|
+
def_delegator :@location, :downloaded?
|
22
|
+
|
23
|
+
# @overload initialize(name, version_constraint, options = {})
|
24
|
+
# @param [#to_s] name
|
25
|
+
# @param [#to_s] version_constraint
|
26
|
+
# @param [Hash] options
|
27
|
+
# @overload initialize(name, options = {})
|
28
|
+
# @param [#to_s] name
|
29
|
+
# @param [Hash] options
|
33
30
|
def initialize(*args)
|
34
31
|
options = args.last.is_a?(Hash) ? args.pop : {}
|
35
32
|
name, constraint = args
|
36
33
|
|
37
34
|
@name = name
|
38
|
-
@version_constraint = DepSelector::VersionConstraint.new(constraint)
|
35
|
+
@version_constraint = DepSelector::VersionConstraint.new(constraint || ">= 0.0.0")
|
39
36
|
@groups = []
|
40
|
-
@
|
37
|
+
@cached_cookbook = nil
|
41
38
|
|
42
39
|
if (options.keys & LOCATION_KEYS).length > 1
|
43
40
|
raise ArgumentError, "Only one location key (#{LOCATION_KEYS.join(', ')}) may be specified"
|
44
41
|
end
|
45
42
|
|
46
|
-
options[:version_constraint] = version_constraint if version_constraint
|
47
|
-
|
48
43
|
@location = case
|
49
44
|
when options[:git]
|
50
|
-
GitLocation.new(name, options)
|
45
|
+
GitLocation.new(name, version_constraint, options)
|
51
46
|
when options[:path]
|
52
|
-
loc = PathLocation.new(name, options)
|
53
|
-
|
47
|
+
loc = PathLocation.new(name, version_constraint, options)
|
48
|
+
@cached_cookbook = CachedCookbook.from_path(loc.path)
|
54
49
|
loc
|
55
50
|
when options[:site]
|
56
|
-
SiteLocation.new(name, options)
|
51
|
+
SiteLocation.new(name, version_constraint, options)
|
57
52
|
else
|
58
|
-
SiteLocation.new(name, options)
|
53
|
+
SiteLocation.new(name, version_constraint, options)
|
59
54
|
end
|
60
55
|
|
61
56
|
@locked_version = DepSelector::Version.new(options[:locked_version]) if options[:locked_version]
|
62
57
|
|
63
58
|
add_group(options[:group]) if options[:group]
|
64
59
|
add_group(:default) if groups.empty?
|
65
|
-
set_downloaded_status(false)
|
66
60
|
end
|
67
61
|
|
68
62
|
def add_group(*groups)
|
@@ -83,55 +77,24 @@ module Berkshelf
|
|
83
77
|
# [ :ok, "/tmp/nginx" ]
|
84
78
|
# [ :error, "Cookbook 'sparkle_motion' not found at site: http://cookbooks.opscode.com/api/v1/cookbooks" ]
|
85
79
|
def download(destination)
|
86
|
-
|
87
|
-
|
80
|
+
self.cached_cookbook = location.download(destination)
|
81
|
+
|
82
|
+
[ :ok, self.cached_cookbook ]
|
88
83
|
rescue CookbookNotFound => e
|
89
|
-
|
84
|
+
self.cached_cookbook = nil
|
90
85
|
[ :error, e.message ]
|
91
86
|
end
|
92
87
|
|
93
|
-
def downloaded?
|
94
|
-
!local_path.nil?
|
95
|
-
end
|
96
|
-
|
97
|
-
def metadata
|
98
|
-
return nil unless local_path
|
99
|
-
|
100
|
-
cookbook_metadata = Chef::Cookbook::Metadata.new
|
101
|
-
cookbook_metadata.from_file(File.join(local_path, "metadata.rb"))
|
102
|
-
cookbook_metadata
|
103
|
-
end
|
104
|
-
|
105
|
-
def to_s
|
106
|
-
name
|
107
|
-
end
|
108
|
-
|
109
88
|
def has_group?(group)
|
110
89
|
groups.include?(group.to_sym)
|
111
90
|
end
|
112
91
|
|
113
|
-
def dependencies
|
114
|
-
return nil unless metadata
|
115
|
-
|
116
|
-
metadata.dependencies
|
117
|
-
end
|
118
|
-
|
119
|
-
def local_version
|
120
|
-
return nil unless metadata
|
121
|
-
|
122
|
-
metadata.version
|
123
|
-
end
|
124
|
-
|
125
92
|
def locked_version
|
126
|
-
@locked_version ||
|
93
|
+
@locked_version || cached_cookbook.version
|
127
94
|
end
|
128
95
|
|
129
96
|
private
|
130
97
|
|
131
|
-
def set_downloaded_status(state)
|
132
|
-
@downloaded_state = state
|
133
|
-
end
|
134
|
-
|
135
98
|
def set_local_path(path)
|
136
99
|
@local_path = path
|
137
100
|
end
|