zip-container 3.0.2 → 4.0.1

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.
Files changed (47) hide show
  1. checksums.yaml +5 -5
  2. data/Gemfile +1 -1
  3. data/Licence.rdoc +1 -1
  4. data/Rakefile +15 -12
  5. data/examples/create-zip-container +7 -8
  6. data/examples/zip-container-info +4 -4
  7. data/lib/zip-container/container.rb +5 -7
  8. data/lib/zip-container/dir.rb +8 -11
  9. data/lib/zip-container/entries/directory.rb +5 -5
  10. data/lib/zip-container/entries/entry.rb +19 -15
  11. data/lib/zip-container/entries/file.rb +10 -9
  12. data/lib/zip-container/entries/managed.rb +11 -11
  13. data/lib/zip-container/entries/reserved.rb +2 -2
  14. data/lib/zip-container/exceptions.rb +4 -2
  15. data/lib/zip-container/file.rb +16 -16
  16. data/lib/zip-container/util.rb +3 -3
  17. data/lib/zip-container/version.rb +4 -3
  18. data/version.yml +2 -2
  19. data/zip-container.gemspec +30 -27
  20. metadata +41 -83
  21. data/.gitignore +0 -9
  22. data/.ruby-env +0 -1
  23. data/.ruby-gemset +0 -1
  24. data/.ruby-version +0 -1
  25. data/.travis.yml +0 -19
  26. data/test/data/compressed_mimetype.container +0 -0
  27. data/test/data/dirs/dir-mimetype/mimetype/.gitkeep +0 -1
  28. data/test/data/dirs/empty/mimetype +0 -1
  29. data/test/data/dirs/managed/dir/.gitkeep +0 -0
  30. data/test/data/dirs/managed/greeting.txt +0 -1
  31. data/test/data/dirs/managed/mimetype +0 -1
  32. data/test/data/dirs/null/.gitkeep +0 -1
  33. data/test/data/empty.container +0 -0
  34. data/test/data/empty.zip +0 -0
  35. data/test/data/example.container +0 -0
  36. data/test/data/null.file +0 -0
  37. data/test/data/subclassed.container +0 -0
  38. data/test/helpers/entry_lists.rb +0 -35
  39. data/test/tc_create_dir.rb +0 -56
  40. data/test/tc_create_file.rb +0 -140
  41. data/test/tc_exceptions.rb +0 -105
  42. data/test/tc_managed_entries.rb +0 -446
  43. data/test/tc_read_dir.rb +0 -90
  44. data/test/tc_read_file.rb +0 -118
  45. data/test/tc_reserved_names.rb +0 -334
  46. data/test/tc_util.rb +0 -67
  47. data/test/ts_container.rb +0 -59
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 4e7102a2cca8e5b0fd4ea9b7ae9a5f11115d918a
4
- data.tar.gz: c1b9b91071dad1589bfb2dafba598e9a1ab11567
2
+ SHA256:
3
+ metadata.gz: 40f261a3985bb13d5eef74340722d167ce5b2addcd0754756ddb00f120bf817e
4
+ data.tar.gz: 027d0a9ec9fe5372be16f3a4e1016625c5bb1e471d3951e7906707eba44c0cbf
5
5
  SHA512:
6
- metadata.gz: db8900129dca6d58d515f68632c19f84fb240041ae31c0e730443ff6d1e6398abeb81aca19abfbf404da6ac3e2905ccef46a72b91e38436b44569df3ebbfc0c0
7
- data.tar.gz: d03bcd00ebc54e52f2aa4646e4e000b9c02d4dd647d37919de624192ee189403969cd108cbebf5035a4694cdeee2b58cff9a0874a488b92305284021a32e29bf
6
+ metadata.gz: 63b164f87290014a514377e2be895ef1c00e8154a668ec977b88a19b1d353046bb39cb6e7d34709107da8a3846e1caf92a787b2ebb8d15c454ddc152c0ad8924
7
+ data.tar.gz: 05450730a60b22f18759a457d942de14c8d8fd571b048e47843beb14a02e075c4db083bd779ee7e6cc4130069ef83f6a54c3ea3d6b09b2172df5f88150ffd2c7
data/Gemfile CHANGED
@@ -30,6 +30,6 @@
30
30
  #
31
31
  # Author: Robert Haines
32
32
 
33
- source "https://rubygems.org"
33
+ source 'https://rubygems.org'
34
34
 
35
35
  gemspec
@@ -1,4 +1,4 @@
1
- Copyright (c) 2013-2015 The University of Manchester, UK.
1
+ Copyright (c) 2013-2018 The University of Manchester, UK.
2
2
 
3
3
  All rights reserved.
4
4
 
data/Rakefile CHANGED
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2013, 2014 The University of Manchester, UK.
1
+ # Copyright (c) 2013-2018 The University of Manchester, UK.
2
2
  #
3
3
  # All rights reserved.
4
4
  #
@@ -30,24 +30,27 @@
30
30
  #
31
31
  # Author: Robert Haines
32
32
 
33
- require "bundler/gem_tasks"
34
- require "rake/testtask"
35
- require "rdoc/task"
33
+ require 'bundler/gem_tasks'
34
+ require 'rake/testtask'
35
+ require 'rdoc/task'
36
+ require 'rubocop/rake_task'
36
37
 
37
- task :default => [:test]
38
+ task default: :test
38
39
 
39
40
  Rake::TestTask.new do |t|
40
- t.libs << "test"
41
+ t.libs << 'test'
41
42
  t.test_files = FileList['test/ts_container.rb']
42
43
  t.verbose = true
43
44
  end
44
45
 
45
46
  RDoc::Task.new do |r|
46
- r.main = "ReadMe.rdoc"
47
- lib = Dir.glob("lib/**/*.rb")
48
- r.rdoc_files.include("ReadMe.rdoc", "Licence.rdoc", "Changes.rdoc", lib)
49
- r.options << "-t ZIP Container Format Ruby Library version " +
47
+ r.main = 'ReadMe.rdoc'
48
+ lib = Dir.glob('lib/**/*.rb')
49
+ r.rdoc_files.include('ReadMe.rdoc', 'Licence.rdoc', 'Changes.rdoc', lib)
50
+ r.options << '-t ZIP Container Format Ruby Library version ' \
50
51
  "#{ZipContainer::Version::STRING}"
51
- r.options << "-N"
52
- r.options << "--tab-width=2"
52
+ r.options << '-N'
53
+ r.options << '--tab-width=2'
53
54
  end
55
+
56
+ RuboCop::RakeTask.new
@@ -43,27 +43,26 @@ usage unless ARGV.length == 1
43
43
 
44
44
  container_file = ARGV[0]
45
45
 
46
- if File.exists?(container_file)
46
+ if File.exist?(container_file)
47
47
  puts "File '#{container_file}' already exists. Exiting."
48
48
  exit 1
49
49
  end
50
50
 
51
51
  begin
52
- ZipContainer::File.create(container_file, "application/epub+zip") do |c|
53
-
52
+ ZipContainer::File.create(container_file, 'application/epub+zip') do |c|
54
53
  # Add a cheery greeting file from a string.
55
- c.file.open("greeting.txt", "w") do |f|
56
- f.puts "Hello, World!"
54
+ c.file.open('greeting.txt', 'w') do |f|
55
+ f.puts 'Hello, World!'
57
56
  end
58
57
 
59
58
  # Create a subdirectory.
60
- c.dir.mkdir("dir")
59
+ c.dir.mkdir('dir')
61
60
 
62
61
  # Copy this example code in straight from a file.
63
- c.add("dir/code.rb", __FILE__)
62
+ c.add('dir/code.rb', __FILE__)
64
63
 
65
64
  # Add a explanation of this file.
66
- c.comment = "This is an example Container file!"
65
+ c.comment = 'This is an example Container file!'
67
66
  end
68
67
  rescue ZipContainer::MalformedContainerError, ZipContainer::ZipError => err
69
68
  puts err.to_s
@@ -50,7 +50,7 @@ rescue ZipContainer::MalformedContainerError, ZipContainer::ZipError => err
50
50
  exit 1
51
51
  end
52
52
 
53
- puts "Archive: #{container.to_s}"
53
+ puts "Archive: #{container}"
54
54
  puts "Container file size: #{File.size(container_file)} bytes, "\
55
55
  "number of entries: #{container.size}"
56
56
 
@@ -60,11 +60,11 @@ total_comp = 0
60
60
  container.each do |entry|
61
61
  total_size += entry.size
62
62
  total_comp += entry.compressed_size
63
- comp = entry.compression_method == 0 ? "stor" : "defN"
63
+ comp = entry.compression_method.zero? ? 'stor' : 'defN'
64
64
  size = entry.size.to_s.rjust(8)
65
65
  puts "#{size} #{comp} #{entry.time} #{entry.name}"
66
66
  end
67
67
 
68
68
  ratio = ((total_size - total_comp) / total_size.to_f) * 100
69
- puts "%d files, %d bytes uncompressed, %d bytes compressed: %.1f%%" %
70
- [container.size, total_size, total_comp, ratio]
69
+ puts "#{container.size} files, #{total_size} bytes uncompressed, "\
70
+ "#{total_comp} bytes compressed: #{ratio.round(1)}%"
@@ -30,13 +30,14 @@
30
30
  #
31
31
  # Author: Robert Haines
32
32
 
33
- #
33
+ ##
34
34
  module ZipContainer
35
35
 
36
36
  # The superclass of anything that represents a Zip Container. That
37
37
  # representation could be as a Zip file (most commonly), as a directory or
38
38
  # something else.
39
39
  class Container
40
+
40
41
  include ReservedNames
41
42
  include ManagedEntries
42
43
 
@@ -47,7 +48,7 @@ module ZipContainer
47
48
 
48
49
  # :stopdoc:
49
50
  # The reserved mimetype file name for standard ZipContainers.
50
- MIMETYPE_FILE = "mimetype"
51
+ MIMETYPE_FILE = 'mimetype'.freeze
51
52
 
52
53
  def initialize(location)
53
54
  @container = open_container(location)
@@ -69,7 +70,7 @@ module ZipContainer
69
70
  #
70
71
  # Open an existing ZipContainer. It will be checked for conformance upon
71
72
  # first access.
72
- def self.open(filename, &block)
73
+ def self.open(filename)
73
74
  c = new(filename)
74
75
 
75
76
  if block_given?
@@ -147,13 +148,10 @@ module ZipContainer
147
148
  # This method raises a MalformedContainerError if there are any problems
148
149
  # with the container.
149
150
  def verify!
150
- unless @mimetype_error.nil?
151
- raise MalformedContainerError.new(@mimetype_error)
152
- end
151
+ raise MalformedContainerError, @mimetype_error unless @mimetype_error.nil?
153
152
 
154
153
  verify_managed_entries!
155
154
  end
156
-
157
155
  end
158
156
 
159
157
  end
@@ -49,7 +49,7 @@ module ZipContainer
49
49
 
50
50
  extend Forwardable
51
51
  def_delegators :@container, :close, :each, :path, :pos, :pos=, :rewind,
52
- :seek, :tell
52
+ :seek, :tell
53
53
 
54
54
  private_class_method :new
55
55
 
@@ -65,7 +65,7 @@ module ZipContainer
65
65
  #
66
66
  # Create a new (or convert an existing) directory as a ZipContainer with
67
67
  # the specified mimetype.
68
- def self.create(pathname, mimetype, &block)
68
+ def self.create(pathname, mimetype)
69
69
  ::Dir.mkdir(pathname) unless ::File.directory?(pathname)
70
70
  ::File.write(::File.join(pathname, MIMETYPE_FILE), mimetype)
71
71
 
@@ -108,7 +108,8 @@ module ZipContainer
108
108
  Entries.new(@container)
109
109
  end
110
110
 
111
- class Entries
111
+ class Entries # :nodoc:
112
+
112
113
  include Enumerable
113
114
 
114
115
  Entry = Struct.new(:name, :ftype)
@@ -122,7 +123,7 @@ module ZipContainer
122
123
  end
123
124
  end
124
125
 
125
- def each(&block)
126
+ def each
126
127
  @entries.each do |entry|
127
128
  yield entry
128
129
  end
@@ -145,12 +146,9 @@ module ZipContainer
145
146
 
146
147
  def verify_mimetype
147
148
  mime_path = full_path(MIMETYPE_FILE)
148
- if ::File.exist?(mime_path)
149
- return "'mimetype' is not a regular file" unless ::File.file?(mime_path)
150
- return "'mimetype' is not readable." unless ::File.readable?(mime_path)
151
- else
152
- return "'mimetype' file is missing."
153
- end
149
+ return "'mimetype' file is missing." unless ::File.exist?(mime_path)
150
+ return "'mimetype' is not a regular file" unless ::File.file?(mime_path)
151
+ return "'mimetype' is not readable." unless ::File.readable?(mime_path)
154
152
  end
155
153
 
156
154
  def read_mimetype
@@ -225,7 +223,6 @@ module ZipContainer
225
223
  #
226
224
  # Equal to
227
225
  # {::Dir.tell}[http://ruby-doc.org/core-1.9.3/Dir.html#method-i-tell]
228
-
229
226
  end
230
227
 
231
228
  end
@@ -30,7 +30,7 @@
30
30
  #
31
31
  # Author: Robert Haines
32
32
 
33
- #
33
+ ##
34
34
  module ZipContainer
35
35
 
36
36
  # A ManagedDirectory acts as the interface to a set of (possibly) managed
@@ -40,6 +40,7 @@ module ZipContainer
40
40
  # Once a ManagedDirectory is registered in a Container then only it can be
41
41
  # used to write to its contents.
42
42
  class ManagedDirectory < ManagedEntry
43
+
43
44
  include ReservedNames
44
45
  include ManagedEntries
45
46
 
@@ -55,9 +56,9 @@ module ZipContainer
55
56
  # that are within this directory (default []).
56
57
  def initialize(name, options = {})
57
58
  options = {
58
- :required => false,
59
- :hidden => false,
60
- :entries => []
59
+ required: false,
60
+ hidden: false,
61
+ entries: []
61
62
  }.merge(options)
62
63
 
63
64
  super(name, options[:required], options[:hidden])
@@ -80,6 +81,5 @@ module ZipContainer
80
81
 
81
82
  messages
82
83
  end
83
-
84
84
  end
85
85
  end
@@ -30,18 +30,23 @@
30
30
  #
31
31
  # Author: Robert Haines
32
32
 
33
- #
33
+ ##
34
34
  module ZipContainer
35
35
 
36
36
  # ManagedEntry is the superclass of ManagedDirectory and ManagedFile. It
37
37
  # should not be used directly but may be subclassed if necessary.
38
38
  class ManagedEntry
39
+
39
40
  include Util
40
41
 
41
42
  # The name of the ManagedEntry. For the full path name of this entry use
42
43
  # full_name.
43
44
  attr_reader :name
44
45
 
46
+ # Allows the object in which this entry has been registered to tell it
47
+ # who it is.
48
+ attr_writer :parent # :nodoc:
49
+
45
50
  # :call-seq:
46
51
  # new(name, required) -> ManagedEntry
47
52
  #
@@ -60,7 +65,11 @@ module ZipContainer
60
65
  #
61
66
  # The fully qualified name of this ManagedEntry.
62
67
  def full_name
63
- @parent.is_a?(ZipContainer::Container) ? @name : "#{@parent.full_name}/#{@name}"
68
+ if @parent.is_a?(ZipContainer::Container)
69
+ @name
70
+ else
71
+ "#{@parent.full_name}/#{@name}"
72
+ end
64
73
  end
65
74
 
66
75
  # :call-seq:
@@ -78,7 +87,11 @@ module ZipContainer
78
87
  # Is this ManagedEntry hidden for normal operations?
79
88
  def hidden?
80
89
  # An entry is hidden if its parent is hidden.
81
- @parent.is_a?(ZipContainer::Container) ? @hidden : @hidden || @parent.hidden?
90
+ if @parent.is_a?(ZipContainer::Container)
91
+ @hidden
92
+ else
93
+ @hidden || @parent.hidden?
94
+ end
82
95
  end
83
96
 
84
97
  # :call-seq:
@@ -87,21 +100,13 @@ module ZipContainer
87
100
  # Does this ManagedEntry exist in the Container?
88
101
  def exists?
89
102
  container.entries.each do |entry|
90
- test = (entry.ftype == :directory) ? "#{full_name}/" : full_name
103
+ test = entry.ftype == :directory ? "#{full_name}/" : full_name
91
104
  return true if entry.name == test
92
105
  end
93
106
 
94
107
  false
95
108
  end
96
109
 
97
- # :stopdoc:
98
- # Allows the object in which this entry has been registered in to tell it
99
- # who it is.
100
- def parent=(parent)
101
- @parent = parent
102
- end
103
- # :startdoc:
104
-
105
110
  # :call-seq:
106
111
  # verify -> Array
107
112
  #
@@ -111,7 +116,7 @@ module ZipContainer
111
116
  # Subclasses should override this method if they require more complex
112
117
  # verification to be done.
113
118
  def verify
114
- unless !@required || exists?
119
+ if @required && !exists?
115
120
  ["Entry '#{full_name}' is required but missing."]
116
121
  else
117
122
  []
@@ -135,7 +140,7 @@ module ZipContainer
135
140
  # fails.
136
141
  def verify!
137
142
  messages = verify
138
- raise MalformedContainerError.new(messages) unless messages.empty?
143
+ raise MalformedContainerError, messages unless messages.empty?
139
144
  end
140
145
 
141
146
  protected
@@ -147,6 +152,5 @@ module ZipContainer
147
152
  def container
148
153
  @parent.is_a?(ZipContainer::Container) ? @parent : @parent.container
149
154
  end
150
-
151
155
  end
152
156
  end
@@ -30,7 +30,7 @@
30
30
  #
31
31
  # Author: Robert Haines
32
32
 
33
- #
33
+ ##
34
34
  module ZipContainer
35
35
 
36
36
  # A ManagedFile is used to reserve a filename in a Container namespace.
@@ -57,13 +57,13 @@ module ZipContainer
57
57
  # word "Boo!".
58
58
  #
59
59
  # valid = Proc.new { |contents| contents == "Boo!" }
60
- # ManagedFile.new("Surprize.txt", :required => false,
61
- # :validation_proc => valid)
60
+ # ManagedFile.new("Surprize.txt", required: false,
61
+ # validation_proc: valid)
62
62
  def initialize(name, options = {})
63
63
  options = {
64
- :required => false,
65
- :hidden => false,
66
- :validation_proc => nil
64
+ required: false,
65
+ hidden: false,
66
+ validation_proc: nil
67
67
  }.merge(options)
68
68
 
69
69
  super(name, options[:required], options[:hidden])
@@ -83,8 +83,10 @@ module ZipContainer
83
83
  def verify
84
84
  messages = super
85
85
 
86
- unless (exists? ? validate : true)
87
- messages << "The contents of file '#{full_name}' do not pass validation."
86
+ valid = exists? ? validate : true
87
+ unless valid
88
+ messages <<
89
+ "The contents of file '#{full_name}' do not pass validation."
88
90
  end
89
91
 
90
92
  messages
@@ -110,6 +112,5 @@ module ZipContainer
110
112
  def contents
111
113
  container.read(full_name)
112
114
  end
113
-
114
115
  end
115
116
  end
@@ -30,7 +30,7 @@
30
30
  #
31
31
  # Author: Robert Haines
32
32
 
33
- #
33
+ ##
34
34
  module ZipContainer
35
35
 
36
36
  # This module provides support for managed file and directory entries.
@@ -49,8 +49,7 @@ module ZipContainer
49
49
  return @managed_directories if @managed_directories
50
50
 
51
51
  dirs = @directories.values
52
- @managed_directories = dirs +
53
- dirs.map { |d| d.managed_directories }.flatten
52
+ @managed_directories = dirs + dirs.map(&:managed_directories).flatten
54
53
  end
55
54
 
56
55
  # :call-seq:
@@ -58,7 +57,7 @@ module ZipContainer
58
57
  #
59
58
  # Return the list of managed directory names.
60
59
  def managed_directory_names
61
- @managed_directory_names ||= managed_directories.map { |d| d.full_name }
60
+ @managed_directory_names ||= managed_directories.map(&:full_name)
62
61
  end
63
62
 
64
63
  # :call-seq:
@@ -91,7 +90,7 @@ module ZipContainer
91
90
  # Is the supplied entry/name a managed entry?
92
91
  def managed_entry?(entry, list = managed_entry_names)
93
92
  name = entry_name(entry)
94
- list.map { |n| n.downcase }.include? name.downcase
93
+ list.map(&:downcase).include? name.downcase
95
94
  end
96
95
 
97
96
  # :call-seq:
@@ -133,8 +132,9 @@ module ZipContainer
133
132
  #
134
133
  # Return the list of managed files.
135
134
  def managed_files
136
- @managed_files ||= @files.values +
137
- @directories.values.map { |d| d.managed_files }.flatten
135
+ @managed_files ||=
136
+ @files.values +
137
+ @directories.values.map(&:managed_files).flatten
138
138
  end
139
139
 
140
140
  # :call-seq:
@@ -142,7 +142,7 @@ module ZipContainer
142
142
  #
143
143
  # Return the list of managed file names.
144
144
  def managed_file_names
145
- @managed_file_names ||= managed_files.map { |f| f.full_name }
145
+ @managed_file_names ||= managed_files.map(&:full_name)
146
146
  end
147
147
 
148
148
  # :call-seq:
@@ -171,7 +171,7 @@ module ZipContainer
171
171
  # exist and validate, if required.
172
172
  def verify_managed_entries!
173
173
  messages = verify_managed_entries
174
- raise MalformedContainerError.new(messages) unless messages.empty?
174
+ raise MalformedContainerError, messages unless messages.empty?
175
175
  end
176
176
 
177
177
  protected
@@ -205,8 +205,8 @@ module ZipContainer
205
205
  # managed files within it.
206
206
  def register_managed_entry(entry)
207
207
  unless entry.is_a?(ManagedDirectory) || entry.is_a?(ManagedFile)
208
- raise ArgumentError.new("The supplied entry must be of type "\
209
- "ManagedDirectory or ManagedFile or a subclass of either.")
208
+ raise ArgumentError, 'The supplied entry must be of type '\
209
+ 'ManagedDirectory or ManagedFile or a subclass of either.'
210
210
  end
211
211
 
212
212
  entry.parent = self