zip-container 4.0.2 → 5.0.0.rc2

Sign up to get free protection for your applications and to get access to all the features.
@@ -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