librarian-chef 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 950187ce3da19669233c3f801545c4ed7f090bd7
4
+ data.tar.gz: d342abdad8f21e4deaec5c85207bb4462de51366
5
+ SHA512:
6
+ metadata.gz: 82af4d4079d644156065ed2747fb23686fda4678f15711e355abd3558389737d5a56618fee67018c16de67762cfe0191336f2a13ddb68f1585d95b0544bd4344
7
+ data.tar.gz: 990d08487fcd2a6d1afa919f951917041022acd284feaf17ddee534520304acdb717d97c85250a48a790c58df0378a76dcd7b57dc0f80dc7ee1d3fda3c6e019c
data/.travis.yml CHANGED
@@ -12,8 +12,6 @@ rvm:
12
12
  - ruby-head
13
13
  matrix:
14
14
  allow_failures:
15
- - rvm: rbx-18mode
16
- - rvm: rbx-19mode
17
15
  - rvm: jruby-18mode
18
16
  - rvm: jruby-19mode
19
17
  - rvm: ruby-head
data/CHANGELOG.md CHANGED
@@ -1,5 +1,9 @@
1
1
  # Change Log
2
2
 
3
+ ## 0.0.2
4
+
5
+ * Support tar cookbook archives in addition to targz cookbook archives.
6
+
3
7
  ## 0.0.1
4
8
 
5
9
  * Extract the chef adapter to its own gem.
data/README.md CHANGED
@@ -35,7 +35,7 @@ to manage them.
35
35
 
36
36
  ### The Cheffile
37
37
 
38
- Every infrastruture repository that uses Librarian-Chef will have a file named
38
+ Every infrastructure repository that uses Librarian-Chef will have a file named
39
39
  `Cheffile` in the root directory of that repository. The full specification for
40
40
  which third-party, publicly-released cookbooks your infrastructure repository
41
41
  depends will go here.
@@ -140,7 +140,7 @@ Prepare your infrastructure repository:
140
140
  Librarian-Chef takes over your `cookbooks/` directory, and will always reinstall
141
141
  the cookbooks listed the `Cheffile.lock` into your `cookbooks/` directory. Hence
142
142
  you do not need your `cookbooks/` directory to be tracked in Git. If you
143
- nevertheless want your `cookbooks/` directory to be tracked in Git, simple don't
143
+ nevertheless want your `cookbooks/` directory to be tracked in Git, simply don't
144
144
  `.gitignore` the directory.
145
145
 
146
146
  If you are manually tracking/vendoring outside cookbooks within the repository,
@@ -250,6 +250,46 @@ module Librarian
250
250
  path.open("wb"){|f| f.write(bytes)}
251
251
  end
252
252
 
253
+ def path_detect_gzip?(path)
254
+ Zlib::GzipReader.open(path) { true }
255
+ rescue Zlib::GzipFile::Error
256
+ false
257
+ end
258
+
259
+ def path_detect_tar?(path)
260
+ path_read_bytes_at(path, 257, 8) == "ustar\x0000"
261
+ end
262
+
263
+ def path_read_bytes_at(path, pos, len)
264
+ path = Pathname(path)
265
+ path.stat.size >= pos + len or return
266
+ path.open "rb" do |f|
267
+ f.seek pos ; f.pos == pos or return
268
+ f.read(len)
269
+ end
270
+ end
271
+
272
+ def extract_archive!(source, destination)
273
+ source = Pathname(source)
274
+ destination = Pathname(destination)
275
+
276
+ return extract_archive_targz! source, destination if path_detect_gzip?(source)
277
+ return extract_archive_tar! source, destination if path_detect_tar?(source)
278
+ raise "Unrecognized archive format!"
279
+ end
280
+
281
+ def extract_archive_targz!(source, destination)
282
+ Zlib::GzipReader.open(source) do |input|
283
+ Archive::Tar::Minitar.unpack(input, destination.to_s)
284
+ end
285
+ end
286
+
287
+ def extract_archive_tar!(source, destination)
288
+ source.open "rb" do |input|
289
+ Archive::Tar::Minitar.unpack(input, destination.to_s)
290
+ end
291
+ end
292
+
253
293
  def unpack_package!(path, source)
254
294
  path = Pathname(path)
255
295
  source = Pathname(source)
@@ -258,9 +298,7 @@ module Librarian
258
298
  temp.mkpath
259
299
 
260
300
  debug { "Unpacking #{relative_path_to(source)} to #{relative_path_to(temp)}" }
261
- Zlib::GzipReader.open(source) do |input|
262
- Archive::Tar::Minitar.unpack(input, temp.to_s)
263
- end
301
+ extract_archive! source, temp
264
302
 
265
303
  # Cookbook files, as pulled from Opscode Community Site API, are
266
304
  # embedded in a subdirectory of the tarball. If created by git archive they
@@ -1,5 +1,5 @@
1
1
  module Librarian
2
2
  module Chef
3
- VERSION = "0.0.1"
3
+ VERSION = "0.0.2"
4
4
  end
5
5
  end
@@ -8,9 +8,10 @@ Gem::Specification.new do |gem|
8
8
  gem.version = Librarian::Chef::VERSION
9
9
  gem.authors = ["Jay Feldblum"]
10
10
  gem.email = ["y_feldblum@yahoo.com"]
11
- gem.description = %q{Librarian::Chef}
12
- gem.summary = %q{Librarian::Chef}
11
+ gem.summary = %q{A Bundler for your Chef Cookbooks.}
12
+ gem.description = %q{A Bundler for your Chef Cookbooks.}
13
13
  gem.homepage = ""
14
+ gem.license = "MIT"
14
15
 
15
16
  gem.files = `git ls-files`.split($/)
16
17
  gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
@@ -7,6 +7,8 @@ require 'librarian/helpers'
7
7
  require 'librarian/chef'
8
8
  require 'librarian/linter/source_linter'
9
9
 
10
+ require 'support/project_path'
11
+
10
12
  module Librarian
11
13
  module Chef
12
14
  module Source
@@ -14,67 +16,16 @@ module Librarian
14
16
 
15
17
  include WebMock::API
16
18
 
17
- let(:project_path) do
18
- project_path = Pathname.new(__FILE__).expand_path
19
- project_path = project_path.dirname until project_path.join("Rakefile").exist?
20
- project_path
21
- end
19
+ let(:project_path) { ::Support::ProjectPath.project_path }
22
20
  let(:tmp_path) { project_path.join("tmp/spec/functional/chef/source/site") }
23
21
  after { tmp_path.rmtree if tmp_path && tmp_path.exist? }
24
- let(:sample_path) { tmp_path.join("sample") }
25
- let(:sample_metadata) do
26
- Helpers.strip_heredoc(<<-METADATA)
27
- version "0.6.5"
28
- METADATA
29
- end
30
22
 
31
23
  let(:api_url) { "http://site.cookbooks.com" }
32
24
 
33
- let(:sample_index_data) do
34
- {
35
- "name" => "sample",
36
- "versions" => [
37
- "#{api_url}/cookbooks/sample/versions/0_6_5"
38
- ]
39
- }
40
- end
41
- let(:sample_0_6_5_data) do
42
- {
43
- "version" => "0.6.5",
44
- "file" => "#{api_url}/cookbooks/sample/versions/0_6_5/file.tar.gz"
45
- }
46
- end
47
- let(:sample_0_6_5_package) do
48
- s = StringIO.new
49
- z = Zlib::GzipWriter.new(s, Zlib::NO_COMPRESSION)
50
- t = Archive::Tar::Minitar::Output.new(z)
51
- t.tar.add_file_simple("sample/metadata.rb", :mode => 0700,
52
- :size => sample_metadata.bytesize){|io| io.write(sample_metadata)}
53
- t.close
54
- z.close unless z.closed?
55
- s.string
56
- end
57
-
58
- # depends on repo_path being defined in each context
59
- let(:env) { Environment.new(:project_path => repo_path) }
60
-
61
- before do
62
- stub_request(:get, "#{api_url}/cookbooks/sample").
63
- to_return(:body => JSON.dump(sample_index_data))
64
-
65
- stub_request(:get, "#{api_url}/cookbooks/sample/versions/0_6_5").
66
- to_return(:body => JSON.dump(sample_0_6_5_data))
67
-
68
- stub_request(:get, "#{api_url}/cookbooks/sample/versions/0_6_5/file.tar.gz").
69
- to_return(:body => sample_0_6_5_package)
70
- end
71
-
72
- after do
73
- WebMock.reset!
74
- end
25
+ let(:repo_path) { tmp_path.join("repo") }
26
+ let(:env) { repo_path.mkpath ; Environment.new(:project_path => repo_path) }
75
27
 
76
- let(:repo_path) { tmp_path.join("methods") }
77
- before { repo_path.mkpath }
28
+ after { WebMock.reset! }
78
29
 
79
30
  describe "lint" do
80
31
  it "lints" do
@@ -119,6 +70,49 @@ module Librarian
119
70
  end
120
71
 
121
72
  describe "instance methods" do
73
+
74
+ let(:sample_metadata) do
75
+ Helpers.strip_heredoc(<<-METADATA)
76
+ version "0.6.5"
77
+ METADATA
78
+ end
79
+
80
+ let(:sample_index_data) do
81
+ {
82
+ "name" => "sample",
83
+ "versions" => [
84
+ "#{api_url}/cookbooks/sample/versions/0_6_5"
85
+ ]
86
+ }
87
+ end
88
+ let(:sample_0_6_5_data) do
89
+ {
90
+ "version" => "0.6.5",
91
+ "file" => "#{api_url}/cookbooks/sample/versions/0_6_5/file.tar.gz"
92
+ }
93
+ end
94
+ let(:sample_0_6_5_package) do
95
+ s = StringIO.new
96
+ z = Zlib::GzipWriter.new(s, Zlib::NO_COMPRESSION)
97
+ t = Archive::Tar::Minitar::Output.new(z)
98
+ t.tar.add_file_simple("sample/metadata.rb", :mode => 0700,
99
+ :size => sample_metadata.bytesize){|io| io.write(sample_metadata)}
100
+ t.close
101
+ z.close unless z.closed?
102
+ s.string
103
+ end
104
+
105
+ before do
106
+ stub_request(:get, "#{api_url}/cookbooks/sample").
107
+ to_return(:body => JSON.dump(sample_index_data))
108
+
109
+ stub_request(:get, "#{api_url}/cookbooks/sample/versions/0_6_5").
110
+ to_return(:body => JSON.dump(sample_0_6_5_data))
111
+
112
+ stub_request(:get, "#{api_url}/cookbooks/sample/versions/0_6_5/file.tar.gz").
113
+ to_return(:body => sample_0_6_5_package)
114
+ end
115
+
122
116
  let(:source) { described_class.new(env, api_url) }
123
117
 
124
118
  describe "#manifests" do
@@ -203,6 +197,37 @@ module Librarian
203
197
  describe "following http redirects" do
204
198
  let(:source) { described_class.new(env, api_url) }
205
199
 
200
+ let(:sample_metadata) do
201
+ Helpers.strip_heredoc(<<-METADATA)
202
+ version "0.6.5"
203
+ METADATA
204
+ end
205
+
206
+ let(:sample_index_data) do
207
+ {
208
+ "name" => "sample",
209
+ "versions" => [
210
+ "#{api_url}/cookbooks/sample/versions/0_6_5"
211
+ ]
212
+ }
213
+ end
214
+ let(:sample_0_6_5_data) do
215
+ {
216
+ "version" => "0.6.5",
217
+ "file" => "#{api_url}/cookbooks/sample/versions/0_6_5/file.tar.gz"
218
+ }
219
+ end
220
+ let(:sample_0_6_5_package) do
221
+ s = StringIO.new
222
+ z = Zlib::GzipWriter.new(s, Zlib::NO_COMPRESSION)
223
+ t = Archive::Tar::Minitar::Output.new(z)
224
+ t.tar.add_file_simple("sample/metadata.rb", :mode => 0700,
225
+ :size => sample_metadata.bytesize){|io| io.write(sample_metadata)}
226
+ t.close
227
+ z.close unless z.closed?
228
+ s.string
229
+ end
230
+
206
231
  def redirect_to(url)
207
232
  {:status => 302, :headers => {"Location" => url}}
208
233
  end
@@ -215,6 +240,12 @@ module Librarian
215
240
  to_return redirect_to "#{api_url}/cookbooks/sample-2"
216
241
  stub_request(:get, "#{api_url}/cookbooks/sample-2").
217
242
  to_return(:body => JSON.dump(sample_index_data))
243
+
244
+ stub_request(:get, "#{api_url}/cookbooks/sample/versions/0_6_5").
245
+ to_return(:body => JSON.dump(sample_0_6_5_data))
246
+
247
+ stub_request(:get, "#{api_url}/cookbooks/sample/versions/0_6_5/file.tar.gz").
248
+ to_return(:body => sample_0_6_5_package)
218
249
  end
219
250
 
220
251
  it "follows a sequence of redirects" do
@@ -260,6 +291,59 @@ module Librarian
260
291
  end
261
292
  end
262
293
 
294
+ describe "extracting .tar packages" do
295
+ let(:source) { described_class.new(env, api_url) }
296
+
297
+ let(:sample_metadata) do
298
+ Helpers.strip_heredoc(<<-METADATA)
299
+ version "0.6.5"
300
+ METADATA
301
+ end
302
+
303
+ let(:sample_index_data) do
304
+ {
305
+ "name" => "sample",
306
+ "versions" => [
307
+ "#{api_url}/cookbooks/sample/versions/0_6_5"
308
+ ]
309
+ }
310
+ end
311
+ let(:sample_0_6_5_data) do
312
+ {
313
+ "version" => "0.6.5",
314
+ "file" => "#{api_url}/cookbooks/sample/versions/0_6_5/file.tar"
315
+ }
316
+ end
317
+ let(:sample_0_6_5_package) do
318
+ s = StringIO.new
319
+ t = Archive::Tar::Minitar::Output.new(s)
320
+ t.tar.add_file_simple("sample/metadata.rb", :mode => 0700,
321
+ :size => sample_metadata.bytesize){|io| io.write(sample_metadata)}
322
+ t.close
323
+ s.string
324
+ end
325
+
326
+ before do
327
+ stub_request(:get, "#{api_url}/cookbooks/sample").
328
+ to_return(:body => JSON.dump(sample_index_data))
329
+
330
+ stub_request(:get, "#{api_url}/cookbooks/sample/versions/0_6_5").
331
+ to_return(:body => JSON.dump(sample_0_6_5_data))
332
+
333
+ stub_request(:get, "#{api_url}/cookbooks/sample/versions/0_6_5/file.tar").
334
+ to_return(:body => sample_0_6_5_package)
335
+ end
336
+
337
+ it "installs the manifest" do
338
+ env.install_path.mkpath
339
+ manifest = source.manifests("sample").first
340
+ source.install!(manifest)
341
+ text = env.install_path.join("sample/metadata.rb").read
342
+ text.should == sample_metadata
343
+ end
344
+
345
+ end
346
+
263
347
  end
264
348
  end
265
349
  end
@@ -9,16 +9,14 @@ require 'librarian/action/install'
9
9
  require 'librarian/action/update'
10
10
  require 'librarian/chef'
11
11
 
12
+ require 'support/project_path'
13
+
12
14
  module Librarian
13
15
  module Chef
14
16
  module Source
15
17
  describe Git do
16
18
 
17
- let(:project_path) do
18
- project_path = Pathname.new(__FILE__).expand_path
19
- project_path = project_path.dirname until project_path.join("Rakefile").exist?
20
- project_path
21
- end
19
+ let(:project_path) { ::Support::ProjectPath.project_path }
22
20
  let(:tmp_path) { project_path.join("tmp/spec/integration/chef/source/git") }
23
21
  after { tmp_path.rmtree if tmp_path && tmp_path.exist? }
24
22
 
@@ -8,6 +8,8 @@ require 'librarian/action/resolve'
8
8
  require 'librarian/action/install'
9
9
  require 'librarian/chef'
10
10
 
11
+ require 'support/project_path'
12
+
11
13
  module Librarian
12
14
  module Chef
13
15
  module Source
@@ -15,11 +17,7 @@ module Librarian
15
17
 
16
18
  include WebMock::API
17
19
 
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
20
+ let(:project_path) { ::Support::ProjectPath.project_path }
23
21
  let(:tmp_path) { project_path.join("tmp/spec/integration/chef/source/site") }
24
22
  after { tmp_path.rmtree if tmp_path && tmp_path.exist? }
25
23
  let(:sample_path) { tmp_path.join("sample") }
@@ -0,0 +1,27 @@
1
+ module Support
2
+ module ProjectPath
3
+
4
+ project_path = Pathname.new(__FILE__).expand_path
5
+ project_path = project_path.dirname until project_path.join("Rakefile").exist?
6
+ project_path
7
+
8
+ PROJECT_PATH = project_path
9
+
10
+ def project_path
11
+ PROJECT_PATH
12
+ end
13
+
14
+ module ClassMethods
15
+ def project_path
16
+ PROJECT_PATH
17
+ end
18
+ end
19
+
20
+ def self.included(base)
21
+ base.extend ClassMethods
22
+ end
23
+
24
+ extend self
25
+
26
+ end
27
+ end
metadata CHANGED
@@ -1,113 +1,100 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: librarian-chef
3
3
  version: !ruby/object:Gem::Version
4
- prerelease:
5
- version: 0.0.1
4
+ version: 0.0.2
6
5
  platform: ruby
7
6
  authors:
8
7
  - Jay Feldblum
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2013-04-03 00:00:00.000000000 Z
11
+ date: 2013-09-18 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
- type: :runtime
16
- version_requirements: !ruby/object:Gem::Requirement
17
- none: false
18
- requirements:
19
- - - ~>
20
- - !ruby/object:Gem::Version
21
- version: 0.1.0
22
14
  name: librarian
23
- prerelease: false
24
15
  requirement: !ruby/object:Gem::Requirement
25
- none: false
26
16
  requirements:
27
17
  - - ~>
28
18
  - !ruby/object:Gem::Version
29
19
  version: 0.1.0
30
- - !ruby/object:Gem::Dependency
31
20
  type: :runtime
21
+ prerelease: false
32
22
  version_requirements: !ruby/object:Gem::Requirement
33
- none: false
34
23
  requirements:
35
- - - ! '>='
24
+ - - ~>
36
25
  - !ruby/object:Gem::Version
37
- version: '0.10'
26
+ version: 0.1.0
27
+ - !ruby/object:Gem::Dependency
38
28
  name: chef
39
- prerelease: false
40
29
  requirement: !ruby/object:Gem::Requirement
41
- none: false
42
30
  requirements:
43
- - - ! '>='
31
+ - - '>='
44
32
  - !ruby/object:Gem::Version
45
33
  version: '0.10'
46
- - !ruby/object:Gem::Dependency
47
34
  type: :runtime
35
+ prerelease: false
48
36
  version_requirements: !ruby/object:Gem::Requirement
49
- none: false
50
37
  requirements:
51
- - - ! '>='
38
+ - - '>='
52
39
  - !ruby/object:Gem::Version
53
- version: 0.5.2
40
+ version: '0.10'
41
+ - !ruby/object:Gem::Dependency
54
42
  name: archive-tar-minitar
55
- prerelease: false
56
43
  requirement: !ruby/object:Gem::Requirement
57
- none: false
58
44
  requirements:
59
- - - ! '>='
45
+ - - '>='
60
46
  - !ruby/object:Gem::Version
61
47
  version: 0.5.2
62
- - !ruby/object:Gem::Dependency
63
- type: :development
48
+ type: :runtime
49
+ prerelease: false
64
50
  version_requirements: !ruby/object:Gem::Requirement
65
- none: false
66
51
  requirements:
67
- - - ! '>='
52
+ - - '>='
68
53
  - !ruby/object:Gem::Version
69
- version: '0'
54
+ version: 0.5.2
55
+ - !ruby/object:Gem::Dependency
70
56
  name: rake
71
- prerelease: false
72
57
  requirement: !ruby/object:Gem::Requirement
73
- none: false
74
58
  requirements:
75
- - - ! '>='
59
+ - - '>='
76
60
  - !ruby/object:Gem::Version
77
61
  version: '0'
78
- - !ruby/object:Gem::Dependency
79
62
  type: :development
63
+ prerelease: false
80
64
  version_requirements: !ruby/object:Gem::Requirement
81
- none: false
82
65
  requirements:
83
- - - ! '>='
66
+ - - '>='
84
67
  - !ruby/object:Gem::Version
85
68
  version: '0'
69
+ - !ruby/object:Gem::Dependency
86
70
  name: rspec
87
- prerelease: false
88
71
  requirement: !ruby/object:Gem::Requirement
89
- none: false
90
72
  requirements:
91
- - - ! '>='
73
+ - - '>='
92
74
  - !ruby/object:Gem::Version
93
75
  version: '0'
94
- - !ruby/object:Gem::Dependency
95
76
  type: :development
77
+ prerelease: false
96
78
  version_requirements: !ruby/object:Gem::Requirement
97
- none: false
98
79
  requirements:
99
- - - ! '>='
80
+ - - '>='
100
81
  - !ruby/object:Gem::Version
101
82
  version: '0'
83
+ - !ruby/object:Gem::Dependency
102
84
  name: webmock
103
- prerelease: false
104
85
  requirement: !ruby/object:Gem::Requirement
105
- none: false
106
86
  requirements:
107
- - - ! '>='
87
+ - - '>='
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - '>='
108
95
  - !ruby/object:Gem::Version
109
96
  version: '0'
110
- description: Librarian::Chef
97
+ description: A Bundler for your Chef Cookbooks.
111
98
  email:
112
99
  - y_feldblum@yahoo.com
113
100
  executables:
@@ -145,38 +132,34 @@ files:
145
132
  - spec/functional/chef/source/site_spec.rb
146
133
  - spec/integration/chef/source/git_spec.rb
147
134
  - spec/integration/chef/source/site_spec.rb
135
+ - spec/support/project_path.rb
148
136
  homepage: ''
149
- licenses: []
137
+ licenses:
138
+ - MIT
139
+ metadata: {}
150
140
  post_install_message:
151
141
  rdoc_options: []
152
142
  require_paths:
153
143
  - lib
154
144
  required_ruby_version: !ruby/object:Gem::Requirement
155
- none: false
156
145
  requirements:
157
- - - ! '>='
146
+ - - '>='
158
147
  - !ruby/object:Gem::Version
159
- segments:
160
- - 0
161
- hash: 4422248623382062472
162
148
  version: '0'
163
149
  required_rubygems_version: !ruby/object:Gem::Requirement
164
- none: false
165
150
  requirements:
166
- - - ! '>='
151
+ - - '>='
167
152
  - !ruby/object:Gem::Version
168
- segments:
169
- - 0
170
- hash: 4422248623382062472
171
153
  version: '0'
172
154
  requirements: []
173
155
  rubyforge_project:
174
- rubygems_version: 1.8.25
156
+ rubygems_version: 2.1.3
175
157
  signing_key:
176
- specification_version: 3
177
- summary: Librarian::Chef
158
+ specification_version: 4
159
+ summary: A Bundler for your Chef Cookbooks.
178
160
  test_files:
179
161
  - spec/functional/chef/cli_spec.rb
180
162
  - spec/functional/chef/source/site_spec.rb
181
163
  - spec/integration/chef/source/git_spec.rb
182
164
  - spec/integration/chef/source/site_spec.rb
165
+ - spec/support/project_path.rb