librarian-chef 0.0.1 → 0.0.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 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