berkshelf 3.0.0.beta7 → 3.0.0.beta8
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.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.travis.yml +4 -1
- data/CONTRIBUTING.md +1 -1
- data/Gemfile +0 -1
- data/Guardfile +0 -8
- data/README.md +33 -13
- data/berkshelf.gemspec +3 -3
- data/features/commands/install.feature +16 -88
- data/features/commands/search.feature +15 -0
- data/features/commands/shelf/show.feature +2 -2
- data/features/commands/shelf/uninstall.feature +1 -1
- data/features/commands/show.feature +3 -3
- data/features/commands/update.feature +29 -1
- data/features/commands/upload.feature +172 -7
- data/features/commands/vendor.feature +32 -0
- data/features/json_formatter.feature +26 -24
- data/features/lifecycle.feature +285 -0
- data/features/lockfile.feature +9 -7
- data/features/step_definitions/chef_server_steps.rb +1 -0
- data/features/step_definitions/cli_steps.rb +2 -2
- data/features/step_definitions/filesystem_steps.rb +2 -4
- data/gem_graph.png +0 -0
- data/generator_files/chefignore +0 -2
- data/lib/berkshelf.rb +39 -14
- data/lib/berkshelf/berksfile.rb +161 -113
- data/lib/berkshelf/cached_cookbook.rb +2 -2
- data/lib/berkshelf/cli.rb +15 -3
- data/lib/berkshelf/commands/shelf.rb +3 -7
- data/lib/berkshelf/community_rest.rb +9 -9
- data/lib/berkshelf/config.rb +3 -3
- data/lib/berkshelf/cookbook_generator.rb +0 -8
- data/lib/berkshelf/cookbook_store.rb +1 -2
- data/lib/berkshelf/dependency.rb +25 -138
- data/lib/berkshelf/downloader.rb +41 -7
- data/lib/berkshelf/errors.rb +113 -214
- data/lib/berkshelf/formatters/base.rb +42 -0
- data/lib/berkshelf/formatters/human.rb +145 -0
- data/lib/berkshelf/formatters/json.rb +149 -133
- data/lib/berkshelf/formatters/null.rb +8 -18
- data/lib/berkshelf/init_generator.rb +1 -1
- data/lib/berkshelf/installer.rb +115 -104
- data/lib/berkshelf/location.rb +22 -121
- data/lib/berkshelf/locations/base.rb +75 -0
- data/lib/berkshelf/locations/git.rb +196 -0
- data/lib/berkshelf/locations/github.rb +8 -0
- data/lib/berkshelf/locations/path.rb +78 -0
- data/lib/berkshelf/lockfile.rb +452 -290
- data/lib/berkshelf/logger.rb +9 -3
- data/lib/berkshelf/mixin/logging.rb +4 -9
- data/lib/berkshelf/resolver.rb +12 -12
- data/lib/berkshelf/source.rb +13 -1
- data/lib/berkshelf/version.rb +1 -1
- data/spec/fixtures/cookbooks/example_cookbook-0.5.0/metadata.rb +3 -7
- data/spec/fixtures/cookbooks/example_cookbook/metadata.rb +3 -6
- data/spec/spec_helper.rb +5 -6
- data/spec/support/matchers/file_system_matchers.rb +4 -0
- data/spec/support/shared_examples/formatter.rb +11 -0
- data/spec/unit/berkshelf/berksfile_spec.rb +25 -28
- data/spec/unit/berkshelf/cli_spec.rb +19 -11
- data/spec/unit/berkshelf/dependency_spec.rb +4 -164
- data/spec/unit/berkshelf/formatters/base_spec.rb +35 -0
- data/spec/unit/berkshelf/formatters/human_spec.rb +7 -0
- data/spec/unit/berkshelf/formatters/json_spec.rb +7 -0
- data/spec/unit/berkshelf/formatters/null_spec.rb +7 -11
- data/spec/unit/berkshelf/location_spec.rb +16 -144
- data/spec/unit/berkshelf/locations/base_spec.rb +80 -0
- data/spec/unit/berkshelf/locations/git_spec.rb +249 -0
- data/spec/unit/berkshelf/locations/path_spec.rb +107 -0
- data/spec/unit/berkshelf/lockfile_parser_spec.rb +3 -3
- data/spec/unit/berkshelf/lockfile_spec.rb +55 -11
- data/spec/unit/berkshelf/logger_spec.rb +2 -2
- data/spec/unit/berkshelf/mixin/logging_spec.rb +5 -9
- data/spec/unit/berkshelf/source_spec.rb +32 -13
- data/spec/unit/berkshelf_spec.rb +6 -9
- metadata +33 -33
- data/.ruby-version +0 -1
- data/berkshelf-complete.sh +0 -75
- data/lib/berkshelf/formatters.rb +0 -110
- data/lib/berkshelf/formatters/human_readable.rb +0 -142
- data/lib/berkshelf/git.rb +0 -204
- data/lib/berkshelf/locations/git_location.rb +0 -135
- data/lib/berkshelf/locations/github_location.rb +0 -55
- data/lib/berkshelf/locations/mercurial_location.rb +0 -114
- data/lib/berkshelf/locations/path_location.rb +0 -88
- data/lib/berkshelf/mercurial.rb +0 -146
- data/lib/berkshelf/mixin.rb +0 -7
- data/spec/support/mercurial.rb +0 -123
- data/spec/unit/berkshelf/formatters_spec.rb +0 -114
- data/spec/unit/berkshelf/git_spec.rb +0 -312
- data/spec/unit/berkshelf/locations/git_location_spec.rb +0 -126
- data/spec/unit/berkshelf/locations/mercurial_location_spec.rb +0 -131
- data/spec/unit/berkshelf/locations/path_location_spec.rb +0 -25
- data/spec/unit/berkshelf/mercurial_spec.rb +0 -172
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Berkshelf
|
4
|
+
describe BaseFormatter do
|
5
|
+
it 'has abstract methods for all the messaging modes' do
|
6
|
+
expect {
|
7
|
+
subject.install('my_coobook','1.2.3','http://community')
|
8
|
+
}.to raise_error(AbstractFunction)
|
9
|
+
|
10
|
+
expect {
|
11
|
+
subject.use('my_coobook','1.2.3')
|
12
|
+
}.to raise_error(AbstractFunction)
|
13
|
+
|
14
|
+
expect {
|
15
|
+
subject.use('my_coobook','1.2.3','http://community')
|
16
|
+
}.to raise_error(AbstractFunction)
|
17
|
+
|
18
|
+
expect {
|
19
|
+
subject.upload('my_coobook','1.2.3','http://chef_server')
|
20
|
+
}.to raise_error(AbstractFunction)
|
21
|
+
|
22
|
+
expect {
|
23
|
+
subject.msg('something you to know')
|
24
|
+
}.to raise_error(AbstractFunction)
|
25
|
+
|
26
|
+
expect {
|
27
|
+
subject.error('whoa this is bad')
|
28
|
+
}.to raise_error(AbstractFunction)
|
29
|
+
|
30
|
+
expect {
|
31
|
+
subject.fetch(double('dependency'))
|
32
|
+
}.to raise_error(AbstractFunction)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -1,17 +1,13 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
|
4
|
-
|
3
|
+
module Berkshelf
|
4
|
+
describe NullFormatter do
|
5
|
+
it_behaves_like 'a formatter object'
|
5
6
|
|
6
|
-
|
7
|
-
|
8
|
-
expect {
|
9
|
-
|
10
|
-
}.to_not raise_error
|
11
|
-
end
|
12
|
-
|
13
|
-
it "returns nil for :#{meth}" do
|
14
|
-
expect(subject.send(meth)).to be_nil
|
7
|
+
it 'does not raise an error for abstract metods methods' do
|
8
|
+
expect { subject.install }.to_not raise_error
|
9
|
+
expect { subject.use }.to_not raise_error
|
10
|
+
expect { subject.msg }.to_not raise_error
|
15
11
|
end
|
16
12
|
end
|
17
13
|
end
|
@@ -1,156 +1,28 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
|
4
|
-
describe
|
5
|
-
|
6
|
-
let(:dependency) { double('dependency') }
|
3
|
+
module Berkshelf
|
4
|
+
describe Location do
|
5
|
+
let(:dependency) { double(name: 'bacon') }
|
7
6
|
|
8
|
-
|
9
|
-
|
10
|
-
|
7
|
+
describe '.init' do
|
8
|
+
it 'finds a :path location by key' do
|
9
|
+
instance = described_class.init(dependency, path: '~/Dev/meats/bacon')
|
10
|
+
expect(instance).to be_a(PathLocation)
|
11
11
|
end
|
12
12
|
|
13
|
-
it '
|
14
|
-
|
15
|
-
expect(
|
13
|
+
it 'finds a :git location by key' do
|
14
|
+
instance = described_class.init(dependency, git: 'git://foo.com/meats/bacon.git')
|
15
|
+
expect(instance).to be_a(GitLocation)
|
16
16
|
end
|
17
17
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
described_class.init(dependency, git: :value, path: :value)
|
22
|
-
}.to raise_error(Berkshelf::InternalError)
|
23
|
-
end
|
18
|
+
it 'finds a :github location by key' do
|
19
|
+
instance = described_class.init(dependency, github: 'meats/bacon')
|
20
|
+
expect(instance).to be_a(GitLocation)
|
24
21
|
end
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
describe Berkshelf::Location::Base do
|
30
|
-
describe "ClassMethods" do
|
31
|
-
subject { Class.new(described_class) }
|
32
|
-
|
33
|
-
describe "::set_location_key" do
|
34
|
-
before do
|
35
|
-
@original = Berkshelf::Dependency.class_variable_get :@@location_keys
|
36
|
-
Berkshelf::Dependency.class_variable_set :@@location_keys, {}
|
37
|
-
end
|
38
|
-
|
39
|
-
after do
|
40
|
-
Berkshelf::Dependency.class_variable_set :@@location_keys, @original
|
41
|
-
end
|
42
|
-
|
43
|
-
it 'adds the given location key Berkshelf::Dependency.location_keys' do
|
44
|
-
subject.set_location_key(:reset)
|
45
|
-
|
46
|
-
expect(Berkshelf::Dependency.location_keys).to have(1).item
|
47
|
-
expect(Berkshelf::Dependency.location_keys).to include(:reset)
|
48
|
-
expect(Berkshelf::Dependency.location_keys[:reset]).to eq(subject)
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
describe "::location_key" do
|
53
|
-
before do
|
54
|
-
@original = Berkshelf::Dependency.class_variable_get :@@location_keys
|
55
|
-
Berkshelf::Dependency.class_variable_set :@@location_keys, {}
|
56
|
-
end
|
57
|
-
|
58
|
-
after do
|
59
|
-
Berkshelf::Dependency.class_variable_set :@@location_keys, @original
|
60
|
-
end
|
61
|
-
|
62
|
-
it "returns the class' registered location key" do
|
63
|
-
subject.set_location_key(:reset)
|
64
|
-
expect(subject.location_key).to eq(:reset)
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
describe "::set_valid_options" do
|
69
|
-
before do
|
70
|
-
@original = Berkshelf::Dependency.class_variable_get :@@valid_options
|
71
|
-
Berkshelf::Dependency.class_variable_set :@@valid_options, []
|
72
|
-
end
|
73
|
-
|
74
|
-
after do
|
75
|
-
Berkshelf::Dependency.class_variable_set :@@valid_options, @original
|
76
|
-
end
|
77
|
-
|
78
|
-
it 'adds the given symbol to the list of valid options on Berkshelf::Dependency' do
|
79
|
-
subject.set_valid_options(:mundo)
|
80
|
-
|
81
|
-
expect(Berkshelf::Dependency.valid_options).to have(1).item
|
82
|
-
expect(Berkshelf::Dependency.valid_options).to include(:mundo)
|
83
|
-
end
|
84
|
-
|
85
|
-
it 'adds parameters to the list of valid options on the Berkshelf::Dependency' do
|
86
|
-
subject.set_valid_options(:riot, :arenanet)
|
87
|
-
|
88
|
-
expect(Berkshelf::Dependency.valid_options).to have(2).items
|
89
|
-
expect(Berkshelf::Dependency.valid_options).to include(:riot)
|
90
|
-
expect(Berkshelf::Dependency.valid_options).to include(:arenanet)
|
91
|
-
end
|
92
|
-
end
|
93
|
-
end
|
94
|
-
|
95
|
-
let(:name) { "nginx" }
|
96
|
-
let(:constraint) { double('constraint') }
|
97
|
-
let(:dependency) { double('dependency', name: name, version_constraint: constraint) }
|
98
|
-
subject { Class.new(Berkshelf::Location::Base).new(dependency) }
|
99
|
-
|
100
|
-
describe "#download" do
|
101
|
-
context "when #do_download is not defined" do
|
102
|
-
it "raises a AbstractFunction" do
|
103
|
-
expect { subject.download }.to raise_error(Berkshelf::AbstractFunction)
|
104
|
-
end
|
105
|
-
end
|
106
|
-
|
107
|
-
context "when #do_download is defined" do
|
108
|
-
let(:cached) { double('cached') }
|
109
|
-
before { subject.stub(do_download: cached) }
|
110
|
-
|
111
|
-
it "validates the returned cached cookbook" do
|
112
|
-
subject.should_receive(:validate_cached).with(cached).and_return(true)
|
113
|
-
subject.download
|
114
|
-
end
|
115
|
-
|
116
|
-
it "returns the cached cookbook if valid" do
|
117
|
-
subject.stub(validate_cached: true)
|
118
|
-
|
119
|
-
expect(subject.download).to eq(cached)
|
120
|
-
end
|
121
|
-
end
|
122
|
-
end
|
123
|
-
|
124
|
-
describe '#validate_cached' do
|
125
|
-
let(:cached) { double('cached-cb', cookbook_name: name, version: '0.1.0') }
|
126
|
-
|
127
|
-
it 'raises a CookbookValidationFailure error if the version constraint does not satisfy the cached version' do
|
128
|
-
constraint.should_receive(:satisfies?).with(cached.version).and_return(false)
|
129
|
-
|
130
|
-
expect {
|
131
|
-
subject.validate_cached(cached)
|
132
|
-
}.to raise_error(Berkshelf::CookbookValidationFailure)
|
133
|
-
end
|
134
|
-
|
135
|
-
it 'returns true if cached_cookbooks satisfies the version constraint' do
|
136
|
-
constraint.should_receive(:satisfies?).with(cached.version).and_return(true)
|
137
|
-
expect(subject.validate_cached(cached)).to be_true
|
138
|
-
end
|
139
|
-
|
140
|
-
context "when the cached_cookbooks satisfies the version constraint" do
|
141
|
-
it "returns true if the name of the cached_cookbook matches the name of the location" do
|
142
|
-
constraint.should_receive(:satisfies?).with(cached.version).and_return(true)
|
143
|
-
cached.stub(:name) { name }
|
144
|
-
expect(subject.validate_cached(cached)).to be_true
|
145
|
-
end
|
146
|
-
|
147
|
-
it "warns about the MismatchedCookbookName if the cached_cookbook's name does not match the location's" do
|
148
|
-
constraint.should_receive(:satisfies?).with(cached.version).and_return(true)
|
149
|
-
cached.stub(:cookbook_name) { "artifact" }
|
150
|
-
msg = Berkshelf::MismatchedCookbookName.new(dependency, cached).to_s
|
151
22
|
|
152
|
-
|
153
|
-
|
23
|
+
it 'returns nil when a location cannot be found' do
|
24
|
+
instance = described_class.init(dependency, lamesauce: 'meats/bacon')
|
25
|
+
expect(instance).to be_nil
|
154
26
|
end
|
155
27
|
end
|
156
28
|
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Berkshelf
|
4
|
+
describe BaseLocation do
|
5
|
+
let(:constraint) { double('constraint') }
|
6
|
+
let(:dependency) { double('dependency', name: 'cookbook', version_constraint: constraint) }
|
7
|
+
|
8
|
+
subject { described_class.new(dependency) }
|
9
|
+
|
10
|
+
describe '#installed?' do
|
11
|
+
it 'is an abstract function' do
|
12
|
+
expect { subject.installed? }.to raise_error(AbstractFunction)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
describe '#install' do
|
17
|
+
it 'is an abstract function' do
|
18
|
+
expect { subject.install }.to raise_error(AbstractFunction)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
describe '#cached_cookbook' do
|
23
|
+
it 'is an abstract function' do
|
24
|
+
expect { subject.cached_cookbook }.to raise_error(AbstractFunction)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
describe '#to_lock' do
|
29
|
+
it 'is an abstract function' do
|
30
|
+
expect { subject.to_lock }.to raise_error(AbstractFunction)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
describe '#validate_cached!' do
|
35
|
+
context 'when the path is not a cookbook' do
|
36
|
+
before { File.stub(:cookbook?).and_return(false) }
|
37
|
+
|
38
|
+
it 'raises an error' do
|
39
|
+
expect {
|
40
|
+
subject.validate_cached!('/foo/bar')
|
41
|
+
}.to raise_error(NotACookbook)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
context 'when the path is a cookbook' do
|
46
|
+
let(:cookbook) do
|
47
|
+
double('cookbook',
|
48
|
+
cookbook_name: 'cookbook',
|
49
|
+
version: '0.1.0',
|
50
|
+
)
|
51
|
+
end
|
52
|
+
|
53
|
+
before do
|
54
|
+
File.stub(:cookbook?).and_return(true)
|
55
|
+
CachedCookbook.stub(:from_path).and_return(cookbook)
|
56
|
+
end
|
57
|
+
|
58
|
+
it 'raises an error if the constraint does not satisfy' do
|
59
|
+
constraint.stub(:satisfies?).with('0.1.0').and_return(false)
|
60
|
+
expect {
|
61
|
+
subject.validate_cached!(cookbook)
|
62
|
+
}.to raise_error(CookbookValidationFailure)
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'raises an error if the names do not match' do
|
66
|
+
constraint.stub(:satisfies?).with('0.1.0').and_return(true)
|
67
|
+
cookbook.stub(:cookbook_name).and_return('different_name')
|
68
|
+
expect {
|
69
|
+
subject.validate_cached!(cookbook)
|
70
|
+
}.to raise_error(MismatchedCookbookName)
|
71
|
+
end
|
72
|
+
|
73
|
+
it 'returns true when the validation succeeds' do
|
74
|
+
constraint.stub(:satisfies?).with('0.1.0').and_return(true)
|
75
|
+
expect(subject.validate_cached!(cookbook)).to be_true
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,249 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Berkshelf
|
4
|
+
describe GitLocation do
|
5
|
+
let(:dependency) { double(name: 'bacon') }
|
6
|
+
|
7
|
+
subject do
|
8
|
+
described_class.new(dependency, git: 'https://repo.com', branch: 'ham',
|
9
|
+
tag: 'v1.2.3', ref: 'abc123', revision: 'defjkl123456', rel: 'hi')
|
10
|
+
end
|
11
|
+
|
12
|
+
describe '.initialize' do
|
13
|
+
it 'sets the uri' do
|
14
|
+
instance = described_class.new(dependency, git: 'https://repo.com')
|
15
|
+
expect(instance.uri).to eq('https://repo.com')
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'sets the branch' do
|
19
|
+
instance = described_class.new(dependency,
|
20
|
+
git: 'https://repo.com', branch: 'magic_new_feature')
|
21
|
+
expect(instance.branch).to eq('magic_new_feature')
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'sets the tag' do
|
25
|
+
instance = described_class.new(dependency,
|
26
|
+
git: 'https://repo.com', tag: 'v1.2.3')
|
27
|
+
expect(instance.tag).to eq('v1.2.3')
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'adds the ref' do
|
31
|
+
instance = described_class.new(dependency,
|
32
|
+
git: 'https://repo.com', ref: 'abc123')
|
33
|
+
expect(instance.ref).to eq('abc123')
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'sets the revision' do
|
37
|
+
instance = described_class.new(dependency,
|
38
|
+
git: 'https://repo.com', revision: 'abcde12345')
|
39
|
+
expect(instance.revision).to eq('abcde12345')
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'sets the rel' do
|
43
|
+
instance = described_class.new(dependency,
|
44
|
+
git: 'https://repo.com', rel: 'internal/path')
|
45
|
+
expect(instance.rel).to eq('internal/path')
|
46
|
+
end
|
47
|
+
|
48
|
+
context 'rev_parse' do
|
49
|
+
def rev_parse(instance)
|
50
|
+
instance.instance_variable_get(:@rev_parse)
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'uses the :ref option with priority' do
|
54
|
+
instance = described_class.new(dependency,
|
55
|
+
git: 'https://repo.com', ref: 'abc123', branch: 'magic_new_feature')
|
56
|
+
expect(rev_parse(instance)).to eq('abc123')
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'uses the :branch option with priority' do
|
60
|
+
instance = described_class.new(dependency,
|
61
|
+
git: 'https://repo.com', branch: 'magic_new_feature', tag: 'v1.2.3')
|
62
|
+
expect(rev_parse(instance)).to eq('magic_new_feature')
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'uses the :tag option' do
|
66
|
+
instance = described_class.new(dependency,
|
67
|
+
git: 'https://repo.com', tag: 'v1.2.3')
|
68
|
+
expect(rev_parse(instance)).to eq('v1.2.3')
|
69
|
+
end
|
70
|
+
|
71
|
+
it 'uses "master" when none is given' do
|
72
|
+
instance = described_class.new(dependency, git: 'https://repo.com')
|
73
|
+
expect(rev_parse(instance)).to eq('master')
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
describe '#installed?' do
|
79
|
+
it 'returns false when there is no revision' do
|
80
|
+
subject.stub(:revision).and_return(nil)
|
81
|
+
expect(subject.installed?).to be_false
|
82
|
+
end
|
83
|
+
|
84
|
+
it 'returns false when the install_path does not exist' do
|
85
|
+
subject.stub(:revision).and_return('abcd1234')
|
86
|
+
subject.stub(:install_path).and_return(double(exist?: false))
|
87
|
+
expect(subject.installed?).to be_false
|
88
|
+
end
|
89
|
+
|
90
|
+
it 'returns true when the location is installed' do
|
91
|
+
subject.stub(:revision).and_return('abcd1234')
|
92
|
+
subject.stub(:install_path).and_return(double(exist?: true))
|
93
|
+
expect(subject.installed?).to be_true
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
describe '#install' do
|
98
|
+
before do
|
99
|
+
File.stub(:chmod)
|
100
|
+
FileUtils.stub(:cp_r)
|
101
|
+
subject.stub(:validate_cached!)
|
102
|
+
subject.stub(:git)
|
103
|
+
end
|
104
|
+
|
105
|
+
context 'when the repository is cached' do
|
106
|
+
it 'pulls a new version' do
|
107
|
+
Dir.stub(:chdir) { |args, &b| b.call } # Force eval the chdir block
|
108
|
+
|
109
|
+
subject.stub(:cached?).and_return(true)
|
110
|
+
expect(subject).to receive(:git).with(
|
111
|
+
'fetch --force --tags https://repo.com "refs/heads/*:refs/heads/*"'
|
112
|
+
)
|
113
|
+
subject.install
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
context 'when the revision is not cached' do
|
118
|
+
it 'clones the repository' do
|
119
|
+
Dir.stub(:chdir) { |args, &b| b.call } # Force eval the chdir block
|
120
|
+
|
121
|
+
cache_path = subject.send(:cache_path)
|
122
|
+
subject.stub(:cached?).and_return(false)
|
123
|
+
expect(subject).to receive(:git).with(
|
124
|
+
%|clone https://repo.com "#{cache_path}" --bare --no-hardlinks|
|
125
|
+
)
|
126
|
+
subject.install
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
describe '#cached_cookbook' do
|
132
|
+
it 'returns nil if the cookbook is not installed' do
|
133
|
+
subject.stub(:installed?).and_return(false)
|
134
|
+
expect(subject.cached_cookbook).to be_nil
|
135
|
+
end
|
136
|
+
|
137
|
+
it 'returns the cookbook at the install_path' do
|
138
|
+
subject.stub(:installed?).and_return(true)
|
139
|
+
CachedCookbook.stub(:from_path)
|
140
|
+
|
141
|
+
expect(CachedCookbook).to receive(:from_path).once
|
142
|
+
subject.cached_cookbook
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
describe '#==' do
|
147
|
+
let(:other) { subject.dup }
|
148
|
+
|
149
|
+
it 'returns true when everything matches' do
|
150
|
+
expect(subject).to eq(other)
|
151
|
+
end
|
152
|
+
|
153
|
+
it 'returns false when the other location is not an GitLocation' do
|
154
|
+
other.stub(:is_a?).and_return(false)
|
155
|
+
expect(subject).to_not eq(other)
|
156
|
+
end
|
157
|
+
|
158
|
+
it 'returns false when the uri is different' do
|
159
|
+
other.stub(:uri).and_return('different')
|
160
|
+
expect(subject).to_not eq(other)
|
161
|
+
end
|
162
|
+
|
163
|
+
it 'returns false when the branch is different' do
|
164
|
+
other.stub(:branch).and_return('different')
|
165
|
+
expect(subject).to_not eq(other)
|
166
|
+
end
|
167
|
+
|
168
|
+
it 'returns false when the tag is different' do
|
169
|
+
other.stub(:tag).and_return('different')
|
170
|
+
expect(subject).to_not eq(other)
|
171
|
+
end
|
172
|
+
|
173
|
+
it 'returns false when the ref is different' do
|
174
|
+
other.stub(:ref).and_return('different')
|
175
|
+
expect(subject).to_not eq(other)
|
176
|
+
end
|
177
|
+
|
178
|
+
it 'returns false when the rel is different' do
|
179
|
+
other.stub(:rel).and_return('different')
|
180
|
+
expect(subject).to_not eq(other)
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
describe '#to_s' do
|
185
|
+
it 'prefers the tag' do
|
186
|
+
expect(subject.to_s).to eq('https://repo.com (at v1.2.3/hi)')
|
187
|
+
end
|
188
|
+
|
189
|
+
it 'prefers the branch' do
|
190
|
+
subject.stub(:tag).and_return(nil)
|
191
|
+
expect(subject.to_s).to eq('https://repo.com (at ham/hi)')
|
192
|
+
end
|
193
|
+
|
194
|
+
it 'falls back to the ref' do
|
195
|
+
subject.stub(:tag).and_return(nil)
|
196
|
+
subject.stub(:branch).and_return(nil)
|
197
|
+
expect(subject.to_s).to eq('https://repo.com (at abc123/hi)')
|
198
|
+
end
|
199
|
+
|
200
|
+
it 'does not use the rel if missing' do
|
201
|
+
subject.stub(:rel).and_return(nil)
|
202
|
+
expect(subject.to_s).to eq('https://repo.com (at v1.2.3)')
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
describe '#to_lock' do
|
207
|
+
it 'includes all the information' do
|
208
|
+
expect(subject.to_lock).to eq <<-EOH.gsub(/^ {8}/, '')
|
209
|
+
git: https://repo.com
|
210
|
+
revision: defjkl123456
|
211
|
+
ref: abc123
|
212
|
+
branch: ham
|
213
|
+
tag: v1.2.3
|
214
|
+
rel: hi
|
215
|
+
EOH
|
216
|
+
end
|
217
|
+
|
218
|
+
it 'does not include the branch if missing' do
|
219
|
+
subject.stub(:branch).and_return(nil)
|
220
|
+
expect(subject.to_lock).to_not include('branch')
|
221
|
+
end
|
222
|
+
|
223
|
+
it 'does not include the tag if missing' do
|
224
|
+
subject.stub(:tag).and_return(nil)
|
225
|
+
expect(subject.to_lock).to_not include('tag')
|
226
|
+
end
|
227
|
+
|
228
|
+
it 'does not include the rel if missing' do
|
229
|
+
subject.stub(:rel).and_return(nil)
|
230
|
+
expect(subject.to_lock).to_not include('rel')
|
231
|
+
end
|
232
|
+
end
|
233
|
+
|
234
|
+
describe '#git' do
|
235
|
+
before { described_class.send(:public, :git) }
|
236
|
+
|
237
|
+
it 'raises an error if Git is not installed' do
|
238
|
+
Berkshelf.stub(:which).and_return(false)
|
239
|
+
expect { subject.git('foo') }.to raise_error(GitLocation::GitNotInstalled)
|
240
|
+
end
|
241
|
+
|
242
|
+
it 'raises an error if the command fails' do
|
243
|
+
shell_out = double('shell_out', success?: false, stderr: nil)
|
244
|
+
Buff::ShellOut.stub(:shell_out).and_return(shell_out)
|
245
|
+
expect { subject.git('foo') }.to raise_error(GitLocation::GitCommandError)
|
246
|
+
end
|
247
|
+
end
|
248
|
+
end
|
249
|
+
end
|