zip-container 1.1.0 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- Njc2NTMxMjAwYTcyYjA2NzA0YTEzMTI5MjgxODhlNTg5ODJlNjY4Nw==
4
+ YjRlNjYzODNiZDM4MDBjYjQyZDMyODIzODdmYjlhNzRkYTNmNjA4NQ==
5
5
  data.tar.gz: !binary |-
6
- MWJkMDk3ZTM2NGYwYzVkY2I5NjljYzIxNzU2MzUyNGIxMjk0MzhmYg==
6
+ MGRmMzVkNTI4NjI0NmVhMGNmNDZiMTIwZTNjM2FlM2E3YWIxZmY4OA==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- MDVmN2MxZjZkYzQzNWQ4OWE1NGM1OGQwMDNhZWQ1ZjkyOTAyOGUyYzBkNTYz
10
- OGRhYjA4ZTQwNGQzMzYyOGNkYTNkYWZhYWZlM2U1MzZhMDA1ODVlYTc2MTdl
11
- YmM2MTZiYTNkMjc4NDJmYjM2MTgyMzA5ZDQ3MTQ4ODVjNGIzN2M=
9
+ NTk3MzMyYjM0M2U5NDgwZTYxNjE3ZDQ5YTIxMzA5NDk0YmQxMWVlOGI4ZmI4
10
+ ZmI3MDFkMGNjN2NjNDZlMTA2NDk2YTIwNTU2MjA4OWNkMzBlYjRlODYyYTNk
11
+ YThiMjNmODA4NjU1OGMzMjgxY2U1ZDhkMjkxMTQ4YmU1NDc5YzY=
12
12
  data.tar.gz: !binary |-
13
- ODAwMGIxYjBkZTRkY2FmNTUxNWY2MjA0ZTk5YTFkOTA1OGY4MGYwNzIxM2Zm
14
- OTdmZTI5ZTdhMjE4MDNmZjRmMTQ4NTcxMjBiNWJlMTc3NzIxMmZjZWI4ZTBi
15
- NzJjYTk2MDBhMDA0NjYzNzQwMTczNjQ4YWU5MWQxN2MxN2QxOTI=
13
+ NjI4YmU4MTkwY2QzNjJiYmQ5MGQ3MmJkOTA2YzRlMDc5OWQyMDA0NTBmNDcx
14
+ ZDAwMWVlMzk4ZGVlYWYyZmUyMjc5MmRkN2UzOTAyZGZhZmUxZDIwZmRmM2Ew
15
+ ZmE4Njk3YmQ2ODczMjNmZmE0OTlhNTc5MTZhMTM0YjVhOGExN2U=
data/.travis.yml CHANGED
@@ -3,3 +3,9 @@ rvm:
3
3
  - 1.9.3
4
4
  - 2.0.0
5
5
  - 2.1.2
6
+ - ruby-head
7
+ - rbx-2
8
+ matrix:
9
+ allow_failures:
10
+ - rvm: ruby-head
11
+ - rvm: rbx-2
data/Changes.rdoc CHANGED
@@ -1,5 +1,28 @@
1
1
  = Changes log for the ZIP Container Ruby Gem
2
2
 
3
+ == Version 2.0.0
4
+
5
+ * Change API: Container => File.
6
+ * Refactor exceptions so we can shadow rubyzip exceptions.
7
+ * Use the shadowed ZipError in the tests.
8
+ * Use the shadowed ZipError in the example scripts.
9
+ * Update the exceptions to use Zip::Error.
10
+ * Refactor managed file and directory initializers.
11
+ * Add the new Util module with a helper method.
12
+ * Toggle managed files as hidden in normal use.
13
+ * Update find_entry to take hidden files into account.
14
+ * Fix the managed files and directories lists.
15
+ * Update the hidden file detection code.
16
+ * Cache managed entry lists.
17
+ * Split up the hidden entry/find_entry tests.
18
+ * Update get_entry to take hidden files into account.
19
+ * Mixin the Util module to the ManagedEntry class.
20
+ * Update glob to take hidden files into account.
21
+ * Improve Util::entry_name to be more robust.
22
+ * Remove old Container compatibility.
23
+ * Document removal of ZipContainer::Container in the ReadMe.
24
+ * Update rubyzip version to latest (1.1.6).
25
+
3
26
  == Version 1.1.0
4
27
 
5
28
  * Bump version of rubyzip to 1.1.4.
data/ReadMe.rdoc CHANGED
@@ -19,7 +19,18 @@ This is a Ruby library for working with ZIP Container files. See the
19
19
  {UDF}[https://learn.adobe.com/wiki/display/PDFNAV/Universal+Container+Format]
20
20
  specifications for more details.
21
21
 
22
- == Backwards incompatibility warning!
22
+ == Backwards incompatibility warnings!
23
+
24
+ === ZipContainer
25
+
26
+ The ZipContainer::Container class is deprecated in favour of
27
+ ZipContainer::File. These classes are functionally identical; it is just a
28
+ change of name. The new name brings this API into closer alignment with the
29
+ underlying rubyzip API (Zip::File).
30
+
31
+ ZipContainer::Container is unavailable from version 2.0.0 onwards.
32
+
33
+ === Rubyzip
23
34
 
24
35
  Version 1.0.0 and up of this gem uses version 1.0.0 and up of the
25
36
  {rubyzip}[https://rubygems.org/gems/rubyzip] library. This has a backwards
@@ -65,7 +65,7 @@ begin
65
65
  # Add a explanation of this file.
66
66
  c.comment = "This is an example Container file!"
67
67
  end
68
- rescue ZipContainer::MalformedContainerError, Zip::ZipError => err
68
+ rescue ZipContainer::MalformedContainerError, ZipContainer::ZipError => err
69
69
  puts err.to_s
70
70
  exit 1
71
71
  end
@@ -45,7 +45,7 @@ container_file = ARGV[0]
45
45
 
46
46
  begin
47
47
  ZipContainer::Container.verify!(container_file)
48
- rescue ZipContainer::MalformedContainerError, Zip::ZipError => err
48
+ rescue ZipContainer::MalformedContainerError, ZipContainer::ZipError => err
49
49
  puts err.to_s
50
50
  exit 1
51
51
  end
@@ -45,7 +45,7 @@ container_file = ARGV[0]
45
45
 
46
46
  begin
47
47
  container = ZipContainer::Container.open(container_file)
48
- rescue ZipContainer::MalformedContainerError, Zip::ZipError => err
48
+ rescue ZipContainer::MalformedContainerError, ZipContainer::ZipError => err
49
49
  puts err.to_s
50
50
  exit 1
51
51
  end
data/lib/zip-container.rb CHANGED
@@ -35,6 +35,7 @@ require 'bundler/setup'
35
35
 
36
36
  require 'zip/filesystem'
37
37
 
38
+ require 'zip-container/util'
38
39
  require 'zip-container/version'
39
40
  require 'zip-container/exceptions'
40
41
  require 'zip-container/entries/reserved'
@@ -42,7 +43,7 @@ require 'zip-container/entries/managed'
42
43
  require 'zip-container/entries/entry'
43
44
  require 'zip-container/entries/file'
44
45
  require 'zip-container/entries/directory'
45
- require 'zip-container/container'
46
+ require 'zip-container/file'
46
47
 
47
48
  # This is a ruby library to read and write ZIP Container Format files. See the
48
49
  # ZipContainer::Container class for more information.
@@ -44,15 +44,25 @@ module ZipContainer
44
44
  include ManagedEntries
45
45
 
46
46
  # :call-seq:
47
- # new(name, required = false) -> ManagedDirectory
47
+ # new(name, options = {}) -> ManagedDirectory
48
48
  #
49
- # Create a new ManagedDirectory with the supplied name and whether it is
50
- # required to exist or not. Any ManagedFile or ManagedDirectory objects
51
- # that are within this directory can also be given if required.
52
- def initialize(name, required = false, entries = [])
53
- super(name, required)
49
+ # Create a new ManagedDirectory with the supplied name. Options that can
50
+ # be passed in are:
51
+ # * <tt>:required</tt> whether it is required to exist or not (default
52
+ # false).
53
+ # * <tt>:hidden</tt> whether it is hidden for normal operations.
54
+ # * <tt>:entries</tt> a list of ManagedFile and ManagedDirectory objects
55
+ # that are within this directory (default []).
56
+ def initialize(name, options = {})
57
+ options = {
58
+ :required => false,
59
+ :hidden => false,
60
+ :entries => []
61
+ }.merge(options)
54
62
 
55
- initialize_managed_entries(entries)
63
+ super(name, options[:required], options[:hidden])
64
+
65
+ initialize_managed_entries(options[:entries])
56
66
  end
57
67
 
58
68
  # :call-seq:
@@ -36,6 +36,7 @@ module ZipContainer
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
+ include Util
39
40
 
40
41
  # The name of the ManagedEntry. For the full path name of this entry use
41
42
  # full_name.
@@ -45,11 +46,13 @@ module ZipContainer
45
46
  # new(name, required) -> ManagedEntry
46
47
  #
47
48
  # Create a new ManagedEntry with the supplied name. The entry should also
48
- # be marked as required or not.
49
- def initialize(name, required)
49
+ # be marked as required or not and whether it is hidden for normal
50
+ # operations.
51
+ def initialize(name, required, hidden)
50
52
  @parent = nil
51
53
  @name = name
52
54
  @required = required
55
+ @hidden = hidden
53
56
  end
54
57
 
55
58
  # :call-seq:
@@ -57,7 +60,7 @@ module ZipContainer
57
60
  #
58
61
  # The fully qualified name of this ManagedEntry.
59
62
  def full_name
60
- @parent.is_a?(Container) ? @name : "#{@parent.name}/#{@name}"
63
+ @parent.is_a?(ZipContainer::File) ? @name : "#{@parent.full_name}/#{@name}"
61
64
  end
62
65
 
63
66
  # :call-seq:
@@ -69,6 +72,15 @@ module ZipContainer
69
72
  @required
70
73
  end
71
74
 
75
+ # :call-seq:
76
+ # hidden? -> true or false
77
+ #
78
+ # Is this ManagedEntry hidden for normal operations?
79
+ def hidden?
80
+ # An entry is hidden if its parent is hidden.
81
+ @parent.is_a?(ZipContainer::File) ? @hidden : @hidden || @parent.hidden?
82
+ end
83
+
72
84
  # :call-seq:
73
85
  # exists? -> true or false
74
86
  #
@@ -128,7 +140,7 @@ module ZipContainer
128
140
  #
129
141
  # Return the Container that this ManagedEntry resides in.
130
142
  def container
131
- @parent.is_a?(Container) ? @parent : @parent.container
143
+ @parent.is_a?(ZipContainer::File) ? @parent : @parent.container
132
144
  end
133
145
 
134
146
  end
@@ -39,12 +39,15 @@ module ZipContainer
39
39
  # :call-seq:
40
40
  # new(name, required = false, validation_proc = nil) -> ManagedFile
41
41
  #
42
- # Create a new ManagedFile with the supplied name and whether it is
43
- # required to exist or not.
44
- #
45
- # If supplied <tt>validation_proc</tt> should be a Proc that takes a
46
- # single parameter and returns +true+ or +false+ depending on whether the
47
- # contents of the file were validated or not.
42
+ # Create a new ManagedFile with the supplied name. Options that can
43
+ # be passed in are:
44
+ # * <tt>:required</tt> whether it is required to exist or not (default
45
+ # false).
46
+ # * <tt>:hidden</tt> whether it is hidden for normal operations.
47
+ # * <tt>:validation_proc</tt> should be a Proc that takes a single
48
+ # parameter, to which will be supplied the contents of the file, and
49
+ # returns +true+ or +false+ depending on whether the contents of the
50
+ # file were validated or not (default nil).
48
51
  #
49
52
  # For more complex content validation subclasses may override the validate
50
53
  # method.
@@ -54,11 +57,19 @@ module ZipContainer
54
57
  # word "Boo!".
55
58
  #
56
59
  # valid = Proc.new { |contents| contents == "Boo!" }
57
- # ManagedFile.new("Surprize.txt", false, valid)
58
- def initialize(name, required = false, validation_proc = nil)
59
- super(name, required)
60
+ # ManagedFile.new("Surprize.txt", :required => false,
61
+ # :validation_proc => valid)
62
+ def initialize(name, options = {})
63
+ options = {
64
+ :required => false,
65
+ :hidden => false,
66
+ :validation_proc => nil
67
+ }.merge(options)
68
+
69
+ super(name, options[:required], options[:hidden])
60
70
 
61
- @validation_proc = validation_proc.is_a?(Proc) ? validation_proc : nil
71
+ @validation_proc =
72
+ options[:validation_proc].is_a?(Proc) ? options[:validation_proc] : nil
62
73
  end
63
74
 
64
75
  # :call-seq:
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2013 The University of Manchester, UK.
1
+ # Copyright (c) 2013, 2014 The University of Manchester, UK.
2
2
  #
3
3
  # All rights reserved.
4
4
  #
@@ -39,13 +39,18 @@ module ZipContainer
39
39
  # +initialize_managed_entries+ in your constructor to ensure that the
40
40
  # internal lists of managed entries are correctly assigned.
41
41
  module ManagedEntries
42
+ include Util
42
43
 
43
44
  # :call-seq:
44
45
  # managed_directories -> Array
45
46
  #
46
47
  # Return the list of managed directories.
47
48
  def managed_directories
48
- @directories.values
49
+ return @managed_directories if @managed_directories
50
+
51
+ dirs = @directories.values
52
+ @managed_directories = dirs +
53
+ dirs.map { |d| d.managed_directories }.flatten
49
54
  end
50
55
 
51
56
  # :call-seq:
@@ -53,7 +58,7 @@ module ZipContainer
53
58
  #
54
59
  # Return the list of managed directory names.
55
60
  def managed_directory_names
56
- expand_names(@directories.keys)
61
+ @managed_directory_names ||= managed_directories.map { |d| d.full_name }
57
62
  end
58
63
 
59
64
  # :call-seq:
@@ -69,7 +74,7 @@ module ZipContainer
69
74
  #
70
75
  # Return the list of managed files and directories.
71
76
  def managed_entries
72
- managed_files + managed_directories
77
+ @managed_entries ||= managed_files + managed_directories
73
78
  end
74
79
 
75
80
  # :call-seq:
@@ -77,7 +82,7 @@ module ZipContainer
77
82
  #
78
83
  # Return the list of managed file and directory names.
79
84
  def managed_entry_names
80
- managed_file_names + managed_directory_names
85
+ @managed_entry_names ||= managed_file_names + managed_directory_names
81
86
  end
82
87
 
83
88
  # :call-seq:
@@ -85,8 +90,7 @@ module ZipContainer
85
90
  #
86
91
  # Is the supplied entry/name a managed entry?
87
92
  def managed_entry?(entry, list = managed_entry_names)
88
- name = entry.kind_of?(::Zip::Entry) ? entry.name : entry
89
- name.chop! if name.end_with? "/"
93
+ name = entry_name(entry)
90
94
  list.map { |n| n.downcase }.include? name.downcase
91
95
  end
92
96
 
@@ -98,12 +102,39 @@ module ZipContainer
98
102
  managed_entry?(entry, managed_file_names)
99
103
  end
100
104
 
105
+ # :call-seq:
106
+ # hidden_directory?(entry) -> boolean
107
+ #
108
+ # Is the supplied entry/name a hidden directory?
109
+ def hidden_directory?(entry)
110
+ name = entry_name(entry)
111
+ managed_directory?(name) ? all_managed_entries[name].hidden? : false
112
+ end
113
+
114
+ # :call-seq:
115
+ # hidden_file?(entry) -> boolean
116
+ #
117
+ # Is the supplied entry/name a hidden file?
118
+ def hidden_file?(entry)
119
+ name = entry_name(entry)
120
+ managed_file?(name) ? all_managed_entries[name].hidden? : false
121
+ end
122
+
123
+ # :call-seq:
124
+ # hidden_entry?(entry) -> boolean
125
+ #
126
+ # Is the supplied entry/name a hidden?
127
+ def hidden_entry?(entry)
128
+ hidden_directory?(entry) || hidden_file?(entry)
129
+ end
130
+
101
131
  # :call-seq:
102
132
  # managed_files -> Array
103
133
  #
104
134
  # Return the list of managed files.
105
135
  def managed_files
106
- @files.values + managed_directories.map { |d| d.managed_files }.flatten
136
+ @managed_files ||= @files.values +
137
+ @directories.values.map { |d| d.managed_files }.flatten
107
138
  end
108
139
 
109
140
  # :call-seq:
@@ -111,8 +142,7 @@ module ZipContainer
111
142
  #
112
143
  # Return the list of managed file names.
113
144
  def managed_file_names
114
- expand_names(@files.keys) +
115
- managed_directories.map { |d| d.managed_file_names }.flatten
145
+ @managed_file_names ||= managed_files.map { |f| f.full_name }
116
146
  end
117
147
 
118
148
  # :call-seq:
@@ -172,11 +202,15 @@ module ZipContainer
172
202
  @files[entry.name] = entry if entry.is_a? ManagedFile
173
203
  end
174
204
 
175
- private
205
+ # :stopdoc:
206
+ def all_managed_entries
207
+ return @entries unless @entries.nil?
176
208
 
177
- def expand_names(names)
178
- names.map { |n| self.is_a?(Container) ? n : "#{name}/#{n}" }
209
+ all = {}
210
+ managed_entries.each { |e| all[e.full_name] = e }
211
+ @entries = all
179
212
  end
213
+ # :startdoc:
180
214
 
181
215
  end
182
216
  end
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2013 The University of Manchester, UK.
1
+ # Copyright (c) 2013, 2014 The University of Manchester, UK.
2
2
  #
3
3
  # All rights reserved.
4
4
  #
@@ -35,6 +35,7 @@ module ZipContainer
35
35
 
36
36
  # This module provides support for reserved names.
37
37
  module ReservedNames
38
+ include Util
38
39
 
39
40
  # :call-seq:
40
41
  # reserved_names -> Array
@@ -68,8 +69,7 @@ module ZipContainer
68
69
  # Is the given entry in the reserved list of names? A String or a
69
70
  # Zip::Entry object can be passed in here.
70
71
  def reserved_entry?(entry)
71
- name = entry.kind_of?(::Zip::Entry) ? entry.name : entry
72
- name.chop! if name.end_with? "/"
72
+ name = entry_name(entry)
73
73
  reserved_names.map { |n| n.downcase }.include? name.downcase
74
74
  end
75
75
 
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2013 The University of Manchester, UK.
1
+ # Copyright (c) 2013, 2014 The University of Manchester, UK.
2
2
  #
3
3
  # All rights reserved.
4
4
  #
@@ -33,12 +33,17 @@
33
33
  #
34
34
  module ZipContainer
35
35
 
36
- # The base class of all other exceptions raised by this library.
37
- class ContainerError < RuntimeError
36
+ # The base of all exceptions raised by this library.
37
+ module ContainerError
38
38
  end
39
39
 
40
+ # Shadow Zip::Error so the rubyzip API doesn't leak out.
41
+ ZipError = ::Zip::Error
42
+ ZipError.send(:include, ContainerError)
43
+
40
44
  # This exception is raised when a bad Container is detected.
41
- class MalformedContainerError < ContainerError
45
+ class MalformedContainerError < RuntimeError
46
+ include ContainerError
42
47
 
43
48
  # :call-seq:
44
49
  # new(reason = "")
@@ -56,7 +61,8 @@ module ZipContainer
56
61
 
57
62
  # This exception is raised when a clash occurs with a reserved or managed
58
63
  # name.
59
- class ReservedNameClashError < ContainerError
64
+ class ReservedNameClashError < RuntimeError
65
+ include ContainerError
60
66
 
61
67
  # :call-seq:
62
68
  # new(name)