librarian 0.0.25 → 0.0.26
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +4 -0
- data/CHANGELOG.md +21 -0
- data/README.md +6 -1
- data/lib/librarian/action/persist_resolution_mixin.rb +51 -0
- data/lib/librarian/action/resolve.rb +3 -38
- data/lib/librarian/action/update.rb +4 -38
- data/lib/librarian/chef/dsl.rb +1 -0
- data/lib/librarian/chef/source.rb +1 -0
- data/lib/librarian/chef/source/github.rb +27 -0
- data/lib/librarian/chef/source/site.rb +51 -51
- data/lib/librarian/cli.rb +31 -23
- data/lib/librarian/cli/manifest_presenter.rb +36 -22
- data/lib/librarian/dependency.rb +60 -0
- data/lib/librarian/environment.rb +13 -1
- data/lib/librarian/linter/source_linter.rb +55 -0
- data/lib/librarian/lockfile/parser.rb +39 -16
- data/lib/librarian/manifest.rb +8 -0
- data/lib/librarian/manifest_set.rb +5 -7
- data/lib/librarian/mock/source/mock.rb +4 -21
- data/lib/librarian/resolution.rb +1 -1
- data/lib/librarian/resolver.rb +15 -12
- data/lib/librarian/resolver/implementation.rb +166 -75
- data/lib/librarian/source/basic_api.rb +45 -0
- data/lib/librarian/source/git.rb +4 -22
- data/lib/librarian/source/git/repository.rb +1 -1
- data/lib/librarian/source/local.rb +0 -7
- data/lib/librarian/source/path.rb +4 -22
- data/lib/librarian/version.rb +1 -1
- data/librarian.gemspec +3 -3
- data/spec/functional/chef/source/site_spec.rb +150 -100
- data/spec/functional/source/git/repository_spec.rb +2 -1
- data/spec/{functional → integration}/chef/source/git_spec.rb +12 -3
- data/spec/integration/chef/source/site_spec.rb +217 -0
- data/spec/support/cli_macro.rb +4 -12
- data/spec/support/method_patch_macro.rb +30 -0
- data/spec/unit/config/database_spec.rb +8 -0
- data/spec/unit/dependency_spec.rb +176 -0
- data/spec/unit/environment_spec.rb +76 -7
- data/spec/unit/resolver_spec.rb +2 -2
- metadata +52 -46
@@ -105,7 +105,7 @@ module Librarian
|
|
105
105
|
def remote_branch_names
|
106
106
|
remotes = remote_names.sort_by(&:length).reverse
|
107
107
|
|
108
|
-
command = %W(branch -r)
|
108
|
+
command = %W(branch -r --no-color)
|
109
109
|
names = run!(command, :chdir => true).strip.lines.map(&:strip).to_a
|
110
110
|
names.each{|n| n.gsub!(/\s*->.*$/, "")}
|
111
111
|
names.reject!{|n| n =~ /\/HEAD$/}
|
@@ -16,13 +16,6 @@ module Librarian
|
|
16
16
|
[manifest].compact
|
17
17
|
end
|
18
18
|
|
19
|
-
def manifest(name, version, dependencies)
|
20
|
-
manifest = Manifest.new(self, name)
|
21
|
-
manifest.version = version
|
22
|
-
manifest.dependencies = dependencies
|
23
|
-
manifest
|
24
|
-
end
|
25
|
-
|
26
19
|
def manifest_search_paths(name)
|
27
20
|
@manifest_search_paths ||= { }
|
28
21
|
@manifest_search_paths[name] ||= begin
|
@@ -1,32 +1,14 @@
|
|
1
|
+
require 'librarian/source/basic_api'
|
1
2
|
require 'librarian/source/local'
|
2
3
|
|
3
4
|
module Librarian
|
4
5
|
module Source
|
5
6
|
class Path
|
6
|
-
|
7
|
+
include BasicApi
|
7
8
|
include Local
|
8
9
|
|
9
|
-
|
10
|
-
|
11
|
-
LOCK_NAME = 'PATH'
|
12
|
-
|
13
|
-
def lock_name
|
14
|
-
LOCK_NAME
|
15
|
-
end
|
16
|
-
|
17
|
-
def from_lock_options(environment, options)
|
18
|
-
new(environment, options[:remote], options.reject{|k, v| k == :remote})
|
19
|
-
end
|
20
|
-
|
21
|
-
def from_spec_args(environment, path, options)
|
22
|
-
recognized_options = []
|
23
|
-
unrecognized_options = options.keys - recognized_options
|
24
|
-
unrecognized_options.empty? or raise Error, "unrecognized options: #{unrecognized_options.join(", ")}"
|
25
|
-
|
26
|
-
new(environment, path, options)
|
27
|
-
end
|
28
|
-
|
29
|
-
end
|
10
|
+
lock_name 'PATH'
|
11
|
+
spec_options []
|
30
12
|
|
31
13
|
attr_accessor :environment
|
32
14
|
private :environment=
|
data/lib/librarian/version.rb
CHANGED
data/librarian.gemspec
CHANGED
@@ -2,15 +2,15 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = "librarian"
|
5
|
-
s.version = "0.0.
|
5
|
+
s.version = "0.0.26"
|
6
6
|
|
7
7
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
8
8
|
s.authors = ["Jay Feldblum"]
|
9
|
-
s.date = "2012-
|
9
|
+
s.date = "2012-12-30"
|
10
10
|
s.description = "Librarian"
|
11
11
|
s.email = ["y_feldblum@yahoo.com"]
|
12
12
|
s.executables = ["librarian-chef", "librarian-mock"]
|
13
|
-
s.files = [".gitignore", ".rspec", ".travis.yml", "CHANGELOG.md", "Gemfile", "MIT-LICENSE", "README.md", "Rakefile", "bin/librarian-chef", "bin/librarian-mock", "lib/librarian.rb", "lib/librarian/action.rb", "lib/librarian/action/base.rb", "lib/librarian/action/clean.rb", "lib/librarian/action/ensure.rb", "lib/librarian/action/install.rb", "lib/librarian/action/resolve.rb", "lib/librarian/action/update.rb", "lib/librarian/chef.rb", "lib/librarian/chef/cli.rb", "lib/librarian/chef/dsl.rb", "lib/librarian/chef/environment.rb", "lib/librarian/chef/extension.rb", "lib/librarian/chef/integration/knife.rb", "lib/librarian/chef/manifest_reader.rb", "lib/librarian/chef/source.rb", "lib/librarian/chef/source/git.rb", "lib/librarian/chef/source/local.rb", "lib/librarian/chef/source/path.rb", "lib/librarian/chef/source/site.rb", "lib/librarian/chef/templates/Cheffile", "lib/librarian/cli.rb", "lib/librarian/cli/manifest_presenter.rb", "lib/librarian/config.rb", "lib/librarian/config/database.rb", "lib/librarian/config/file_source.rb", "lib/librarian/config/hash_source.rb", "lib/librarian/config/source.rb", "lib/librarian/dependency.rb", "lib/librarian/dsl.rb", "lib/librarian/dsl/receiver.rb", "lib/librarian/dsl/target.rb", "lib/librarian/environment.rb", "lib/librarian/error.rb", "lib/librarian/helpers.rb", "lib/librarian/lockfile.rb", "lib/librarian/lockfile/compiler.rb", "lib/librarian/lockfile/parser.rb", "lib/librarian/logger.rb", "lib/librarian/manifest.rb", "lib/librarian/manifest_set.rb", "lib/librarian/mock.rb", "lib/librarian/mock/cli.rb", "lib/librarian/mock/dsl.rb", "lib/librarian/mock/environment.rb", "lib/librarian/mock/extension.rb", "lib/librarian/mock/source.rb", "lib/librarian/mock/source/mock.rb", "lib/librarian/mock/source/mock/registry.rb", "lib/librarian/resolution.rb", "lib/librarian/resolver.rb", "lib/librarian/resolver/implementation.rb", "lib/librarian/source.rb", "lib/librarian/source/git.rb", "lib/librarian/source/git/repository.rb", "lib/librarian/source/local.rb", "lib/librarian/source/path.rb", "lib/librarian/spec.rb", "lib/librarian/spec_change_set.rb", "lib/librarian/specfile.rb", "lib/librarian/support/abstract_method.rb", "lib/librarian/ui.rb", "lib/librarian/version.rb", "librarian.gemspec", "spec/functional/chef/cli_spec.rb", "spec/functional/chef/source/
|
13
|
+
s.files = [".gitignore", ".rspec", ".travis.yml", "CHANGELOG.md", "Gemfile", "MIT-LICENSE", "README.md", "Rakefile", "bin/librarian-chef", "bin/librarian-mock", "lib/librarian.rb", "lib/librarian/action.rb", "lib/librarian/action/base.rb", "lib/librarian/action/clean.rb", "lib/librarian/action/ensure.rb", "lib/librarian/action/install.rb", "lib/librarian/action/persist_resolution_mixin.rb", "lib/librarian/action/resolve.rb", "lib/librarian/action/update.rb", "lib/librarian/chef.rb", "lib/librarian/chef/cli.rb", "lib/librarian/chef/dsl.rb", "lib/librarian/chef/environment.rb", "lib/librarian/chef/extension.rb", "lib/librarian/chef/integration/knife.rb", "lib/librarian/chef/manifest_reader.rb", "lib/librarian/chef/source.rb", "lib/librarian/chef/source/git.rb", "lib/librarian/chef/source/github.rb", "lib/librarian/chef/source/local.rb", "lib/librarian/chef/source/path.rb", "lib/librarian/chef/source/site.rb", "lib/librarian/chef/templates/Cheffile", "lib/librarian/cli.rb", "lib/librarian/cli/manifest_presenter.rb", "lib/librarian/config.rb", "lib/librarian/config/database.rb", "lib/librarian/config/file_source.rb", "lib/librarian/config/hash_source.rb", "lib/librarian/config/source.rb", "lib/librarian/dependency.rb", "lib/librarian/dsl.rb", "lib/librarian/dsl/receiver.rb", "lib/librarian/dsl/target.rb", "lib/librarian/environment.rb", "lib/librarian/error.rb", "lib/librarian/helpers.rb", "lib/librarian/linter/source_linter.rb", "lib/librarian/lockfile.rb", "lib/librarian/lockfile/compiler.rb", "lib/librarian/lockfile/parser.rb", "lib/librarian/logger.rb", "lib/librarian/manifest.rb", "lib/librarian/manifest_set.rb", "lib/librarian/mock.rb", "lib/librarian/mock/cli.rb", "lib/librarian/mock/dsl.rb", "lib/librarian/mock/environment.rb", "lib/librarian/mock/extension.rb", "lib/librarian/mock/source.rb", "lib/librarian/mock/source/mock.rb", "lib/librarian/mock/source/mock/registry.rb", "lib/librarian/resolution.rb", "lib/librarian/resolver.rb", "lib/librarian/resolver/implementation.rb", "lib/librarian/source.rb", "lib/librarian/source/basic_api.rb", "lib/librarian/source/git.rb", "lib/librarian/source/git/repository.rb", "lib/librarian/source/local.rb", "lib/librarian/source/path.rb", "lib/librarian/spec.rb", "lib/librarian/spec_change_set.rb", "lib/librarian/specfile.rb", "lib/librarian/support/abstract_method.rb", "lib/librarian/ui.rb", "lib/librarian/version.rb", "librarian.gemspec", "spec/functional/chef/cli_spec.rb", "spec/functional/chef/source/site_spec.rb", "spec/functional/source/git/repository_spec.rb", "spec/integration/chef/source/git_spec.rb", "spec/integration/chef/source/site_spec.rb", "spec/support/cli_macro.rb", "spec/support/method_patch_macro.rb", "spec/support/with_env_macro.rb", "spec/unit/action/base_spec.rb", "spec/unit/action/clean_spec.rb", "spec/unit/action/ensure_spec.rb", "spec/unit/action/install_spec.rb", "spec/unit/config/database_spec.rb", "spec/unit/dependency_spec.rb", "spec/unit/dsl_spec.rb", "spec/unit/environment_spec.rb", "spec/unit/lockfile/parser_spec.rb", "spec/unit/lockfile_spec.rb", "spec/unit/manifest_set_spec.rb", "spec/unit/manifest_spec.rb", "spec/unit/mock/source/mock_spec.rb", "spec/unit/resolver_spec.rb", "spec/unit/source/git_spec.rb", "spec/unit/spec_change_set_spec.rb"]
|
14
14
|
s.homepage = ""
|
15
15
|
s.require_paths = ["lib"]
|
16
16
|
s.rubyforge_project = "librarian"
|
@@ -4,9 +4,8 @@ require 'webmock'
|
|
4
4
|
|
5
5
|
require 'librarian'
|
6
6
|
require 'librarian/helpers'
|
7
|
-
require 'librarian/action/resolve'
|
8
|
-
require 'librarian/action/install'
|
9
7
|
require 'librarian/chef'
|
8
|
+
require 'librarian/linter/source_linter'
|
10
9
|
|
11
10
|
module Librarian
|
12
11
|
module Chef
|
@@ -20,7 +19,8 @@ module Librarian
|
|
20
19
|
project_path = project_path.dirname until project_path.join("Rakefile").exist?
|
21
20
|
project_path
|
22
21
|
end
|
23
|
-
let(:tmp_path) { project_path.join("tmp/spec/chef/site
|
22
|
+
let(:tmp_path) { project_path.join("tmp/spec/functional/chef/source/site") }
|
23
|
+
after { tmp_path.rmtree if tmp_path && tmp_path.exist? }
|
24
24
|
let(:sample_path) { tmp_path.join("sample") }
|
25
25
|
let(:sample_metadata) do
|
26
26
|
Helpers.strip_heredoc(<<-METADATA)
|
@@ -73,141 +73,191 @@ module Librarian
|
|
73
73
|
WebMock.reset!
|
74
74
|
end
|
75
75
|
|
76
|
-
|
76
|
+
let(:repo_path) { tmp_path.join("methods") }
|
77
|
+
before { repo_path.mkpath }
|
77
78
|
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
79
|
+
describe "lint" do
|
80
|
+
it "lints" do
|
81
|
+
Librarian::Linter::SourceLinter.lint! described_class
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
describe "class methods" do
|
86
|
+
|
87
|
+
describe ".lock_name" do
|
88
|
+
specify { described_class.lock_name.should == "SITE" }
|
89
|
+
end
|
90
|
+
|
91
|
+
describe ".from_spec_args" do
|
92
|
+
it "gives the expected source" do
|
93
|
+
args = { }
|
94
|
+
source = described_class.from_spec_args(env, api_url, args)
|
95
|
+
source.uri.should == api_url
|
95
96
|
end
|
96
97
|
|
97
|
-
|
98
|
-
|
98
|
+
it "raises on unexpected args" do
|
99
|
+
args = {:k => 3}
|
100
|
+
expect { described_class.from_spec_args(env, api_url, args) }.
|
101
|
+
to raise_error Librarian::Error, "unrecognized options: k"
|
102
|
+
end
|
103
|
+
end
|
99
104
|
|
100
|
-
|
101
|
-
|
102
|
-
|
105
|
+
describe ".from_lock_options" do
|
106
|
+
it "gives the expected source" do
|
107
|
+
options = {:remote => api_url}
|
108
|
+
source = described_class.from_lock_options(env, options)
|
109
|
+
source.uri.should == api_url
|
110
|
+
end
|
103
111
|
|
104
|
-
|
105
|
-
|
106
|
-
|
112
|
+
it "roundtrips" do
|
113
|
+
options = {:remote => api_url}
|
114
|
+
source = described_class.from_lock_options(env, options)
|
115
|
+
source.to_lock_options.should == options
|
107
116
|
end
|
108
117
|
end
|
109
118
|
|
110
|
-
|
111
|
-
let(:repo_path) { tmp_path.join("repo/install") }
|
112
|
-
before do
|
113
|
-
repo_path.rmtree if repo_path.exist?
|
114
|
-
repo_path.mkpath
|
115
|
-
repo_path.join("cookbooks").mkpath
|
116
|
-
cheffile = Helpers.strip_heredoc(<<-CHEFFILE)
|
117
|
-
#!/usr/bin/env ruby
|
118
|
-
cookbook "sample", :site => #{api_url.inspect}
|
119
|
-
CHEFFILE
|
120
|
-
repo_path.join("Cheffile").open("wb") { |f| f.write(cheffile) }
|
119
|
+
end
|
121
120
|
|
122
|
-
|
121
|
+
describe "instance methods" do
|
122
|
+
let(:source) { described_class.new(env, api_url) }
|
123
|
+
|
124
|
+
describe "#manifests" do
|
125
|
+
it "gives a list of all manifests" do
|
126
|
+
manifests = source.manifests("sample")
|
127
|
+
manifests.should have(1).item
|
128
|
+
manifest = manifests.first
|
129
|
+
manifest.source.should be source
|
130
|
+
manifest.version.should == Manifest::Version.new("0.6.5")
|
131
|
+
manifest.dependencies.should be_empty
|
123
132
|
end
|
133
|
+
end
|
124
134
|
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
135
|
+
describe "#fetch_version" do
|
136
|
+
it "fetches the version based on extra" do
|
137
|
+
extra = "#{api_url}/cookbooks/sample/versions/0_6_5"
|
138
|
+
source.fetch_version("sample", extra).should == "0.6.5"
|
129
139
|
end
|
140
|
+
end
|
130
141
|
|
131
|
-
|
132
|
-
|
142
|
+
describe "#fetch_dependencies" do
|
143
|
+
it "fetches the dependencies based on extra" do
|
144
|
+
extra = "#{api_url}/cookbooks/sample/versions/0_6_5"
|
145
|
+
source.fetch_dependencies("sample", "0.6.5", extra).should == [ ]
|
146
|
+
end
|
147
|
+
end
|
133
148
|
|
134
|
-
|
135
|
-
|
136
|
-
|
149
|
+
describe "#pinned?" do
|
150
|
+
it "returns false" do
|
151
|
+
source.should_not be_pinned
|
152
|
+
end
|
153
|
+
end
|
137
154
|
|
138
|
-
|
139
|
-
|
140
|
-
|
155
|
+
describe "#unpin!" do
|
156
|
+
it "is a no-op" do
|
157
|
+
source.unpin!
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
describe "#install!" do
|
162
|
+
before { env.install_path.mkpath }
|
141
163
|
|
142
|
-
|
143
|
-
|
164
|
+
context "directly" do
|
165
|
+
it "installs the manifest" do
|
166
|
+
manifest = Manifest.new(source, "sample")
|
167
|
+
manifest.version = "0.6.5"
|
168
|
+
source.install!(manifest)
|
169
|
+
text = env.install_path.join("sample/metadata.rb").read
|
170
|
+
text.should == sample_metadata
|
144
171
|
end
|
145
172
|
end
|
146
|
-
end
|
147
173
|
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
cheffile = Helpers.strip_heredoc(<<-CHEFFILE)
|
155
|
-
#!/usr/bin/env ruby
|
156
|
-
cookbook "sample", :site => #{api_url.inspect}
|
157
|
-
CHEFFILE
|
158
|
-
repo_path.join("Cheffile").open("wb") { |f| f.write(cheffile) }
|
159
|
-
|
160
|
-
Action::Resolve.new(env).run
|
161
|
-
repo_path.join("tmp").rmtree if repo_path.join("tmp").exist?
|
162
|
-
end
|
163
|
-
|
164
|
-
context "the install" do
|
165
|
-
it "should not raise an exception" do
|
166
|
-
expect { Action::Install.new(env).run }.to_not raise_error
|
174
|
+
context "indirectly" do
|
175
|
+
it "installs the manifest" do
|
176
|
+
manifest = source.manifests("sample").first
|
177
|
+
source.install!(manifest)
|
178
|
+
text = env.install_path.join("sample/metadata.rb").read
|
179
|
+
text.should == sample_metadata
|
167
180
|
end
|
168
181
|
end
|
182
|
+
end
|
169
183
|
|
170
|
-
|
171
|
-
|
184
|
+
describe "#to_spec_args" do
|
185
|
+
it "gives the expected spec args" do
|
186
|
+
source.to_spec_args.should == [api_url, { }]
|
187
|
+
end
|
188
|
+
end
|
172
189
|
|
173
|
-
|
174
|
-
|
175
|
-
|
190
|
+
describe "#to_lock_options" do
|
191
|
+
it "gives the expected lock options" do
|
192
|
+
source.to_lock_options.should == {:remote => api_url}
|
193
|
+
end
|
176
194
|
|
177
|
-
|
178
|
-
|
179
|
-
|
195
|
+
it "roundtrips" do
|
196
|
+
options = source.to_lock_options
|
197
|
+
described_class.from_lock_options(env, options).should == source
|
180
198
|
end
|
181
199
|
end
|
182
200
|
|
183
201
|
end
|
184
202
|
|
185
|
-
|
203
|
+
describe "following http redirects" do
|
204
|
+
let(:source) { described_class.new(env, api_url) }
|
186
205
|
|
187
|
-
|
206
|
+
def redirect_to(url)
|
207
|
+
{:status => 302, :headers => {"Location" => url}}
|
208
|
+
end
|
188
209
|
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
210
|
+
context "with a sequence of http redirects" do
|
211
|
+
before do
|
212
|
+
stub_request(:get, "#{api_url}/cookbooks/sample").
|
213
|
+
to_return redirect_to "#{api_url}/cookbooks/sample-1"
|
214
|
+
stub_request(:get, "#{api_url}/cookbooks/sample-1").
|
215
|
+
to_return redirect_to "#{api_url}/cookbooks/sample-2"
|
216
|
+
stub_request(:get, "#{api_url}/cookbooks/sample-2").
|
217
|
+
to_return(:body => JSON.dump(sample_index_data))
|
218
|
+
end
|
193
219
|
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
repo_path.join("Cheffile").open("wb") { |f| f.write(cheffile) }
|
220
|
+
it "follows a sequence of redirects" do
|
221
|
+
manifest = source.manifests("sample").first
|
222
|
+
manifest.version.to_s.should == "0.6.5"
|
223
|
+
end
|
199
224
|
end
|
200
225
|
|
201
|
-
|
202
|
-
|
203
|
-
|
226
|
+
context "with too many http redirects" do
|
227
|
+
before do
|
228
|
+
stub_request(:get, "#{api_url}/cookbooks/sample").
|
229
|
+
to_return redirect_to "#{api_url}/cookbooks/sample-1"
|
230
|
+
(1 .. 11).each do |i|
|
231
|
+
stub_request(:get, "#{api_url}/cookbooks/sample-#{i}").
|
232
|
+
to_return redirect_to "#{api_url}/cookbooks/sample-#{i + 1}"
|
233
|
+
end
|
234
|
+
stub_request(:get, "#{api_url}/cookbooks/sample-12").
|
235
|
+
to_return(:body => JSON.dump(sample_index_data))
|
236
|
+
end
|
204
237
|
|
205
|
-
|
206
|
-
|
207
|
-
|
238
|
+
it "raises, warning of too many redirects" do
|
239
|
+
expect { source.manifests("sample").first }.
|
240
|
+
to raise_error Librarian::Error, /because too many redirects!/
|
208
241
|
end
|
209
242
|
end
|
210
243
|
|
244
|
+
context "with a redirect cycle" do
|
245
|
+
before do
|
246
|
+
stub_request(:get, "#{api_url}/cookbooks/sample").
|
247
|
+
to_return redirect_to "#{api_url}/cookbooks/sample-1"
|
248
|
+
(1 .. 8).each do |i|
|
249
|
+
stub_request(:get, "#{api_url}/cookbooks/sample-#{i}").
|
250
|
+
to_return redirect_to "#{api_url}/cookbooks/sample-#{i + 1}"
|
251
|
+
end
|
252
|
+
stub_request(:get, "#{api_url}/cookbooks/sample-9").
|
253
|
+
to_return redirect_to "#{api_url}/cookbooks/sample-6"
|
254
|
+
end
|
255
|
+
|
256
|
+
it "raises, warning of a redirect cycle" do
|
257
|
+
expect { source.manifests("sample").first }.
|
258
|
+
to raise_error Librarian::Error, /because redirect cycle!/
|
259
|
+
end
|
260
|
+
end
|
211
261
|
end
|
212
262
|
|
213
263
|
end
|
@@ -15,7 +15,8 @@ describe Librarian::Source::Git::Repository do
|
|
15
15
|
project_path = project_path.dirname until project_path.join("Rakefile").exist?
|
16
16
|
project_path
|
17
17
|
end
|
18
|
-
let(:tmp_path) { project_path + "tmp/spec/
|
18
|
+
let(:tmp_path) { project_path + "tmp/spec/functional/source/git/repository" }
|
19
|
+
after { tmp_path.rmtree if tmp_path && tmp_path.exist? }
|
19
20
|
let(:git_source_path) { tmp_path + SecureRandom.hex(16) }
|
20
21
|
let(:branch) { "the-branch" }
|
21
22
|
let(:tag) { "the-tag" }
|
@@ -19,7 +19,8 @@ module Librarian
|
|
19
19
|
project_path = project_path.dirname until project_path.join("Rakefile").exist?
|
20
20
|
project_path
|
21
21
|
end
|
22
|
-
let(:tmp_path) { project_path.join("tmp/spec/chef/git
|
22
|
+
let(:tmp_path) { project_path.join("tmp/spec/integration/chef/source/git") }
|
23
|
+
after { tmp_path.rmtree if tmp_path && tmp_path.exist? }
|
23
24
|
|
24
25
|
let(:cookbooks_path) { tmp_path.join("cookbooks") }
|
25
26
|
|
@@ -49,7 +50,7 @@ module Librarian
|
|
49
50
|
METADATA
|
50
51
|
end
|
51
52
|
|
52
|
-
before
|
53
|
+
before do
|
53
54
|
sample_path.rmtree if sample_path.exist?
|
54
55
|
sample_path.mkpath
|
55
56
|
sample_path.join("metadata.rb").open("wb") { |f| f.write(sample_metadata) }
|
@@ -217,7 +218,7 @@ module Librarian
|
|
217
218
|
METADATA
|
218
219
|
end
|
219
220
|
|
220
|
-
before
|
221
|
+
before do
|
221
222
|
git_path.rmtree if git_path.exist?
|
222
223
|
git_path.mkpath
|
223
224
|
sample_path.mkpath
|
@@ -304,6 +305,14 @@ module Librarian
|
|
304
305
|
let(:git_path) { tmp_path.join("big-git-repo") }
|
305
306
|
let(:repo_path) { tmp_path.join("repo/resolve") }
|
306
307
|
before do
|
308
|
+
git_path.rmtree if git_path.exist?
|
309
|
+
git_path.mkpath
|
310
|
+
Dir.chdir(git_path) do
|
311
|
+
`git init`
|
312
|
+
`touch not-a-metadata`
|
313
|
+
`git add .`
|
314
|
+
`git commit -m "Initial commit."`
|
315
|
+
end
|
307
316
|
repo_path.rmtree if repo_path.exist?
|
308
317
|
repo_path.mkpath
|
309
318
|
repo_path.join("cookbooks").mkpath
|
@@ -0,0 +1,217 @@
|
|
1
|
+
require 'pathname'
|
2
|
+
require 'json'
|
3
|
+
require 'webmock'
|
4
|
+
|
5
|
+
require 'librarian'
|
6
|
+
require 'librarian/helpers'
|
7
|
+
require 'librarian/action/resolve'
|
8
|
+
require 'librarian/action/install'
|
9
|
+
require 'librarian/chef'
|
10
|
+
|
11
|
+
module Librarian
|
12
|
+
module Chef
|
13
|
+
module Source
|
14
|
+
describe Site do
|
15
|
+
|
16
|
+
include WebMock::API
|
17
|
+
|
18
|
+
let(:project_path) do
|
19
|
+
project_path = Pathname.new(__FILE__).expand_path
|
20
|
+
project_path = project_path.dirname until project_path.join("Rakefile").exist?
|
21
|
+
project_path
|
22
|
+
end
|
23
|
+
let(:tmp_path) { project_path.join("tmp/spec/integration/chef/source/site") }
|
24
|
+
after { tmp_path.rmtree if tmp_path && tmp_path.exist? }
|
25
|
+
let(:sample_path) { tmp_path.join("sample") }
|
26
|
+
let(:sample_metadata) do
|
27
|
+
Helpers.strip_heredoc(<<-METADATA)
|
28
|
+
version "0.6.5"
|
29
|
+
METADATA
|
30
|
+
end
|
31
|
+
|
32
|
+
let(:api_url) { "http://site.cookbooks.com" }
|
33
|
+
|
34
|
+
let(:sample_index_data) do
|
35
|
+
{
|
36
|
+
"name" => "sample",
|
37
|
+
"versions" => [
|
38
|
+
"#{api_url}/cookbooks/sample/versions/0_6_5"
|
39
|
+
]
|
40
|
+
}
|
41
|
+
end
|
42
|
+
let(:sample_0_6_5_data) do
|
43
|
+
{
|
44
|
+
"version" => "0.6.5",
|
45
|
+
"file" => "#{api_url}/cookbooks/sample/versions/0_6_5/file.tar.gz"
|
46
|
+
}
|
47
|
+
end
|
48
|
+
let(:sample_0_6_5_package) do
|
49
|
+
s = StringIO.new
|
50
|
+
z = Zlib::GzipWriter.new(s, Zlib::NO_COMPRESSION)
|
51
|
+
t = Archive::Tar::Minitar::Output.new(z)
|
52
|
+
t.tar.add_file_simple("sample/metadata.rb", :mode => 0700,
|
53
|
+
:size => sample_metadata.bytesize){|io| io.write(sample_metadata)}
|
54
|
+
t.close
|
55
|
+
z.close unless z.closed?
|
56
|
+
s.string
|
57
|
+
end
|
58
|
+
|
59
|
+
# depends on repo_path being defined in each context
|
60
|
+
let(:env) { Environment.new(:project_path => repo_path) }
|
61
|
+
|
62
|
+
before do
|
63
|
+
stub_request(:get, "#{api_url}/cookbooks/sample").
|
64
|
+
to_return(:body => JSON.dump(sample_index_data))
|
65
|
+
|
66
|
+
stub_request(:get, "#{api_url}/cookbooks/sample/versions/0_6_5").
|
67
|
+
to_return(:body => JSON.dump(sample_0_6_5_data))
|
68
|
+
|
69
|
+
stub_request(:get, "#{api_url}/cookbooks/sample/versions/0_6_5/file.tar.gz").
|
70
|
+
to_return(:body => sample_0_6_5_package)
|
71
|
+
end
|
72
|
+
|
73
|
+
after do
|
74
|
+
WebMock.reset!
|
75
|
+
end
|
76
|
+
|
77
|
+
context "a single dependency with a site source" do
|
78
|
+
|
79
|
+
context "resolving" do
|
80
|
+
let(:repo_path) { tmp_path.join("repo/resolve") }
|
81
|
+
before do
|
82
|
+
repo_path.rmtree if repo_path.exist?
|
83
|
+
repo_path.mkpath
|
84
|
+
repo_path.join("cookbooks").mkpath
|
85
|
+
cheffile = Helpers.strip_heredoc(<<-CHEFFILE)
|
86
|
+
#!/usr/bin/env ruby
|
87
|
+
cookbook "sample", :site => #{api_url.inspect}
|
88
|
+
CHEFFILE
|
89
|
+
repo_path.join("Cheffile").open("wb") { |f| f.write(cheffile) }
|
90
|
+
end
|
91
|
+
|
92
|
+
context "the resolve" do
|
93
|
+
it "should not raise an exception" do
|
94
|
+
expect { Action::Resolve.new(env).run }.to_not raise_error
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
context "the results" do
|
99
|
+
before { Action::Resolve.new(env).run }
|
100
|
+
|
101
|
+
it "should create the lockfile" do
|
102
|
+
repo_path.join("Cheffile.lock").should exist
|
103
|
+
end
|
104
|
+
|
105
|
+
it "should not attempt to install the cookbok" do
|
106
|
+
repo_path.join("cookbooks/sample").should_not exist
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
context "intalling" do
|
112
|
+
let(:repo_path) { tmp_path.join("repo/install") }
|
113
|
+
before do
|
114
|
+
repo_path.rmtree if repo_path.exist?
|
115
|
+
repo_path.mkpath
|
116
|
+
repo_path.join("cookbooks").mkpath
|
117
|
+
cheffile = Helpers.strip_heredoc(<<-CHEFFILE)
|
118
|
+
#!/usr/bin/env ruby
|
119
|
+
cookbook "sample", :site => #{api_url.inspect}
|
120
|
+
CHEFFILE
|
121
|
+
repo_path.join("Cheffile").open("wb") { |f| f.write(cheffile) }
|
122
|
+
|
123
|
+
Action::Resolve.new(env).run
|
124
|
+
end
|
125
|
+
|
126
|
+
context "the install" do
|
127
|
+
it "should not raise an exception" do
|
128
|
+
expect { Action::Install.new(env).run }.to_not raise_error
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
context "the results" do
|
133
|
+
before { Action::Install.new(env).run }
|
134
|
+
|
135
|
+
it "should create the lockfile" do
|
136
|
+
repo_path.join("Cheffile.lock").should exist
|
137
|
+
end
|
138
|
+
|
139
|
+
it "should create a directory for the cookbook" do
|
140
|
+
repo_path.join("cookbooks/sample").should exist
|
141
|
+
end
|
142
|
+
|
143
|
+
it "should copy the cookbook files into the cookbook directory" do
|
144
|
+
repo_path.join("cookbooks/sample/metadata.rb").should exist
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
context "resolving and separately installing" do
|
150
|
+
let(:repo_path) { tmp_path.join("repo/resolve-install") }
|
151
|
+
before do
|
152
|
+
repo_path.rmtree if repo_path.exist?
|
153
|
+
repo_path.mkpath
|
154
|
+
repo_path.join("cookbooks").mkpath
|
155
|
+
cheffile = Helpers.strip_heredoc(<<-CHEFFILE)
|
156
|
+
#!/usr/bin/env ruby
|
157
|
+
cookbook "sample", :site => #{api_url.inspect}
|
158
|
+
CHEFFILE
|
159
|
+
repo_path.join("Cheffile").open("wb") { |f| f.write(cheffile) }
|
160
|
+
|
161
|
+
Action::Resolve.new(env).run
|
162
|
+
repo_path.join("tmp").rmtree if repo_path.join("tmp").exist?
|
163
|
+
end
|
164
|
+
|
165
|
+
context "the install" do
|
166
|
+
it "should not raise an exception" do
|
167
|
+
expect { Action::Install.new(env).run }.to_not raise_error
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
context "the results" do
|
172
|
+
before { Action::Install.new(env).run }
|
173
|
+
|
174
|
+
it "should create a directory for the cookbook" do
|
175
|
+
repo_path.join("cookbooks/sample").should exist
|
176
|
+
end
|
177
|
+
|
178
|
+
it "should copy the cookbook files into the cookbook directory" do
|
179
|
+
repo_path.join("cookbooks/sample/metadata.rb").should exist
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
end
|
185
|
+
|
186
|
+
context "when the repo path has a space" do
|
187
|
+
|
188
|
+
let(:repo_path) { tmp_path.join("repo/with extra spaces/resolve") }
|
189
|
+
|
190
|
+
before do
|
191
|
+
repo_path.rmtree if repo_path.exist?
|
192
|
+
repo_path.mkpath
|
193
|
+
repo_path.join("cookbooks").mkpath
|
194
|
+
|
195
|
+
cheffile = Helpers.strip_heredoc(<<-CHEFFILE)
|
196
|
+
#!/usr/bin/env ruby
|
197
|
+
cookbook "sample", :site => #{api_url.inspect}
|
198
|
+
CHEFFILE
|
199
|
+
repo_path.join("Cheffile").open("wb") { |f| f.write(cheffile) }
|
200
|
+
end
|
201
|
+
|
202
|
+
after do
|
203
|
+
repo_path.rmtree
|
204
|
+
end
|
205
|
+
|
206
|
+
context "the resolution" do
|
207
|
+
it "should not raise an exception" do
|
208
|
+
expect { Action::Resolve.new(env).run }.to_not raise_error
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
212
|
+
end
|
213
|
+
|
214
|
+
end
|
215
|
+
end
|
216
|
+
end
|
217
|
+
end
|