knife_cookbook_dependencies 0.0.3 → 0.0.5
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +4 -1
- data/README.rdoc +41 -2
- data/Rakefile +42 -0
- data/features/lib/chef/knife/error_messages.feature +16 -0
- data/features/lib/chef/knife/lockfile.feature +25 -0
- data/features/lib/chef/knife/without.feature +27 -0
- data/features/support/env.rb +30 -0
- data/features/support/step_definitions.rb +22 -0
- data/knife_cookbook_dependencies.gemspec +6 -2
- data/lib/chef/knife/cookbook_dependencies_install.rb +12 -6
- data/lib/kcd.rb +1 -0
- data/lib/{knife_cookbook_dependencies → kcd}/cookbook.rb +72 -40
- data/lib/{knife_cookbook_dependencies → kcd}/cookbookfile.rb +12 -11
- data/lib/kcd/dsl.rb +13 -0
- data/lib/{knife_cookbook_dependencies → kcd}/error_messages.rb +1 -1
- data/lib/{knife_cookbook_dependencies → kcd}/git.rb +0 -0
- data/lib/{knife_cookbook_dependencies → kcd}/knife_utils.rb +1 -1
- data/lib/{knife_cookbook_dependencies → kcd}/lockfile.rb +8 -5
- data/lib/{knife_cookbook_dependencies → kcd}/metacookbook.rb +1 -1
- data/lib/{knife_cookbook_dependencies → kcd}/shelf.rb +30 -5
- data/lib/{knife_cookbook_dependencies → kcd}/version.rb +1 -1
- data/lib/knife_cookbook_dependencies.rb +20 -13
- data/spec/acceptance/knife_cookbook_dependencies_spec.rb +1 -11
- data/spec/fixtures/lockfile_spec/with_lock/Cookbookfile +1 -0
- data/spec/fixtures/lockfile_spec/without_lock/Cookbookfile.lock +5 -0
- data/spec/lib/{knife_cookbook_dependencies → kcd}/cookbook_spec.rb +43 -14
- data/spec/lib/{knife_cookbook_dependencies → kcd}/cookbookfile_spec.rb +3 -3
- data/spec/lib/kcd/dsl_spec.rb +56 -0
- data/spec/lib/{knife_cookbook_dependencies → kcd}/git_spec.rb +0 -0
- data/spec/lib/kcd/lockfile_spec.rb +54 -0
- data/spec/lib/kcd/shelf_spec.rb +81 -0
- data/spec/spec_helper.rb +22 -2
- data/todo.txt +8 -8
- metadata +98 -51
- data/lib/knife_cookbook_dependencies/dependency_reader.rb +0 -46
- data/lib/knife_cookbook_dependencies/dsl.rb +0 -7
- data/spec/lib/knife_cookbook_dependencies/dependency_reader_spec.rb +0 -42
- data/spec/lib/knife_cookbook_dependencies/dsl_spec.rb +0 -29
- data/spec/lib/knife_cookbook_dependencies/shelf_spec.rb +0 -37
data/.gitignore
CHANGED
data/README.rdoc
CHANGED
@@ -1,6 +1,44 @@
|
|
1
1
|
= Knife Cookbook Dependencies
|
2
2
|
|
3
|
-
|
3
|
+
A knife plugin to manage cookbook dependencies.
|
4
|
+
|
5
|
+
== Getting Started
|
6
|
+
|
7
|
+
To start, just install the plugin
|
8
|
+
|
9
|
+
$ gem install knife_cookbook_dependencies
|
10
|
+
|
11
|
+
And add your dependencies to the Cookbookfile in the top-level of your repo
|
12
|
+
|
13
|
+
cookbook 'memcached'
|
14
|
+
cookbook 'ngnix'
|
15
|
+
|
16
|
+
Install the dependencies to cookbooks/
|
17
|
+
|
18
|
+
$ knife cookbook dependencies install
|
19
|
+
|
20
|
+
Put dependencies in a group so they can be ignored at deploy time. This is especially helpful
|
21
|
+
when working with chef-solo.
|
22
|
+
|
23
|
+
group :solo do
|
24
|
+
cookbook 'base'
|
25
|
+
end
|
26
|
+
|
27
|
+
If you only have 1 in the group, you can pass it as an option
|
28
|
+
|
29
|
+
cookbook 'base', :group => 'solo'
|
30
|
+
|
31
|
+
By default, cookbooks are loaded from the community site. You can load them from a git repository
|
32
|
+
|
33
|
+
cookbook 'nfs', :git => 'git://github.com/RiotGames/cookbook-nfs.git'
|
34
|
+
|
35
|
+
Or from a local path
|
36
|
+
|
37
|
+
cookbook 'myapp', :path => './cookbook'
|
38
|
+
|
39
|
+
= Contributing
|
40
|
+
|
41
|
+
== Running tests
|
4
42
|
|
5
43
|
=== Install prerequisites
|
6
44
|
|
@@ -27,4 +65,5 @@ Bundler will install all gems and their dependencies required for testing and de
|
|
27
65
|
|
28
66
|
* Josiah Kiehl (<josiah@skirmisher.net>)
|
29
67
|
* Jamie Winsor (<jamie@vialstudios.com>)
|
30
|
-
* Erik Hollensbe (<erik@hollensbe.org>)
|
68
|
+
* Erik Hollensbe (<erik@hollensbe.org>)
|
69
|
+
* Michael Ivey (<ivey@gweezlebur.com>)
|
data/Rakefile
CHANGED
@@ -27,3 +27,45 @@ end
|
|
27
27
|
|
28
28
|
task :check => [:default, "rdoc:check"]
|
29
29
|
task :default => [:clean, :spec]
|
30
|
+
|
31
|
+
begin
|
32
|
+
require 'rspec/core/rake_task'
|
33
|
+
|
34
|
+
desc "Run specs"
|
35
|
+
RSpec::Core::RakeTask.new(:spec) do |r|
|
36
|
+
r.rspec_path = "bundle exec rspec"
|
37
|
+
end
|
38
|
+
rescue LoadError
|
39
|
+
desc 'RSpec rake task not available'
|
40
|
+
task :spec do
|
41
|
+
abort 'RSpec rake task is not available. Be sure to install rspec.'
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
begin
|
46
|
+
require 'cucumber'
|
47
|
+
require 'cucumber/rake/task'
|
48
|
+
|
49
|
+
Cucumber::Rake::Task.new(:features) do |t|
|
50
|
+
t.cucumber_opts = "--format progress --tags ~@wip --tags ~@live"
|
51
|
+
end
|
52
|
+
|
53
|
+
namespace :features do
|
54
|
+
Cucumber::Rake::Task.new(:wip) do |t|
|
55
|
+
t.cucumber_opts = "--format progress --tags @wip"
|
56
|
+
end
|
57
|
+
|
58
|
+
Cucumber::Rake::Task.new(:current) do |t|
|
59
|
+
t.cucumber_opts = "--format progress --tags @current"
|
60
|
+
end
|
61
|
+
|
62
|
+
Cucumber::Rake::Task.new(:tag) do |t|
|
63
|
+
t.cucumber_opts = "--format progress --tags @#{ENV['tag']}"
|
64
|
+
end
|
65
|
+
end
|
66
|
+
rescue LoadError
|
67
|
+
desc 'Cucumber rake task not available'
|
68
|
+
task :features do
|
69
|
+
abort 'Cucumber rake task is not available. Be sure to install cucumber.'
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
Feature: Friendly error messages
|
2
|
+
As a CLI user
|
3
|
+
I want to have friendly human readable error messages
|
4
|
+
So I can identify what went wrong without ambiguity
|
5
|
+
|
6
|
+
Scenario: running without a Cookbookfile
|
7
|
+
When I run `knife cookbook dependencies install`
|
8
|
+
Then the output should contain "FATAL: There is no Cookbookfile in "
|
9
|
+
|
10
|
+
Scenario: when missing a cookbook
|
11
|
+
Given I write to "Cookbookfile" with:
|
12
|
+
"""
|
13
|
+
cookbook "doesntexist"
|
14
|
+
"""
|
15
|
+
When I run `knife cookbook dependencies install`
|
16
|
+
Then the output should contain "FATAL: The cookbook doesntexist was not found on the Opscode Community site. Provide a git or path key for doesntexist if it is unpublished."
|
@@ -0,0 +1,25 @@
|
|
1
|
+
Feature: Cookbookfile.lock
|
2
|
+
As a user
|
3
|
+
I want my versions to be locked even when I don't specify versions in my Cookbookfile
|
4
|
+
So when I share my repository, all other developers get the same versions that I did when I installed.
|
5
|
+
|
6
|
+
@slow_process
|
7
|
+
Scenario: Writing the Cookbookfile.lock
|
8
|
+
Given I write to "Cookbookfile" with:
|
9
|
+
"""
|
10
|
+
cookbook 'ntp'
|
11
|
+
cookbook 'mysql', git: 'https://github.com/opscode-cookbooks/mysql.git', :ref => '190c0c2267785b7b9b303369b8a64ed04364d5f9'
|
12
|
+
cookbook 'example_cookbook', path: File.join(KCD.root, 'spec', 'fixtures', 'cookbooks')
|
13
|
+
"""
|
14
|
+
When I run `knife cookbook dependencies install`
|
15
|
+
When I sleep
|
16
|
+
Then a file named "Cookbookfile.lock" should exist in the current directory
|
17
|
+
And the file "Cookbookfile.lock" should contain in the current directory:
|
18
|
+
"""
|
19
|
+
cookbook 'mysql', :git => 'https://github.com/opscode-cookbooks/mysql.git', :ref => '190c0c2267785b7b9b303369b8a64ed04364d5f9'
|
20
|
+
cookbook 'example_cookbook', :path => .*
|
21
|
+
cookbook 'ntp', :locked_version => '1.1.8'
|
22
|
+
cookbook 'openssl', :locked_version => '1.0.0'
|
23
|
+
cookbook 'windows', :locked_version => '1.2.12'
|
24
|
+
cookbook 'chef_handler', :locked_version => '1.0.6'
|
25
|
+
"""
|
@@ -0,0 +1,27 @@
|
|
1
|
+
Feature: --without block
|
2
|
+
As a user
|
3
|
+
I want to be able to exclude blocks in my Cookbookfile
|
4
|
+
So I can have cookbooks organized for use in different situations in a single Cookbookfile
|
5
|
+
|
6
|
+
@slow_process
|
7
|
+
Scenario: Exclude a block
|
8
|
+
Given I write to "Cookbookfile" with:
|
9
|
+
"""
|
10
|
+
group :notme do
|
11
|
+
cookbook "nginx"
|
12
|
+
end
|
13
|
+
|
14
|
+
cookbook "mysql"
|
15
|
+
|
16
|
+
group :takeme do
|
17
|
+
cookbook "ntp"
|
18
|
+
end
|
19
|
+
"""
|
20
|
+
When I run `knife cookbook dependencies install --without notme`
|
21
|
+
Then the following directories should exist:
|
22
|
+
| cookbooks/mysql |
|
23
|
+
| cookbooks/openssl |
|
24
|
+
| cookbooks/ntp |
|
25
|
+
And the following directories should not exist:
|
26
|
+
| cookbooks/nginx |
|
27
|
+
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'spork'
|
2
|
+
|
3
|
+
Spork.prefork do
|
4
|
+
require 'rspec'
|
5
|
+
require 'pp'
|
6
|
+
require 'aruba/cucumber'
|
7
|
+
require 'vcr'
|
8
|
+
|
9
|
+
APP_ROOT = File.expand_path('../../', __FILE__)
|
10
|
+
|
11
|
+
Dir[File.join(APP_ROOT, "spec/support/**/*.rb")].each {|f| require f}
|
12
|
+
|
13
|
+
After do
|
14
|
+
KCD.clean
|
15
|
+
end
|
16
|
+
|
17
|
+
Around do |scenario, block|
|
18
|
+
VCR.use_cassette(scenario.title) do
|
19
|
+
block.call
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
Before('@slow_process') do
|
24
|
+
@aruba_io_wait_seconds = 5
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
Spork.each_run do
|
29
|
+
require 'kcd'
|
30
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
Then /^I trace$/ do
|
2
|
+
end
|
3
|
+
|
4
|
+
When /^I sleep$/ do
|
5
|
+
sleep 10
|
6
|
+
end
|
7
|
+
|
8
|
+
Then /^a file named "(.*?)" should exist in the current directory$/ do |filename|
|
9
|
+
in_current_dir do
|
10
|
+
File.exists?(filename).should be_true # not sure why Aruba's
|
11
|
+
# #check_file_presence
|
12
|
+
# doesn't work here. It
|
13
|
+
# looks in the wrong
|
14
|
+
# directory.
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
Then /^the file "(.*?)" should contain in the current directory:$/ do |filename, string|
|
19
|
+
in_current_dir do
|
20
|
+
File.read(filename).should match(Regexp.new(string))
|
21
|
+
end
|
22
|
+
end
|
@@ -1,5 +1,6 @@
|
|
1
|
-
# -*- encoding: utf-8 -*-
|
2
|
-
|
1
|
+
# -*- encoding: utf-8; mode: ruby -*-
|
2
|
+
|
3
|
+
require File.expand_path('../lib/kcd/version', __FILE__)
|
3
4
|
|
4
5
|
Gem::Specification.new do |s|
|
5
6
|
# TODO FIXME need to modify all of these
|
@@ -20,6 +21,9 @@ Gem::Specification.new do |s|
|
|
20
21
|
s.add_runtime_dependency 'chef', '~> 0.10.0'
|
21
22
|
s.add_runtime_dependency 'minitar'
|
22
23
|
|
24
|
+
s.add_development_dependency 'cucumber'
|
25
|
+
s.add_development_dependency 'vcr'
|
26
|
+
s.add_development_dependency 'webmock'
|
23
27
|
s.add_development_dependency 'aruba'
|
24
28
|
s.add_development_dependency 'rake', '~> 0.9.0'
|
25
29
|
s.add_development_dependency 'rdoc', '~> 3.0'
|
@@ -1,17 +1,23 @@
|
|
1
1
|
require 'chef/knife'
|
2
|
-
require '
|
2
|
+
require 'kcd'
|
3
3
|
|
4
4
|
module KnifeCookbookDependencies
|
5
5
|
class CookbookDependenciesInstall < Chef::Knife
|
6
|
-
banner "knife cookbook dependencies install"
|
6
|
+
banner "knife cookbook dependencies install (options)"
|
7
|
+
|
8
|
+
option :without,
|
9
|
+
:short => "-W WITHOUT",
|
10
|
+
:long => "--without WITHOUT",
|
11
|
+
:description => "Exclude cookbooks that are in these groups"
|
7
12
|
|
8
13
|
def run
|
9
14
|
ui.info 'Reading Cookbookfile'
|
10
|
-
::
|
11
|
-
::
|
15
|
+
::KCD.ui = ui
|
16
|
+
::KCD::Cookbookfile.process_install(config[:without])
|
12
17
|
end
|
13
18
|
end
|
14
19
|
|
15
|
-
class CookbookDepsInstall < CookbookDependenciesInstall
|
16
|
-
|
20
|
+
class CookbookDepsInstall < CookbookDependenciesInstall
|
21
|
+
banner "knife cookbook deps install (options)"
|
22
|
+
end
|
17
23
|
end
|
data/lib/kcd.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'knife_cookbook_dependencies'
|
@@ -1,17 +1,17 @@
|
|
1
|
-
require 'knife_cookbook_dependencies/knife_utils'
|
2
|
-
require 'knife_cookbook_dependencies/git'
|
3
1
|
require 'chef/knife/cookbook_site_download'
|
4
2
|
require 'chef/knife/cookbook_site_show'
|
3
|
+
require 'chef/cookbook/metadata'
|
5
4
|
|
6
5
|
module KnifeCookbookDependencies
|
7
6
|
class Cookbook
|
8
|
-
attr_reader :name, :version_constraints
|
7
|
+
attr_reader :name, :version_constraints, :groups
|
9
8
|
attr_accessor :locked_version
|
10
9
|
|
11
10
|
DOWNLOAD_LOCATION = ENV["TMPDIR"] || '/tmp'
|
12
11
|
|
13
|
-
def initialize
|
12
|
+
def initialize(*args)
|
14
13
|
@options = args.last.is_a?(Hash) ? args.pop : {}
|
14
|
+
@groups = []
|
15
15
|
|
16
16
|
if from_git? and from_path?
|
17
17
|
raise "Invalid: path and git options provided to #{args[0]}. They are mutually exclusive."
|
@@ -21,14 +21,17 @@ module KnifeCookbookDependencies
|
|
21
21
|
@name, constraint_string = args
|
22
22
|
|
23
23
|
add_version_constraint(if from_path?
|
24
|
-
"= #{
|
24
|
+
"= #{version_from_metadata.to_s}"
|
25
25
|
else
|
26
26
|
constraint_string
|
27
27
|
end)
|
28
28
|
@locked_version = DepSelector::Version.new(@options[:locked_version]) if @options[:locked_version]
|
29
|
+
add_group(KnifeCookbookDependencies.shelf.active_group) if KnifeCookbookDependencies.shelf.active_group
|
30
|
+
add_group(@options[:group]) if @options[:group]
|
31
|
+
add_group(:default) if @groups.empty?
|
29
32
|
end
|
30
33
|
|
31
|
-
def add_version_constraint
|
34
|
+
def add_version_constraint(constraint_string)
|
32
35
|
@version_constraints ||= []
|
33
36
|
@version_constraints << DepSelector::VersionConstraint.new(constraint_string) unless @version_constraints.collect(&:to_s).include? constraint_string
|
34
37
|
end
|
@@ -36,22 +39,21 @@ module KnifeCookbookDependencies
|
|
36
39
|
def download(show_output = false)
|
37
40
|
return if @downloaded
|
38
41
|
return if !from_git? and downloaded_archive_exists?
|
42
|
+
return if from_path? and !from_git?
|
39
43
|
|
40
44
|
if from_git?
|
41
|
-
@git ||=
|
45
|
+
@git ||= KCD::Git.new(@options[:git])
|
42
46
|
@git.clone
|
43
47
|
@git.checkout(@options[:ref]) if @options[:ref]
|
44
48
|
@options[:path] ||= @git.directory
|
45
|
-
elsif from_path?
|
46
|
-
return
|
47
49
|
else
|
48
50
|
csd = Chef::Knife::CookbookSiteDownload.new([name, latest_constrained_version.to_s, "--file", download_filename])
|
49
51
|
rescue_404 do
|
50
|
-
output =
|
52
|
+
output = KCD::KnifeUtils.capture_knife_output(csd)
|
51
53
|
end
|
52
54
|
|
53
55
|
if show_output
|
54
|
-
|
56
|
+
output.split(/\r?\n/).each { |x| KCD.ui.info(x) }
|
55
57
|
end
|
56
58
|
end
|
57
59
|
|
@@ -59,69 +61,74 @@ module KnifeCookbookDependencies
|
|
59
61
|
end
|
60
62
|
|
61
63
|
def copy_to_cookbooks_directory
|
62
|
-
FileUtils.mkdir_p
|
64
|
+
FileUtils.mkdir_p KCD::COOKBOOKS_DIRECTORY
|
63
65
|
|
64
|
-
target = File.join(
|
66
|
+
target = File.join(KCD::COOKBOOKS_DIRECTORY, @name)
|
65
67
|
FileUtils.rm_rf target
|
66
68
|
FileUtils.cp_r full_path, target
|
67
69
|
FileUtils.rm_rf File.join(target, '.git') if from_git?
|
68
70
|
end
|
69
71
|
|
70
72
|
# TODO: Clean up download repetition functionality here, in #download and the associated test.
|
71
|
-
def unpack(location = unpacked_cookbook_path,
|
73
|
+
def unpack(location = unpacked_cookbook_path, options={})
|
72
74
|
return true if from_path?
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
Archive::Tar::Minitar.unpack(Zlib::GzipReader.new(File.open(fname)), location)
|
80
|
-
true
|
81
|
-
else
|
82
|
-
# TODO: Raise friendly error message class
|
75
|
+
|
76
|
+
clean if options[:clean]
|
77
|
+
download if options[:download]
|
78
|
+
|
79
|
+
unless downloaded_archive_exists? or File.directory?(location)
|
80
|
+
# TODO raise friendly error
|
83
81
|
raise "Archive hasn't been downloaded yet"
|
84
82
|
end
|
83
|
+
|
84
|
+
if downloaded_archive_exists?
|
85
|
+
Archive::Tar::Minitar.unpack(Zlib::GzipReader.new(File.open(download_filename)), location)
|
86
|
+
end
|
87
|
+
|
88
|
+
return true
|
85
89
|
end
|
86
90
|
|
87
91
|
def dependencies
|
88
92
|
download
|
89
93
|
unpack
|
90
|
-
|
94
|
+
|
95
|
+
unless @dependencies
|
96
|
+
@dependencies = []
|
97
|
+
metadata.dependencies.each { |name, constraint| depends(name, constraint) }
|
98
|
+
end
|
99
|
+
|
100
|
+
@dependencies
|
91
101
|
end
|
92
102
|
|
93
103
|
def latest_constrained_version
|
94
104
|
return @locked_version if @locked_version
|
95
|
-
return
|
105
|
+
return version_from_metadata if from_path? or from_git?
|
96
106
|
|
97
107
|
versions.reverse.each do |v|
|
98
108
|
return v if version_constraints_include? v
|
99
109
|
end
|
100
|
-
|
110
|
+
KCD.ui.fatal "No version available to fit the following constraints for #{@name}: #{version_constraints.inspect}\nAvailable versions: #{versions.inspect}"
|
101
111
|
exit 1
|
102
112
|
end
|
103
113
|
|
104
|
-
def version_constraints_include?
|
114
|
+
def version_constraints_include?(version)
|
105
115
|
@version_constraints.inject(true) { |check, constraint| check and constraint.include? version }
|
106
116
|
end
|
107
117
|
|
108
118
|
def versions
|
109
119
|
return [latest_constrained_version] if @locked_version
|
110
|
-
return [
|
120
|
+
return [version_from_metadata] if from_path? or from_git?
|
111
121
|
cookbook_data['versions'].collect { |v| DepSelector::Version.new(v.split(/\//).last.gsub(/_/, '.')) }.sort
|
112
122
|
end
|
113
123
|
|
114
|
-
def
|
115
|
-
|
116
|
-
# dependencyreader and incorporate pulling the version as
|
117
|
-
# well... knife probably has something like this I can use/steal
|
118
|
-
DepSelector::Version.new(metadata_file.match(/version\s+[\"\']([0-9\.]*)[\"\']/)[1])
|
124
|
+
def version_from_metadata
|
125
|
+
DepSelector::Version.new(metadata.version)
|
119
126
|
end
|
120
127
|
|
121
128
|
def cookbook_data
|
122
129
|
css = Chef::Knife::CookbookSiteShow.new([@name])
|
123
130
|
rescue_404 do
|
124
|
-
@cookbook_data ||= JSON.parse(
|
131
|
+
@cookbook_data ||= JSON.parse(KCD::KnifeUtils.capture_knife_output(css))
|
125
132
|
end
|
126
133
|
end
|
127
134
|
|
@@ -146,18 +153,25 @@ module KnifeCookbookDependencies
|
|
146
153
|
File.join(full_path, "metadata.rb")
|
147
154
|
end
|
148
155
|
|
149
|
-
def
|
156
|
+
def metadata
|
150
157
|
download
|
151
158
|
unpack
|
152
|
-
|
159
|
+
|
160
|
+
cookbook_metadata = Chef::Cookbook::Metadata.new
|
161
|
+
cookbook_metadata.from_file(metadata_filename)
|
162
|
+
cookbook_metadata
|
163
|
+
end
|
164
|
+
|
165
|
+
def local_path
|
166
|
+
@options[:path]
|
153
167
|
end
|
154
168
|
|
155
169
|
def from_path?
|
156
|
-
|
170
|
+
!!local_path
|
157
171
|
end
|
158
172
|
|
159
173
|
def from_git?
|
160
|
-
|
174
|
+
!!git_repo
|
161
175
|
end
|
162
176
|
|
163
177
|
def git_repo
|
@@ -168,6 +182,14 @@ module KnifeCookbookDependencies
|
|
168
182
|
(from_git? && @git) ? @git.ref : nil
|
169
183
|
end
|
170
184
|
|
185
|
+
def add_group(*groups)
|
186
|
+
groups = groups.first if groups.first.is_a?(Array)
|
187
|
+
groups.each do |group|
|
188
|
+
group = group.to_sym
|
189
|
+
@groups << group unless @groups.include?(group)
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
171
193
|
def downloaded_archive_exists?
|
172
194
|
download_filename && File.exists?(download_filename)
|
173
195
|
end
|
@@ -189,9 +211,19 @@ module KnifeCookbookDependencies
|
|
189
211
|
begin
|
190
212
|
yield
|
191
213
|
rescue Net::HTTPServerException => e
|
192
|
-
|
214
|
+
KCD.ui.fatal ErrorMessages.missing_cookbook(@name) if e.message.match(/404/)
|
193
215
|
exit 100
|
194
216
|
end
|
195
217
|
end
|
218
|
+
|
219
|
+
private
|
220
|
+
def depends(name, constraint = nil)
|
221
|
+
dependency_cookbook = KCD.shelf.get_cookbook(name) || @dependencies.find { |c| c.name == name }
|
222
|
+
if dependency_cookbook
|
223
|
+
dependency_cookbook.add_version_constraint constraint
|
224
|
+
else
|
225
|
+
@dependencies << Cookbook.new(name, constraint)
|
226
|
+
end
|
227
|
+
end
|
196
228
|
end
|
197
229
|
end
|