zip-container 4.0.2 → 5.0.0.rc2

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.
@@ -1,4 +1,6 @@
1
- # Copyright (c) 2013-2015 The University of Manchester, UK.
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright (c) 2013-2025 The University of Manchester, UK.
2
4
  #
3
5
  # All rights reserved.
4
6
  #
@@ -30,20 +32,20 @@
30
32
  #
31
33
  # Author: Robert Haines
32
34
 
35
+ require 'zip/errors'
36
+
33
37
  ##
34
38
  module ZipContainer
35
-
36
- # The base of all exceptions raised by this library.
39
+ # The base of all errors raised by this library.
37
40
  module Error
38
41
  end
39
42
 
40
43
  # Shadow Zip::Error so the rubyzip API doesn't leak out.
41
44
  ZipError = ::Zip::Error
42
- ZipError.send(:include, Error)
45
+ ZipError.include Error
43
46
 
44
- # This exception is raised when a bad Container is detected.
47
+ # This error is raised when a bad Container is detected.
45
48
  class MalformedContainerError < RuntimeError
46
-
47
49
  include Error
48
50
 
49
51
  # :call-seq:
@@ -65,10 +67,9 @@ module ZipContainer
65
67
  end
66
68
  end
67
69
 
68
- # This exception is raised when a clash occurs with a reserved or managed
70
+ # This error is raised when a clash occurs with a reserved or managed
69
71
  # name.
70
72
  class ReservedNameClashError < RuntimeError
71
-
72
73
  include Error
73
74
 
74
75
  # :call-seq:
@@ -79,5 +80,4 @@ module ZipContainer
79
80
  super("'#{name}' is reserved for internal use in this ZipContainer.")
80
81
  end
81
82
  end
82
-
83
83
  end
@@ -1,4 +1,6 @@
1
- # Copyright (c) 2013, 2014 The University of Manchester, UK.
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright (c) 2013-2025 The University of Manchester, UK.
2
4
  #
3
5
  # All rights reserved.
4
6
  #
@@ -30,10 +32,13 @@
30
32
  #
31
33
  # Author: Robert Haines
32
34
 
35
+ require_relative 'container'
36
+ require_relative 'errors'
37
+
38
+ require 'zip/filesystem'
33
39
  require 'forwardable'
34
40
 
35
41
  module ZipContainer
36
-
37
42
  # This class represents a ZipContainer file in PK Zip format. See the
38
43
  # {OCF}[http://www.idpf.org/epub/30/spec/epub30-ocf.html] and
39
44
  # {UCF}[https://learn.adobe.com/wiki/display/PDFNAV/Universal+Container+Format]
@@ -46,7 +51,6 @@ module ZipContainer
46
51
  #
47
52
  # There are code examples available with the source code of this library.
48
53
  class File < Container
49
-
50
54
  extend Forwardable
51
55
  def_delegators :@container, :comment, :comment=, :commit_required?, :each,
52
56
  :entries, :extract, :get_input_stream, :name, :read, :size
@@ -104,7 +108,7 @@ module ZipContainer
104
108
  def self.each_entry(filename, &block)
105
109
  c = new(filename)
106
110
 
107
- if block_given?
111
+ if block
108
112
  begin
109
113
  c.each(&block)
110
114
  ensure
@@ -138,12 +142,14 @@ module ZipContainer
138
142
  # close -> boolean
139
143
  #
140
144
  # Commits changes that have been made since the previous commit to the
141
- # ZipContainer file. Returns +true+ if anything was actually done, +false+
145
+ # ZipContainer file. Returns +false+ if no commit was required, +true+
142
146
  # otherwise.
143
147
  def commit
144
148
  return false unless commit_required?
145
149
 
146
150
  @container.commit if on_disk?
151
+
152
+ true
147
153
  end
148
154
 
149
155
  alias close commit
@@ -182,9 +188,7 @@ module ZipContainer
182
188
  def find_entry(entry_name, options = {})
183
189
  options = { include_hidden: false }.merge(options)
184
190
 
185
- unless options[:include_hidden]
186
- return if hidden_entry?(entry_name)
187
- end
191
+ return if !options[:include_hidden] && hidden_entry?(entry_name)
188
192
 
189
193
  @container.find_entry(entry_name)
190
194
  end
@@ -199,9 +203,7 @@ module ZipContainer
199
203
  def get_entry(entry, options = {})
200
204
  options = { include_hidden: false }.merge(options)
201
205
 
202
- unless options[:include_hidden]
203
- raise Errno::ENOENT, entry if hidden_entry?(entry)
204
- end
206
+ raise Errno::ENOENT, entry if !options[:include_hidden] && hidden_entry?(entry)
205
207
 
206
208
  @container.get_entry(entry)
207
209
  end
@@ -238,7 +240,7 @@ module ZipContainer
238
240
  # <tt>::File::FNM_PATHNAME | ::File::FNM_DOTMATCH</tt>
239
241
  # * +options+ - <tt>:include_hidden => true</tt> will include hidden
240
242
  # entries in the search.
241
- def glob(pattern, *params)
243
+ def glob(pattern, *params) # rubocop:disable Metrics/CyclomaticComplexity
242
244
  flags = ::File::FNM_PATHNAME | ::File::FNM_DOTMATCH
243
245
  options = { include_hidden: false }
244
246
 
@@ -251,13 +253,13 @@ module ZipContainer
251
253
  end
252
254
  end
253
255
 
254
- entries.map do |entry|
256
+ entries.filter_map do |entry|
255
257
  next if !options[:include_hidden] && hidden_entry?(entry)
256
258
  next unless ::File.fnmatch(pattern, entry.name.chomp('/'), flags)
257
259
 
258
260
  yield(entry) if block_given?
259
261
  entry
260
- end.compact
262
+ end
261
263
  end
262
264
 
263
265
  # :call-seq:
@@ -279,9 +281,7 @@ module ZipContainer
279
281
  # permissions. The default (+0755+) is owner read, write and list; group
280
282
  # read and list; and world read and list.
281
283
  def mkdir(name, permission = 0o0755)
282
- if reserved_entry?(name) || managed_file?(name)
283
- raise ReservedNameClashError, name
284
- end
284
+ raise ReservedNameClashError, name if reserved_entry?(name) || managed_file?(name)
285
285
 
286
286
  @container.mkdir(name, permission)
287
287
  end
@@ -353,13 +353,12 @@ module ZipContainer
353
353
  def verify_mimetype
354
354
  # Check mimetype file is present and correct.
355
355
  entry = @container.find_entry(MIMETYPE_FILE)
356
-
357
356
  return "'mimetype' file is missing." if entry.nil?
357
+
358
358
  if entry.local_header_offset != 0
359
- return "'mimetype' file is not at offset 0 in the archive."
360
- end
361
- if entry.compression_method != ::Zip::Entry::STORED
362
- return "'mimetype' file is compressed."
359
+ "'mimetype' file is not at offset 0 in the archive."
360
+ elsif entry.compression_method != ::Zip::Entry::STORED
361
+ "'mimetype' file is compressed."
363
362
  end
364
363
  end
365
364
 
@@ -1,4 +1,6 @@
1
- # Copyright (c) 2013-2015 The University of Manchester, UK.
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright (c) 2013-2025 The University of Manchester, UK.
2
4
  #
3
5
  # All rights reserved.
4
6
  #
@@ -30,9 +32,12 @@
30
32
  #
31
33
  # Author: Robert Haines
32
34
 
35
+ require_relative 'managed_entries'
36
+ require_relative 'managed_entry'
37
+ require_relative 'reserved_names'
38
+
33
39
  ##
34
40
  module ZipContainer
35
-
36
41
  # A ManagedDirectory acts as the interface to a set of (possibly) managed
37
42
  # files within it and also reserves the directory name in the Container
38
43
  # namespace.
@@ -40,7 +45,6 @@ module ZipContainer
40
45
  # Once a ManagedDirectory is registered in a Container then only it can be
41
46
  # used to write to its contents.
42
47
  class ManagedDirectory < ManagedEntry
43
-
44
48
  include ReservedNames
45
49
  include ManagedEntries
46
50
 
@@ -77,7 +81,7 @@ module ZipContainer
77
81
  def verify
78
82
  messages = super
79
83
 
80
- @files.values.each { |f| messages += f.verify }
84
+ @files.each_value { |f| messages += f.verify }
81
85
 
82
86
  messages
83
87
  end
@@ -1,4 +1,6 @@
1
- # Copyright (c) 2013, 2014 The University of Manchester, UK.
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright (c) 2013-2025 The University of Manchester, UK.
2
4
  #
3
5
  # All rights reserved.
4
6
  #
@@ -30,23 +32,25 @@
30
32
  #
31
33
  # Author: Robert Haines
32
34
 
35
+ require_relative 'errors'
36
+ require_relative 'managed_entry'
37
+ require_relative 'managed_file'
38
+ require_relative 'util'
39
+
33
40
  ##
34
41
  module ZipContainer
35
-
36
42
  # This module provides support for managed file and directory entries.
37
43
  #
38
44
  # <b>Note!</b> If you mix this module in you *must* call
39
45
  # +initialize_managed_entries+ in your constructor to ensure that the
40
46
  # internal lists of managed entries are correctly assigned.
41
47
  module ManagedEntries
42
- include Util
43
-
44
48
  # :call-seq:
45
49
  # managed_directories -> Array
46
50
  #
47
51
  # Return the list of managed directories.
48
52
  def managed_directories
49
- return @managed_directories if @managed_directories
53
+ return @managed_directories if defined?(@managed_directories)
50
54
 
51
55
  dirs = @directories.values
52
56
  @managed_directories = dirs + dirs.map(&:managed_directories).flatten
@@ -89,7 +93,7 @@ module ZipContainer
89
93
  #
90
94
  # Is the supplied entry/name a managed entry?
91
95
  def managed_entry?(entry, list = managed_entry_names)
92
- name = entry_name(entry)
96
+ name = Util.entry_name(entry)
93
97
  list.map(&:downcase).include? name.downcase
94
98
  end
95
99
 
@@ -106,7 +110,7 @@ module ZipContainer
106
110
  #
107
111
  # Is the supplied entry/name a hidden directory?
108
112
  def hidden_directory?(entry)
109
- name = entry_name(entry)
113
+ name = Util.entry_name(entry)
110
114
  managed_directory?(name) ? all_managed_entries[name].hidden? : false
111
115
  end
112
116
 
@@ -115,7 +119,7 @@ module ZipContainer
115
119
  #
116
120
  # Is the supplied entry/name a hidden file?
117
121
  def hidden_file?(entry)
118
- name = entry_name(entry)
122
+ name = Util.entry_name(entry)
119
123
  managed_file?(name) ? all_managed_entries[name].hidden? : false
120
124
  end
121
125
 
@@ -204,25 +208,28 @@ module ZipContainer
204
208
  # the container namespace and act as an interface to the (possibly)
205
209
  # managed files within it.
206
210
  def register_managed_entry(entry)
207
- unless entry.is_a?(ManagedDirectory) || entry.is_a?(ManagedFile)
208
- raise ArgumentError, 'The supplied entry must be of type '\
209
- 'ManagedDirectory or ManagedFile or a subclass of either.'
211
+ unless entry.is_a?(ManagedEntry)
212
+ raise ArgumentError,
213
+ 'The supplied entry must be of type ' \
214
+ 'ManagedDirectory or ManagedFile or a subclass of either.'
210
215
  end
211
216
 
212
217
  entry.parent = self
213
- @directories[entry.name] = entry if entry.is_a? ManagedDirectory
214
- @files[entry.name] = entry if entry.is_a? ManagedFile
218
+ if entry.is_a?(ManagedFile)
219
+ @files[entry.name] = entry
220
+ else
221
+ @directories[entry.name] = entry
222
+ end
215
223
  end
216
224
 
217
- # :stopdoc:
225
+ private
226
+
218
227
  def all_managed_entries
219
- return @entries unless @entries.nil?
228
+ return @entries if defined?(@entries) && !@entries.nil?
220
229
 
221
230
  all = {}
222
231
  managed_entries.each { |e| all[e.full_name] = e }
223
232
  @entries = all
224
233
  end
225
- # :startdoc:
226
-
227
234
  end
228
235
  end
@@ -1,4 +1,6 @@
1
- # Copyright (c) 2013 The University of Manchester, UK.
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright (c) 2013-2025 The University of Manchester, UK.
2
4
  #
3
5
  # All rights reserved.
4
6
  #
@@ -32,13 +34,9 @@
32
34
 
33
35
  ##
34
36
  module ZipContainer
35
-
36
37
  # ManagedEntry is the superclass of ManagedDirectory and ManagedFile. It
37
38
  # should not be used directly but may be subclassed if necessary.
38
39
  class ManagedEntry
39
-
40
- include Util
41
-
42
40
  # The name of the ManagedEntry. For the full path name of this entry use
43
41
  # full_name.
44
42
  attr_reader :name
@@ -1,4 +1,6 @@
1
- # Copyright (c) 2013-2015 The University of Manchester, UK.
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright (c) 2013-2025 The University of Manchester, UK.
2
4
  #
3
5
  # All rights reserved.
4
6
  #
@@ -30,12 +32,12 @@
30
32
  #
31
33
  # Author: Robert Haines
32
34
 
35
+ require_relative 'managed_entry'
36
+
33
37
  ##
34
38
  module ZipContainer
35
-
36
39
  # A ManagedFile is used to reserve a filename in a Container namespace.
37
40
  class ManagedFile < ManagedEntry
38
-
39
41
  # :call-seq:
40
42
  # new(name, required = false, validation_proc = nil) -> ManagedFile
41
43
  #
@@ -1,4 +1,6 @@
1
- # Copyright (c) 2013, 2014 The University of Manchester, UK.
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright (c) 2013-2025 The University of Manchester, UK.
2
4
  #
3
5
  # All rights reserved.
4
6
  #
@@ -30,13 +32,12 @@
30
32
  #
31
33
  # Author: Robert Haines
32
34
 
35
+ require_relative 'util'
36
+
33
37
  ##
34
38
  module ZipContainer
35
-
36
39
  # This module provides support for reserved names.
37
40
  module ReservedNames
38
- include Util
39
-
40
41
  # :call-seq:
41
42
  # reserved_names -> Array
42
43
  #
@@ -69,7 +70,7 @@ module ZipContainer
69
70
  # Is the given entry in the reserved list of names? A String or a
70
71
  # Zip::Entry object can be passed in here.
71
72
  def reserved_entry?(entry)
72
- name = entry_name(entry)
73
+ name = Util.entry_name(entry)
73
74
  reserved_names.map(&:downcase).include? name.downcase
74
75
  end
75
76
 
@@ -1,4 +1,6 @@
1
- # Copyright (c) 2014 The University of Manchester, UK.
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright (c) 2014-2025 The University of Manchester, UK.
2
4
  #
3
5
  # All rights reserved.
4
6
  #
@@ -30,11 +32,14 @@
30
32
  #
31
33
  # Author: Robert Haines
32
34
 
35
+ require 'zip' # Remove this when we update to rubyzip 3.x.
36
+ require 'zip/entry'
37
+
33
38
  ##
34
39
  module ZipContainer
35
-
36
40
  # Utility methods useful throughout the rest of the ZipContainer library.
37
41
  module Util
42
+ module_function
38
43
 
39
44
  # :call-seq:
40
45
  # entry_name(entry) -> String
@@ -48,12 +53,7 @@ module ZipContainer
48
53
  def entry_name(entry)
49
54
  name = entry.is_a?(::Zip::Entry) ? entry.name : entry
50
55
 
51
- if name.respond_to?(:end_with?) && name.respond_to?(:chop!)
52
- name.chop! if name.end_with?('/')
53
- end
54
-
55
- name
56
+ name.respond_to?(:chomp) ? name.chomp('/') : name
56
57
  end
57
-
58
58
  end
59
59
  end
@@ -1,4 +1,6 @@
1
- # Copyright (c) 2014 The University of Manchester, UK.
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright (c) 2014-2025 The University of Manchester, UK.
2
4
  #
3
5
  # All rights reserved.
4
6
  #
@@ -30,18 +32,6 @@
30
32
  #
31
33
  # Author: Robert Haines
32
34
 
33
- require 'yaml'
34
-
35
35
  module ZipContainer
36
-
37
- # Library version information.
38
- module Version
39
- # Version information in a Hash
40
- INFO = YAML.load_file(
41
- File.join(File.dirname(__FILE__), '..', '..', 'version.yml')
42
- )
43
-
44
- # Version number as a String
45
- STRING = %i[major minor patch].map { |d| INFO[d] }.compact.join('.')
46
- end
36
+ VERSION = '5.0.0.rc2' # :nodoc:
47
37
  end
data/lib/zip-container.rb CHANGED
@@ -1,4 +1,6 @@
1
- # Copyright (c) 2013, 2014 The University of Manchester, UK.
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright (c) 2013-2025 The University of Manchester, UK.
2
4
  #
3
5
  # All rights reserved.
4
6
  #
@@ -30,22 +32,9 @@
30
32
  #
31
33
  # Author: Robert Haines
32
34
 
33
- require 'rubygems'
34
- require 'bundler/setup'
35
-
36
- require 'zip/filesystem'
37
-
38
- require 'zip-container/util'
39
- require 'zip-container/version'
40
- require 'zip-container/exceptions'
41
- require 'zip-container/entries/reserved'
42
- require 'zip-container/entries/managed'
43
- require 'zip-container/entries/entry'
44
- require 'zip-container/entries/file'
45
- require 'zip-container/entries/directory'
46
- require 'zip-container/container'
47
- require 'zip-container/file'
48
- require 'zip-container/dir'
35
+ require_relative 'zip-container/file'
36
+ require_relative 'zip-container/dir'
37
+ require_relative 'zip-container/managed_directory'
49
38
 
50
39
  # This is a ruby library to read and write ZIP Container Format files. See the
51
40
  # ZipContainer::Container class for more information.
@@ -1,4 +1,6 @@
1
- # Copyright (c) 2013, 2014, 2018 The University of Manchester, UK.
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright (c) 2013-2025 The University of Manchester, UK.
2
4
  #
3
5
  # All rights reserved.
4
6
  #
@@ -30,22 +32,21 @@
30
32
  #
31
33
  # Author: Robert Haines
32
34
 
33
- lib = File.expand_path('lib', __dir__)
34
- $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
35
- require 'zip-container/version'
35
+ require_relative 'lib/zip-container/version'
36
36
 
37
37
  Gem::Specification.new do |s|
38
38
  s.name = 'zip-container'
39
- s.version = ZipContainer::Version::STRING
39
+ s.version = ZipContainer::VERSION
40
40
  s.authors = ['Robert Haines', 'Finn Bacall']
41
- s.email = ['support@mygrid.org.uk']
41
+ s.email = ['robert.haines@manchester.ac.uk']
42
42
 
43
- s.homepage = 'http://mygrid.github.io/ruby-zip-container/'
43
+ s.homepage = 'https://github.com/hainesr/ruby-zip-container'
44
44
  s.summary = 'A ZIP Container for use by OCF and UCF implementations'
45
- s.description = 'A Ruby library for working with ZIP Container '\
46
- 'Format files. See http://www.idpf.org/epub/30/spec/epub30-ocf.html for '\
47
- 'the OCF specification and '\
48
- 'https://learn.adobe.com/wiki/display/PDFNAV/Universal+Container+Format '\
45
+ s.description =
46
+ 'A Ruby library for working with ZIP Container ' \
47
+ 'Format files. See http://www.idpf.org/epub/30/spec/epub30-ocf.html for ' \
48
+ 'the OCF specification and ' \
49
+ 'https://learn.adobe.com/wiki/display/PDFNAV/Universal+Container+Format ' \
49
50
  'for the UCF specification.'
50
51
  s.license = 'BSD'
51
52
 
@@ -54,14 +55,26 @@ Gem::Specification.new do |s|
54
55
  f.match(%r{^((test|spec|features)/|\.)})
55
56
  end
56
57
 
57
- s.required_ruby_version = '>= 2.2.0'
58
+ s.metadata = {
59
+ 'bug_tracker_uri' => 'https://github.com/hainesr/ruby-zip-container/issues',
60
+ 'changelog_uri' => "https://github.com/hainesr/ruby-zip-container/blob/v#{s.version}/CHANGES.md",
61
+ 'documentation_uri' => 'https://hainesr.github.io/ruby-zip-container',
62
+ 'source_code_uri' => "https://github.com/hainesr/ruby-zip-container/tree/v#{s.version}",
63
+ 'rubygems_mfa_required' => 'true'
64
+ }
65
+
66
+ s.required_ruby_version = '>= 2.7'
58
67
 
59
- s.add_runtime_dependency 'rubyzip', '~> 2.0.0'
68
+ s.add_runtime_dependency 'rubyzip', '~> 2.4'
60
69
 
61
- s.add_development_dependency 'bundler'
62
- s.add_development_dependency 'coveralls', '~> 0.8'
63
- s.add_development_dependency 'rake', '~> 10.1'
64
- s.add_development_dependency 'rdoc', '~> 4.1'
65
- s.add_development_dependency 'rubocop', '~> 0.59'
66
- s.add_development_dependency 'test-unit', '~> 3.0'
70
+ s.add_development_dependency 'minitest', '~> 5.25'
71
+ s.add_development_dependency 'os', '~> 1.1.4'
72
+ s.add_development_dependency 'rake', '~> 13.2'
73
+ s.add_development_dependency 'rdoc', '~> 6.11'
74
+ s.add_development_dependency 'rubocop', '~> 1.50.0'
75
+ s.add_development_dependency 'rubocop-minitest', '~> 0.30.0'
76
+ s.add_development_dependency 'rubocop-performance', '~> 1.17.0'
77
+ s.add_development_dependency 'rubocop-rake', '~> 0.6.0'
78
+ s.add_development_dependency 'simplecov', '0.22.0'
79
+ s.add_development_dependency 'simplecov-lcov', '~> 0.8'
67
80
  end