librarianp 0.1.2
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 +7 -0
- data/.gitignore +5 -0
- data/.rspec +1 -0
- data/.travis.yml +10 -0
- data/CHANGELOG.md +255 -0
- data/Gemfile +8 -0
- data/Gemfile.lock +235 -0
- data/LICENSE.txt +22 -0
- data/README.md +55 -0
- data/Rakefile +28 -0
- data/VERSION +1 -0
- data/lib/librarian/action/base.rb +24 -0
- data/lib/librarian/action/clean.rb +44 -0
- data/lib/librarian/action/ensure.rb +24 -0
- data/lib/librarian/action/install.rb +95 -0
- data/lib/librarian/action/persist_resolution_mixin.rb +51 -0
- data/lib/librarian/action/resolve.rb +46 -0
- data/lib/librarian/action/update.rb +44 -0
- data/lib/librarian/action.rb +5 -0
- data/lib/librarian/algorithms.rb +133 -0
- data/lib/librarian/cli/manifest_presenter.rb +89 -0
- data/lib/librarian/cli.rb +225 -0
- data/lib/librarian/config/database.rb +205 -0
- data/lib/librarian/config/file_source.rb +47 -0
- data/lib/librarian/config/hash_source.rb +33 -0
- data/lib/librarian/config/source.rb +149 -0
- data/lib/librarian/config.rb +7 -0
- data/lib/librarian/dependency.rb +153 -0
- data/lib/librarian/dsl/receiver.rb +42 -0
- data/lib/librarian/dsl/target.rb +171 -0
- data/lib/librarian/dsl.rb +102 -0
- data/lib/librarian/environment/runtime_cache.rb +101 -0
- data/lib/librarian/environment.rb +230 -0
- data/lib/librarian/error.rb +4 -0
- data/lib/librarian/helpers.rb +29 -0
- data/lib/librarian/linter/source_linter.rb +55 -0
- data/lib/librarian/lockfile/compiler.rb +66 -0
- data/lib/librarian/lockfile/parser.rb +123 -0
- data/lib/librarian/lockfile.rb +29 -0
- data/lib/librarian/logger.rb +46 -0
- data/lib/librarian/manifest.rb +146 -0
- data/lib/librarian/manifest_set.rb +150 -0
- data/lib/librarian/mock/cli.rb +19 -0
- data/lib/librarian/mock/dsl.rb +15 -0
- data/lib/librarian/mock/environment.rb +21 -0
- data/lib/librarian/mock/extension.rb +9 -0
- data/lib/librarian/mock/source/mock/registry.rb +83 -0
- data/lib/librarian/mock/source/mock.rb +80 -0
- data/lib/librarian/mock/source.rb +1 -0
- data/lib/librarian/mock/version.rb +5 -0
- data/lib/librarian/mock.rb +1 -0
- data/lib/librarian/posix.rb +129 -0
- data/lib/librarian/resolution.rb +46 -0
- data/lib/librarian/resolver/implementation.rb +238 -0
- data/lib/librarian/resolver.rb +94 -0
- data/lib/librarian/rspec/support/cli_macro.rb +120 -0
- data/lib/librarian/source/basic_api.rb +45 -0
- data/lib/librarian/source/git/repository.rb +193 -0
- data/lib/librarian/source/git.rb +172 -0
- data/lib/librarian/source/local.rb +54 -0
- data/lib/librarian/source/path.rb +56 -0
- data/lib/librarian/source.rb +2 -0
- data/lib/librarian/spec.rb +13 -0
- data/lib/librarian/spec_change_set.rb +173 -0
- data/lib/librarian/specfile.rb +19 -0
- data/lib/librarian/support/abstract_method.rb +21 -0
- data/lib/librarian/ui.rb +64 -0
- data/lib/librarian/version.rb +3 -0
- data/lib/librarian.rb +11 -0
- data/librarian.gemspec +47 -0
- data/spec/functional/cli_spec.rb +27 -0
- data/spec/functional/posix_spec.rb +32 -0
- data/spec/functional/source/git/repository_spec.rb +199 -0
- data/spec/functional/source/git_spec.rb +174 -0
- data/spec/support/fakefs.rb +37 -0
- data/spec/support/method_patch_macro.rb +30 -0
- data/spec/support/project_path_macro.rb +14 -0
- data/spec/support/with_env_macro.rb +22 -0
- data/spec/unit/action/base_spec.rb +18 -0
- data/spec/unit/action/clean_spec.rb +102 -0
- data/spec/unit/action/ensure_spec.rb +37 -0
- data/spec/unit/action/install_spec.rb +111 -0
- data/spec/unit/algorithms_spec.rb +131 -0
- data/spec/unit/config/database_spec.rb +320 -0
- data/spec/unit/dependency/requirement_spec.rb +12 -0
- data/spec/unit/dependency_spec.rb +212 -0
- data/spec/unit/dsl_spec.rb +173 -0
- data/spec/unit/environment/runtime_cache_spec.rb +73 -0
- data/spec/unit/environment_spec.rb +209 -0
- data/spec/unit/lockfile/parser_spec.rb +162 -0
- data/spec/unit/lockfile_spec.rb +65 -0
- data/spec/unit/manifest/version_spec.rb +11 -0
- data/spec/unit/manifest_set_spec.rb +202 -0
- data/spec/unit/manifest_spec.rb +36 -0
- data/spec/unit/mock/environment_spec.rb +25 -0
- data/spec/unit/mock/source/mock_spec.rb +22 -0
- data/spec/unit/resolver_spec.rb +299 -0
- data/spec/unit/source/git_spec.rb +29 -0
- data/spec/unit/spec_change_set_spec.rb +169 -0
- metadata +257 -0
@@ -0,0 +1,202 @@
|
|
1
|
+
require 'librarian'
|
2
|
+
|
3
|
+
module Librarian
|
4
|
+
describe ManifestSet do
|
5
|
+
|
6
|
+
describe ".new" do
|
7
|
+
let(:jelly) { double(:name => "jelly") }
|
8
|
+
let(:butter) { double(:name => "butter") }
|
9
|
+
let(:jam) { double(:name => "jam") }
|
10
|
+
|
11
|
+
let(:array) { [jelly, butter, jam] }
|
12
|
+
let(:hash) { {"jelly" => jelly, "butter" => butter, "jam" => jam} }
|
13
|
+
|
14
|
+
context "with an array" do
|
15
|
+
let(:set) { described_class.new(array) }
|
16
|
+
|
17
|
+
it "should give back the array" do
|
18
|
+
expect(set.to_a).to match_array( array )
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should give back the hash" do
|
22
|
+
expect(set.to_hash).to eq hash
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
context "with a hash" do
|
27
|
+
let(:set) { described_class.new(hash) }
|
28
|
+
|
29
|
+
it "should give back the array" do
|
30
|
+
expect(set.to_a).to match_array( array )
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should give back the hash" do
|
34
|
+
expect(set.to_hash).to eq hash
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
# Does not trace dependencies.
|
40
|
+
# That's why it's "shallow".
|
41
|
+
describe "#shallow_strip!" do
|
42
|
+
let(:jelly) { double(:name => "jelly") }
|
43
|
+
let(:butter) { double(:name => "butter") }
|
44
|
+
let(:jam) { double(:name => "jam") }
|
45
|
+
|
46
|
+
let(:set) { described_class.new([jelly, butter, jam]) }
|
47
|
+
|
48
|
+
it "should not do anything when given no names" do
|
49
|
+
set.shallow_strip!([])
|
50
|
+
|
51
|
+
expect(set.to_a).to match_array( [jelly, butter, jam] )
|
52
|
+
end
|
53
|
+
|
54
|
+
it "should remove only the named elements" do
|
55
|
+
set.shallow_strip!(["butter", "jam"])
|
56
|
+
|
57
|
+
expect(set.to_a).to match_array( [jelly] )
|
58
|
+
end
|
59
|
+
|
60
|
+
it "should allow removing all the elements" do
|
61
|
+
set.shallow_strip!(["jelly", "butter", "jam"])
|
62
|
+
|
63
|
+
expect(set.to_a).to match_array( [] )
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
# Does not trace dependencies.
|
68
|
+
# That's why it's "shallow".
|
69
|
+
describe "#shallow_keep!" do
|
70
|
+
let(:jelly) { double(:name => "jelly") }
|
71
|
+
let(:butter) { double(:name => "butter") }
|
72
|
+
let(:jam) { double(:name => "jam") }
|
73
|
+
|
74
|
+
let(:set) { described_class.new([jelly, butter, jam]) }
|
75
|
+
|
76
|
+
it "should empty the set when given no names" do
|
77
|
+
set.shallow_keep!([])
|
78
|
+
|
79
|
+
expect(set.to_a).to match_array( [] )
|
80
|
+
end
|
81
|
+
|
82
|
+
it "should keep only the named elements" do
|
83
|
+
set.shallow_keep!(["butter", "jam"])
|
84
|
+
|
85
|
+
expect(set.to_a).to match_array( [butter, jam] )
|
86
|
+
end
|
87
|
+
|
88
|
+
it "should allow keeping all the elements" do
|
89
|
+
set.shallow_keep!(["jelly", "butter", "jam"])
|
90
|
+
|
91
|
+
expect(set.to_a).to match_array( [jelly, butter, jam] )
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
describe "#deep_strip!" do
|
96
|
+
def man(o)
|
97
|
+
k, v = o.keys.first, o.values.first
|
98
|
+
double(k, :name => k, :dependencies => deps(v))
|
99
|
+
end
|
100
|
+
|
101
|
+
def deps(names)
|
102
|
+
names.map{|n| double(:name => n)}
|
103
|
+
end
|
104
|
+
|
105
|
+
let(:a) { man("a" => %w[b c]) }
|
106
|
+
let(:b) { man("b" => %w[c d]) }
|
107
|
+
let(:c) { man("c" => %w[ ]) }
|
108
|
+
let(:d) { man("d" => %w[ ]) }
|
109
|
+
|
110
|
+
let(:e) { man("e" => %w[f g]) }
|
111
|
+
let(:f) { man("f" => %w[g h]) }
|
112
|
+
let(:g) { man("g" => %w[ ]) }
|
113
|
+
let(:h) { man("h" => %w[ ]) }
|
114
|
+
|
115
|
+
let(:set) { described_class.new([a, b, c, d, e, f, g, h]) }
|
116
|
+
|
117
|
+
it "should not do anything when given no names" do
|
118
|
+
set.deep_strip!([])
|
119
|
+
|
120
|
+
expect(set.to_a).to match_array( [a, b, c, d, e, f, g, h] )
|
121
|
+
end
|
122
|
+
|
123
|
+
it "should remove just the named elements if they have no dependencies" do
|
124
|
+
set.deep_strip!(["c", "h"])
|
125
|
+
|
126
|
+
expect(set.to_a).to match_array( [a, b, d, e, f, g] )
|
127
|
+
end
|
128
|
+
|
129
|
+
it "should remove the named elements and all their dependencies" do
|
130
|
+
set.deep_strip!(["b"])
|
131
|
+
|
132
|
+
expect(set.to_a).to match_array( [a, e, f, g, h] )
|
133
|
+
end
|
134
|
+
|
135
|
+
it "should remove an entire tree of dependencies" do
|
136
|
+
set.deep_strip!(["e"])
|
137
|
+
|
138
|
+
expect(set.to_a).to match_array( [a, b, c, d] )
|
139
|
+
end
|
140
|
+
|
141
|
+
it "should allow removing all the elements" do
|
142
|
+
set.deep_strip!(["a", "e"])
|
143
|
+
|
144
|
+
expect(set.to_a).to match_array( [] )
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
describe "#deep_keep!" do
|
149
|
+
def man(o)
|
150
|
+
k, v = o.keys.first, o.values.first
|
151
|
+
double(k, :name => k, :dependencies => deps(v))
|
152
|
+
end
|
153
|
+
|
154
|
+
def deps(names)
|
155
|
+
names.map{|n| double(:name => n)}
|
156
|
+
end
|
157
|
+
|
158
|
+
let(:a) { man("a" => %w[b c]) }
|
159
|
+
let(:b) { man("b" => %w[c d]) }
|
160
|
+
let(:c) { man("c" => %w[ ]) }
|
161
|
+
let(:d) { man("d" => %w[ ]) }
|
162
|
+
|
163
|
+
let(:e) { man("e" => %w[f g]) }
|
164
|
+
let(:f) { man("f" => %w[g h]) }
|
165
|
+
let(:g) { man("g" => %w[ ]) }
|
166
|
+
let(:h) { man("h" => %w[ ]) }
|
167
|
+
|
168
|
+
let(:set) { described_class.new([a, b, c, d, e, f, g, h]) }
|
169
|
+
|
170
|
+
it "should remove all the elements when given no names" do
|
171
|
+
set.deep_keep!([])
|
172
|
+
|
173
|
+
expect(set.to_a).to match_array( [] )
|
174
|
+
end
|
175
|
+
|
176
|
+
it "should keep just the named elements if they have no dependencies" do
|
177
|
+
set.deep_keep!(["c", "h"])
|
178
|
+
|
179
|
+
expect(set.to_a).to match_array( [c, h] )
|
180
|
+
end
|
181
|
+
|
182
|
+
it "should keep the named elements and all their dependencies" do
|
183
|
+
set.deep_keep!(["b"])
|
184
|
+
|
185
|
+
expect(set.to_a).to match_array( [b, c, d] )
|
186
|
+
end
|
187
|
+
|
188
|
+
it "should keep an entire tree of dependencies" do
|
189
|
+
set.deep_keep!(["e"])
|
190
|
+
|
191
|
+
expect(set.to_a).to match_array( [e, f, g, h] )
|
192
|
+
end
|
193
|
+
|
194
|
+
it "should allow keeping all the elements" do
|
195
|
+
set.deep_keep!(["a", "e"])
|
196
|
+
|
197
|
+
expect(set.to_a).to match_array( [a, b, c, d, e, f, g, h] )
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
end
|
202
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require "librarian/manifest"
|
2
|
+
|
3
|
+
describe Librarian::Manifest do
|
4
|
+
|
5
|
+
describe "validations" do
|
6
|
+
|
7
|
+
context "when the name is blank" do
|
8
|
+
it "raises" do
|
9
|
+
expect { described_class.new(nil, "") }.
|
10
|
+
to raise_error(ArgumentError, %{name ("") must be sensible})
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
context "when the name has leading whitespace" do
|
15
|
+
it "raises" do
|
16
|
+
expect { described_class.new(nil, " the-name") }.
|
17
|
+
to raise_error(ArgumentError, %{name (" the-name") must be sensible})
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
context "when the name has trailing whitespace" do
|
22
|
+
it "raises" do
|
23
|
+
expect { described_class.new(nil, "the-name ") }.
|
24
|
+
to raise_error(ArgumentError, %{name ("the-name ") must be sensible})
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
context "when the name is a single character" do
|
29
|
+
it "passes" do
|
30
|
+
described_class.new(nil, "R")
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require "librarian/mock/environment"
|
2
|
+
|
3
|
+
module Librarian::Mock
|
4
|
+
describe Environment do
|
5
|
+
|
6
|
+
let(:env) { described_class.new }
|
7
|
+
|
8
|
+
describe "#version" do
|
9
|
+
specify { expect(env.version).to eq Librarian::VERSION }
|
10
|
+
end
|
11
|
+
|
12
|
+
describe "#adapter_module" do
|
13
|
+
specify { expect(env.adapter_module).to eq Librarian::Mock }
|
14
|
+
end
|
15
|
+
|
16
|
+
describe "#adapter_name" do
|
17
|
+
specify { expect(env.adapter_name).to eq "mock" }
|
18
|
+
end
|
19
|
+
|
20
|
+
describe "#adapter_version" do
|
21
|
+
specify { expect(env.adapter_version).to eq Librarian::Mock::VERSION }
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require "librarian/mock"
|
2
|
+
|
3
|
+
module Librarian
|
4
|
+
module Mock
|
5
|
+
module Source
|
6
|
+
describe Mock do
|
7
|
+
|
8
|
+
let(:env) { Librarian::Mock::Environment.new }
|
9
|
+
|
10
|
+
describe ".new" do
|
11
|
+
|
12
|
+
let(:source) { described_class.new(env, "source-a", {}) }
|
13
|
+
subject { source }
|
14
|
+
|
15
|
+
its(:environment) { should_not be_nil }
|
16
|
+
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,299 @@
|
|
1
|
+
require "pathname"
|
2
|
+
require "tmpdir"
|
3
|
+
|
4
|
+
require "support/fakefs"
|
5
|
+
|
6
|
+
require 'librarian/resolver'
|
7
|
+
require 'librarian/spec_change_set'
|
8
|
+
require 'librarian/mock'
|
9
|
+
|
10
|
+
module Librarian
|
11
|
+
describe Resolver do
|
12
|
+
include ::Support::FakeFS
|
13
|
+
|
14
|
+
let(:env) { Mock::Environment.new }
|
15
|
+
let(:resolver) { env.resolver }
|
16
|
+
|
17
|
+
context "a simple specfile" do
|
18
|
+
|
19
|
+
before do
|
20
|
+
env.registry :clear => true do
|
21
|
+
source 'source-1' do
|
22
|
+
spec 'butter', '1.1'
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
let(:spec) do
|
28
|
+
env.dsl do
|
29
|
+
src 'source-1'
|
30
|
+
dep 'butter'
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
let(:resolution) { resolver.resolve(spec) }
|
35
|
+
|
36
|
+
specify { expect(resolution).to be_correct }
|
37
|
+
|
38
|
+
end
|
39
|
+
|
40
|
+
context "a specfile with a dep from one src depending on a dep from another src" do
|
41
|
+
|
42
|
+
before do
|
43
|
+
env.registry :clear => true do
|
44
|
+
source 'source-1' do
|
45
|
+
spec 'butter', '1.1'
|
46
|
+
end
|
47
|
+
source 'source-2' do
|
48
|
+
spec 'jam', '1.2' do
|
49
|
+
dependency 'butter', '>= 1.0'
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
let(:spec) do
|
56
|
+
env.dsl do
|
57
|
+
src 'source-1'
|
58
|
+
src 'source-2' do
|
59
|
+
dep 'jam'
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
let(:resolution) { resolver.resolve(spec) }
|
65
|
+
|
66
|
+
specify { expect(resolution).to be_correct }
|
67
|
+
|
68
|
+
end
|
69
|
+
|
70
|
+
context "a specfile with a dep in multiple sources" do
|
71
|
+
|
72
|
+
before do
|
73
|
+
env.registry :clear => true do
|
74
|
+
source 'source-1' do
|
75
|
+
spec 'butter', '1.0'
|
76
|
+
spec 'butter', '1.1'
|
77
|
+
end
|
78
|
+
source 'source-2' do
|
79
|
+
spec 'butter', '1.0'
|
80
|
+
spec 'butter', '1.1'
|
81
|
+
end
|
82
|
+
source 'source-3' do
|
83
|
+
spec 'butter', '1.0'
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
let(:spec) do
|
89
|
+
env.dsl do
|
90
|
+
src 'source-1'
|
91
|
+
src 'source-2'
|
92
|
+
dep 'butter', '>= 1.1'
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
it "should have the expected number of sources" do
|
97
|
+
expect(spec).to have(2).sources
|
98
|
+
end
|
99
|
+
|
100
|
+
let(:resolution) { resolver.resolve(spec) }
|
101
|
+
|
102
|
+
specify { expect(resolution).to be_correct }
|
103
|
+
|
104
|
+
it "should have the manifest from the final source with a matching manifest" do
|
105
|
+
manifest = resolution.manifests.find{|m| m.name == "butter"}
|
106
|
+
expect(manifest.source.name).to eq "source-2"
|
107
|
+
end
|
108
|
+
|
109
|
+
end
|
110
|
+
|
111
|
+
context "a specfile with a dep depending on a nonexistent dep" do
|
112
|
+
|
113
|
+
before do
|
114
|
+
env.registry :clear => true do
|
115
|
+
source 'source-1' do
|
116
|
+
spec 'jam', '1.2' do
|
117
|
+
dependency 'butter', '>= 1.0'
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
let(:spec) do
|
124
|
+
env.dsl do
|
125
|
+
src 'source-1'
|
126
|
+
dep 'jam'
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
let(:resolution) { resolver.resolve(spec) }
|
131
|
+
|
132
|
+
specify { expect(resolution).to be_nil }
|
133
|
+
|
134
|
+
end
|
135
|
+
|
136
|
+
context "a specfile with conflicting constraints" do
|
137
|
+
|
138
|
+
before do
|
139
|
+
env.registry :clear => true do
|
140
|
+
source 'source-1' do
|
141
|
+
spec 'butter', '1.0'
|
142
|
+
spec 'butter', '1.1'
|
143
|
+
spec 'jam', '1.2' do
|
144
|
+
dependency 'butter', '1.1'
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
let(:spec) do
|
151
|
+
env.dsl do
|
152
|
+
src 'source-1'
|
153
|
+
dep 'butter', '1.0'
|
154
|
+
dep 'jam'
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
let(:resolution) { resolver.resolve(spec) }
|
159
|
+
|
160
|
+
specify { expect(resolution).to be_nil }
|
161
|
+
|
162
|
+
end
|
163
|
+
|
164
|
+
context "a specfile with cyclic constraints" do
|
165
|
+
|
166
|
+
before do
|
167
|
+
env.registry :clear => true do
|
168
|
+
source 'source-1' do
|
169
|
+
spec 'butter', '1.0' do
|
170
|
+
dependency 'jam', '2.0'
|
171
|
+
end
|
172
|
+
spec 'jam', '2.0' do
|
173
|
+
dependency 'butter', '1.0'
|
174
|
+
end
|
175
|
+
end
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
let(:spec) do
|
180
|
+
env.dsl do
|
181
|
+
src 'source-1'
|
182
|
+
dep 'butter'
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
let(:resolution) { resolver.resolve(spec) }
|
187
|
+
|
188
|
+
context "when cyclic resolutions are forbidden" do
|
189
|
+
let(:resolver) { env.resolver(:cyclic => false) }
|
190
|
+
|
191
|
+
specify { expect(resolution).to be_nil }
|
192
|
+
end
|
193
|
+
|
194
|
+
context "when cyclic resolutions are permitted" do
|
195
|
+
let(:resolver) { env.resolver(:cyclic => true) }
|
196
|
+
|
197
|
+
it "should have all the manifests" do
|
198
|
+
manifest_names = resolution.manifests.map(&:name).sort
|
199
|
+
expect(manifest_names).to be == %w[butter jam]
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
203
|
+
end
|
204
|
+
|
205
|
+
context "updating" do
|
206
|
+
|
207
|
+
it "should not work" do
|
208
|
+
env.registry :clear => true do
|
209
|
+
source 'source-1' do
|
210
|
+
spec 'butter', '1.0'
|
211
|
+
spec 'butter', '1.1'
|
212
|
+
spec 'jam', '1.2' do
|
213
|
+
dependency 'butter'
|
214
|
+
end
|
215
|
+
end
|
216
|
+
end
|
217
|
+
first_spec = env.dsl do
|
218
|
+
src 'source-1'
|
219
|
+
dep 'butter', '1.1'
|
220
|
+
dep 'jam'
|
221
|
+
end
|
222
|
+
first_resolution = resolver.resolve(first_spec)
|
223
|
+
expect(first_resolution).to be_correct
|
224
|
+
first_manifests = first_resolution.manifests
|
225
|
+
first_manifests_index = Hash[first_manifests.map{|m| [m.name, m]}]
|
226
|
+
expect(first_manifests_index['butter'].version.to_s).to eq '1.1'
|
227
|
+
|
228
|
+
second_spec = env.dsl do
|
229
|
+
src 'source-1'
|
230
|
+
dep 'butter', '1.0'
|
231
|
+
dep 'jam'
|
232
|
+
end
|
233
|
+
locked_manifests = ManifestSet.deep_strip(first_manifests, ['butter'])
|
234
|
+
second_resolution =resolver.resolve(second_spec, locked_manifests)
|
235
|
+
expect(second_resolution).to be_correct
|
236
|
+
second_manifests = second_resolution.manifests
|
237
|
+
second_manifests_index = Hash[second_manifests.map{|m| [m.name, m]}]
|
238
|
+
expect(second_manifests_index['butter'].version.to_s).to eq '1.0'
|
239
|
+
end
|
240
|
+
|
241
|
+
end
|
242
|
+
|
243
|
+
context "a change to the spec" do
|
244
|
+
|
245
|
+
it "should work" do
|
246
|
+
env.registry :clear => true do
|
247
|
+
source 'source-1' do
|
248
|
+
spec 'butter', '1.0'
|
249
|
+
end
|
250
|
+
source 'source-2' do
|
251
|
+
spec 'butter', '1.0'
|
252
|
+
end
|
253
|
+
end
|
254
|
+
spec = env.dsl do
|
255
|
+
src 'source-1'
|
256
|
+
dep 'butter'
|
257
|
+
end
|
258
|
+
lock = resolver.resolve(spec)
|
259
|
+
expect(lock).to be_correct
|
260
|
+
|
261
|
+
spec = env.dsl do
|
262
|
+
src 'source-1'
|
263
|
+
dep 'butter', :src => 'source-2'
|
264
|
+
end
|
265
|
+
changes = SpecChangeSet.new(env, spec, lock)
|
266
|
+
expect(changes).to_not be_same
|
267
|
+
manifests = ManifestSet.new(changes.analyze).to_hash
|
268
|
+
expect(manifests).to_not have_key('butter')
|
269
|
+
lock = resolver.resolve(spec, changes.analyze)
|
270
|
+
expect(lock).to be_correct
|
271
|
+
expect(lock.manifests.map{|m| m.name}).to include('butter')
|
272
|
+
manifest = lock.manifests.find{|m| m.name == 'butter'}
|
273
|
+
expect(manifest).to_not be_nil
|
274
|
+
expect(manifest.source.name).to eq 'source-2'
|
275
|
+
end
|
276
|
+
|
277
|
+
end
|
278
|
+
|
279
|
+
context "a pathname to a simple specfile" do
|
280
|
+
let(:pwd) { Pathname(Dir.tmpdir) }
|
281
|
+
let(:specfile_path) { pwd + "Mockfile" }
|
282
|
+
before { FileUtils.mkpath(pwd) }
|
283
|
+
|
284
|
+
def write!(path, text)
|
285
|
+
Pathname(path).open("wb"){|f| f.write(text)}
|
286
|
+
end
|
287
|
+
|
288
|
+
it "loads the specfile with the __FILE__" do
|
289
|
+
write! specfile_path, "src __FILE__"
|
290
|
+
spec = env.dsl(specfile_path)
|
291
|
+
expect(spec.sources).to have(1).item
|
292
|
+
source = spec.sources.first
|
293
|
+
expect(source.name).to eq specfile_path.to_s
|
294
|
+
end
|
295
|
+
|
296
|
+
end
|
297
|
+
|
298
|
+
end
|
299
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require "librarian"
|
2
|
+
|
3
|
+
module Librarian
|
4
|
+
module Source
|
5
|
+
describe Git do
|
6
|
+
|
7
|
+
let(:env) { Environment.new }
|
8
|
+
|
9
|
+
describe "validating options for the specfile" do
|
10
|
+
|
11
|
+
context "with only known options" do
|
12
|
+
it "should not raise" do
|
13
|
+
expect { described_class.from_spec_args(env, "some://git/repo.git", :ref => "megapatches") }.
|
14
|
+
to_not raise_error
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
context "with an unknown option" do
|
19
|
+
it "should raise" do
|
20
|
+
expect { described_class.from_spec_args(env, "some://git/repo.git", :branch => "megapatches") }.
|
21
|
+
to raise_error Error, "unrecognized options: branch"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|