and_feathers-zip 1.0.0.pre

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: 224035664c022a59680fc4a7fc812ea1909deb09
4
+ data.tar.gz: 3c54fab55be5e069537898545fad61efa4f7c1ef
5
+ SHA512:
6
+ metadata.gz: 622bdce1ae22b2a45f08b32b98c97b77d269b1cf660c01cd3666c6980ede1aa147d5a162fe42c326a3a2e80a45a258bd43c3293d36a3800ea472af6a4fa41afc
7
+ data.tar.gz: 72f89c310ef0416be931488c8116c27ef645a3e4038912d4857f8203c41e81e3158767424fb6536a8ab2e1dacca8741e7771903535c4ab9050dacf84d658804f
data/.gitignore ADDED
@@ -0,0 +1,18 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ .ruby-version
data/.rspec ADDED
@@ -0,0 +1,5 @@
1
+ -I spec
2
+ -I lib
3
+ --color
4
+ -r byebug
5
+ -r support/cleanliness
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'byebug'
4
+
5
+ # Specify your gem's dependencies in and_feathers-zip.gemspec
6
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Brian Cobb
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,51 @@
1
+ # AndFeathers::Zip
2
+
3
+ Works with [and-feathers](http://github.com/bcobb/and_feathers) to turn in-memory archives into zip files.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'and_feathers-zip'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install and_feathers-zip
18
+
19
+ ## Usage
20
+
21
+ ### Writing a ZIP to disk
22
+
23
+ ```ruby
24
+ require 'and_feathers'
25
+ require 'and_feathers/zip'
26
+
27
+ # This is a simple archive
28
+ archive = AndFeathers.build('archive') do |root|
29
+ root.file('README')
30
+ end
31
+
32
+ File.open('archive.zip', 'w+') do |f|
33
+ f << archive.to_io(AndFeathers::Zip).read
34
+ end
35
+ ```
36
+
37
+ ### Zip an existing directory, plus a few changes/additions
38
+
39
+ ```ruby
40
+ require 'and_feathers'
41
+ require 'and_feathers/zip'
42
+
43
+ archive = AndFeathers.from_path('spec') do |spec|
44
+ spec.file('end_to_end_spec.rb') { '# whoops' }
45
+ spec.file('spec_helper.rb') { '# everyone needs one of these' }
46
+ end
47
+
48
+ File.open('spec.zip', 'w+') do |f|
49
+ f << archive.to_io(AndFeathers::Zip).read
50
+ end
51
+ ```
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,25 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'and_feathers/zip/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "and_feathers-zip"
8
+ spec.version = AndFeathers::Zip::VERSION
9
+ spec.authors = ["Brian Cobb"]
10
+ spec.email = ["bcobb@uwalumni.com"]
11
+ spec.description = %q{Turn AndFeathers archives into zip archives}
12
+ spec.summary = %q{Zip AndFeathers archives}
13
+ spec.homepage = "http://github.com/bcobb/and_feathers-zip"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.test_files = spec.files.grep(%r{^spec/})
18
+ spec.require_paths = ["lib"]
19
+
20
+ spec.add_development_dependency "bundler", "~> 1.3"
21
+ spec.add_development_dependency "rake"
22
+ spec.add_development_dependency "rspec"
23
+ spec.add_development_dependency "and_feathers", ">= 1.0.0.pre", "< 2"
24
+ spec.add_runtime_dependency "rubyzip"
25
+ end
@@ -0,0 +1,56 @@
1
+ require 'zip'
2
+
3
+ module AndFeathers
4
+ #
5
+ # Conforms to the interface expected by +Archive#to_io+ in the service of
6
+ # turning +Archive+s into .zip files
7
+ #
8
+ class Zip
9
+ #
10
+ # Yields a +Zip+ ready for adding files and directories.
11
+ #
12
+ # @yieldparam zip [AndFeathers::Zip]
13
+ #
14
+ # @return [StringIO]
15
+ #
16
+ def self.open(&block)
17
+ io = StringIO.new('')
18
+
19
+ ::Zip::OutputStream.write_buffer(io) do |zip|
20
+ block.call(new(zip))
21
+ end.tap(&:rewind)
22
+ end
23
+
24
+ #
25
+ # Creates a new +Zip+. Provides the interface require by
26
+ # +AndFeathers::Zip#to_io+
27
+ #
28
+ # @param zip [Zip::File]
29
+ #
30
+ def initialize(zip)
31
+ @zip = zip
32
+ end
33
+
34
+ #
35
+ # Adds the given file to the zip
36
+ #
37
+ # @param file [AndFeathers::File]
38
+ #
39
+ def add_file(file)
40
+ @zip.put_next_entry(file.path)
41
+ @zip.write(file.read)
42
+ end
43
+
44
+ #
45
+ # Adds the given directory to the zip
46
+ #
47
+ # @note Directories are added to the zip with a trailing slash. Otherwise,
48
+ # they would manifest as empty files.
49
+ #
50
+ # @param directory [AndFeathers::Directory]
51
+ #
52
+ def add_directory(directory)
53
+ @zip.put_next_entry(::File.join(directory.path, ''))
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,11 @@
1
+ module AndFeathers
2
+ class Zip
3
+ #
4
+ # and_feathers-zip is versioned independently of and_feathers. The only
5
+ # breaking change in and_feathers that would affect and_feathers-zip at
6
+ # this point is a change to the protocol expected of the argument passed to
7
+ # +AndFeathers::Archive#to_io+
8
+ #
9
+ VERSION = "1.0.0.pre"
10
+ end
11
+ end
@@ -0,0 +1,129 @@
1
+ require 'and_feathers'
2
+ require 'and_feathers/zip'
3
+ require 'support/in_memory_zip'
4
+
5
+ describe AndFeathers::Zip do
6
+ describe 'an archive with a base directory' do
7
+ let(:archive) do
8
+ AndFeathers.build('redis') do |redis|
9
+ redis.dir('cookbooks') do |cookbooks|
10
+ cookbooks.dir('redis') do |redis|
11
+ redis.file('README') { 'README contents' }
12
+ redis.file('CHANGELOG') { 'CHANGELOG contents' }
13
+ redis.file('metadata.rb') { 'metadata.rb contents' }
14
+ redis.dir('recipes') do |recipes|
15
+ recipes.file('default.rb') { 'default.rb contents' }
16
+ end
17
+ redis.dir('templates') do |templates|
18
+ templates.dir('default')
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
24
+
25
+ let(:tree) do
26
+ [
27
+ './redis/',
28
+ './redis/cookbooks/',
29
+ './redis/cookbooks/redis/',
30
+ './redis/cookbooks/redis/README',
31
+ './redis/cookbooks/redis/CHANGELOG',
32
+ './redis/cookbooks/redis/metadata.rb',
33
+ './redis/cookbooks/redis/recipes/',
34
+ './redis/cookbooks/redis/recipes/default.rb',
35
+ './redis/cookbooks/redis/templates/',
36
+ './redis/cookbooks/redis/templates/default/'
37
+ ]
38
+ end
39
+
40
+ it 'can build an in-memory zip IO stream' do
41
+ zip = archive.to_io(AndFeathers::Zip)
42
+ reader = InMemoryZip.new(zip)
43
+
44
+ expect(reader.to_a.map(&:first)).to eql(tree)
45
+ end
46
+
47
+ it 'produces an in-memory IO stream that can be saved to disk' do
48
+ file = ::File.join("spec", "tmp", "#{Time.now.to_f}.zip")
49
+ zip = archive.to_io(AndFeathers::Zip)
50
+
51
+ ::File.open(file, 'w+') { |f| f << zip.read }
52
+
53
+ zipped_files = []
54
+
55
+ ::Zip::File.open(file) do |files|
56
+ files.each do |file|
57
+ zipped_files << file.name
58
+ end
59
+ end
60
+
61
+ expect(zipped_files).to eql(tree)
62
+ end
63
+ end
64
+
65
+ describe 'an archive without a base directory' do
66
+ let(:archive) do
67
+ AndFeathers.build do |redis|
68
+ redis.dir('cookbooks') do |cookbooks|
69
+ cookbooks.dir('redis') do |redis|
70
+ redis.file('README') { 'README contents' }
71
+ redis.file('CHANGELOG') { 'CHANGELOG contents' }
72
+ redis.file('metadata.rb') { 'metadata.rb contents' }
73
+ redis.dir('recipes') do |recipes|
74
+ recipes.file('default.rb') { 'default.rb contents' }
75
+ end
76
+ redis.dir('templates') do |templates|
77
+ templates.dir('default')
78
+ end
79
+ end
80
+ end
81
+ end
82
+ end
83
+
84
+ let(:tree) do
85
+ [
86
+ './',
87
+ './cookbooks/',
88
+ './cookbooks/redis/',
89
+ './cookbooks/redis/README',
90
+ './cookbooks/redis/CHANGELOG',
91
+ './cookbooks/redis/metadata.rb',
92
+ './cookbooks/redis/recipes/',
93
+ './cookbooks/redis/recipes/default.rb',
94
+ './cookbooks/redis/templates/',
95
+ './cookbooks/redis/templates/default/'
96
+ ]
97
+ end
98
+
99
+ it 'can build an in-memory zip IO stream' do
100
+ zip = archive.to_io(AndFeathers::Zip)
101
+ reader = InMemoryZip.new(zip)
102
+
103
+ expect(reader.to_a.map(&:first)).to eql(tree)
104
+ expect(reader.to_a.map(&:last).reject(&:empty?)).to eq([
105
+ 'README contents',
106
+ 'CHANGELOG contents',
107
+ 'metadata.rb contents',
108
+ 'default.rb contents'
109
+ ])
110
+ end
111
+
112
+ it 'produces an in-memory IO stream that can be saved to disk' do
113
+ file = ::File.join("spec", "tmp", "#{Time.now.to_f}.zip")
114
+ zip = archive.to_io(AndFeathers::Zip)
115
+
116
+ ::File.open(file, 'w+') { |f| f << zip.read }
117
+
118
+ zipped_files = []
119
+
120
+ ::Zip::File.open(file) do |files|
121
+ files.each do |file|
122
+ zipped_files << file.name
123
+ end
124
+ end
125
+
126
+ expect(zipped_files).to eql(tree)
127
+ end
128
+ end
129
+ end
@@ -0,0 +1,7 @@
1
+ RSpec.configure do |config|
2
+ config.after(:suite) do
3
+ Dir['spec/tmp/*.{zip,tgz}'].each do |archive|
4
+ File.unlink(archive)
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,29 @@
1
+ require 'zip'
2
+
3
+ class InMemoryZip
4
+ include Enumerable
5
+
6
+ NotUnzipped = Object.new
7
+
8
+ def initialize(io)
9
+ @io = io
10
+ @unzipped = NotUnzipped
11
+ @entries = []
12
+ end
13
+
14
+ def each
15
+ if NotUnzipped == @unzipped
16
+ ::Zip::InputStream.open(@io) do |zip|
17
+ while entry = zip.get_next_entry
18
+ @entries.push([entry, zip.read])
19
+ end
20
+ end
21
+
22
+ @unzipped = true
23
+ end
24
+
25
+ @entries.each do |entry, content|
26
+ yield entry.name, content
27
+ end
28
+ end
29
+ end
metadata ADDED
@@ -0,0 +1,136 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: and_feathers-zip
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0.pre
5
+ platform: ruby
6
+ authors:
7
+ - Brian Cobb
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-03-26 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '1.3'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '1.3'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: and_feathers
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - '>='
60
+ - !ruby/object:Gem::Version
61
+ version: 1.0.0.pre
62
+ - - <
63
+ - !ruby/object:Gem::Version
64
+ version: '2'
65
+ type: :development
66
+ prerelease: false
67
+ version_requirements: !ruby/object:Gem::Requirement
68
+ requirements:
69
+ - - '>='
70
+ - !ruby/object:Gem::Version
71
+ version: 1.0.0.pre
72
+ - - <
73
+ - !ruby/object:Gem::Version
74
+ version: '2'
75
+ - !ruby/object:Gem::Dependency
76
+ name: rubyzip
77
+ requirement: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - '>='
80
+ - !ruby/object:Gem::Version
81
+ version: '0'
82
+ type: :runtime
83
+ prerelease: false
84
+ version_requirements: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - '>='
87
+ - !ruby/object:Gem::Version
88
+ version: '0'
89
+ description: Turn AndFeathers archives into zip archives
90
+ email:
91
+ - bcobb@uwalumni.com
92
+ executables: []
93
+ extensions: []
94
+ extra_rdoc_files: []
95
+ files:
96
+ - .gitignore
97
+ - .rspec
98
+ - Gemfile
99
+ - LICENSE.txt
100
+ - README.md
101
+ - Rakefile
102
+ - and_feathers-zip.gemspec
103
+ - lib/and_feathers/zip.rb
104
+ - lib/and_feathers/zip/version.rb
105
+ - spec/end_to_end_spec.rb
106
+ - spec/support/cleanliness.rb
107
+ - spec/support/in_memory_zip.rb
108
+ homepage: http://github.com/bcobb/and_feathers-zip
109
+ licenses:
110
+ - MIT
111
+ metadata: {}
112
+ post_install_message:
113
+ rdoc_options: []
114
+ require_paths:
115
+ - lib
116
+ required_ruby_version: !ruby/object:Gem::Requirement
117
+ requirements:
118
+ - - '>='
119
+ - !ruby/object:Gem::Version
120
+ version: '0'
121
+ required_rubygems_version: !ruby/object:Gem::Requirement
122
+ requirements:
123
+ - - '>'
124
+ - !ruby/object:Gem::Version
125
+ version: 1.3.1
126
+ requirements: []
127
+ rubyforge_project:
128
+ rubygems_version: 2.0.3
129
+ signing_key:
130
+ specification_version: 4
131
+ summary: Zip AndFeathers archives
132
+ test_files:
133
+ - spec/end_to_end_spec.rb
134
+ - spec/support/cleanliness.rb
135
+ - spec/support/in_memory_zip.rb
136
+ has_rdoc: