ro-bundle 0.1.0

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 +15 -0
  2. data/.gitignore +11 -0
  3. data/.ruby-env +1 -0
  4. data/.ruby-gemset +2 -0
  5. data/.ruby-version +2 -0
  6. data/.travis.yml +11 -0
  7. data/Changes.rdoc +129 -0
  8. data/Gemfile +11 -0
  9. data/Licence.rdoc +29 -0
  10. data/Rakefile +29 -0
  11. data/ReadMe.rdoc +57 -0
  12. data/bin/dir2ro +48 -0
  13. data/bin/ro-bundle-info +45 -0
  14. data/bin/verify-ro-bundle +27 -0
  15. data/bin/zip2ro +57 -0
  16. data/lib/ro-bundle.rb +45 -0
  17. data/lib/ro-bundle/exceptions.rb +30 -0
  18. data/lib/ro-bundle/file.rb +323 -0
  19. data/lib/ro-bundle/ro/agent.rb +73 -0
  20. data/lib/ro-bundle/ro/aggregate.rb +107 -0
  21. data/lib/ro-bundle/ro/annotation.rb +89 -0
  22. data/lib/ro-bundle/ro/directory.rb +120 -0
  23. data/lib/ro-bundle/ro/manifest.rb +338 -0
  24. data/lib/ro-bundle/ro/provenance.rb +153 -0
  25. data/lib/ro-bundle/util.rb +57 -0
  26. data/lib/ro-bundle/version.rb +13 -0
  27. data/ro-bundle.gemspec +43 -0
  28. data/test/data/HelloAnyone.robundle +0 -0
  29. data/test/data/empty-manifest.json +1 -0
  30. data/test/data/example3-manifest.json +40 -0
  31. data/test/data/invalid-manifest.json +5 -0
  32. data/test/data/invalid-manifest.robundle +0 -0
  33. data/test/helpers/fake_manifest.rb +23 -0
  34. data/test/helpers/fake_provenance.rb +32 -0
  35. data/test/helpers/list_tests.rb +22 -0
  36. data/test/tc_add_annotation.rb +571 -0
  37. data/test/tc_agent.rb +63 -0
  38. data/test/tc_aggregate.rb +116 -0
  39. data/test/tc_annotation.rb +84 -0
  40. data/test/tc_create.rb +170 -0
  41. data/test/tc_manifest.rb +221 -0
  42. data/test/tc_provenance.rb +121 -0
  43. data/test/tc_read.rb +66 -0
  44. data/test/tc_remove.rb +140 -0
  45. data/test/tc_util.rb +64 -0
  46. data/test/ts_ro_bundle.rb +28 -0
  47. metadata +217 -0
checksums.yaml ADDED
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ MzZiZjc4MTE0OTMyM2Q2ZDhiMDY1Yjk1MTY4NjgwNDc1YTAzY2I1NA==
5
+ data.tar.gz: !binary |-
6
+ ZDhiYWIxODFjYmNkZWExZGZkZDEzNjkwNmY4OTAwNTQ4M2NhMDZhMQ==
7
+ SHA512:
8
+ metadata.gz: !binary |-
9
+ ZWQyYjRmZjY1YWQyODE2YTAzN2Y5YzI1NTliMzgwYjY5M2RmNDk1MmQ3ODJj
10
+ ZjM0ZmRjN2Y5ZWY2MjA1ZmE3MjdiYjRiMDYwNGQ0YjlkODhhN2FkNDZjNzI2
11
+ MWRiOWEwOGEwYzEyZWJlNDNhNjY4MTU2ZTA2OTU1NWIzMmQ1ODk=
12
+ data.tar.gz: !binary |-
13
+ NGJkYjkxZmQwMTE3ZTBmZjRmNDQ3YmI2NzhmMTM5NTM5ZDAxMjZhNzQ2NTM1
14
+ YzUwNGZiNzJjY2QzYWJjMjI3Yjg5NDQxOGFhZGM0YTliZTc1ZjMyMjBlYmIz
15
+ MTU5OGY0YTg1M2Q5M2FiOTFlZGU1YzRhYzdkOGI4OTQ3YmZmZTM=
data/.gitignore ADDED
@@ -0,0 +1,11 @@
1
+ pkg/
2
+ html/
3
+ coverage/
4
+ .buildpath
5
+ .project
6
+ .settings
7
+ .idea
8
+ .rvmrc
9
+ example.zip
10
+ .bundle
11
+ Gemfile.lock
data/.ruby-env ADDED
@@ -0,0 +1 @@
1
+ RUBYLIB=./lib:../lib
data/.ruby-gemset ADDED
@@ -0,0 +1,2 @@
1
+ ro-bundle
2
+
data/.ruby-version ADDED
@@ -0,0 +1,2 @@
1
+ ruby-1.9.3
2
+
data/.travis.yml ADDED
@@ -0,0 +1,11 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.3
4
+ - 2.0.0
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 ADDED
@@ -0,0 +1,129 @@
1
+ = Changes log for the RO Bundle Ruby Gem
2
+
3
+ == Version 0.1.0
4
+
5
+ * Use the ZipContainer::ZipError in examples and tests.
6
+ * Use "self" for the File class methods and fix docs.
7
+ * Read the id from the manifest.
8
+ * Set .ro and .ro/manifest.json to be required entries.
9
+ * Properly detect missing manifest during creation.
10
+ * Simple validation of the manifest file.
11
+ * Read createdOn and authoredOn info from the manifest.
12
+ * Add a class to represent an Agent in an RO.
13
+ * Read createdBy and authoredBy from the manifest.
14
+ * Move the .ro directory code to a sub-directory.
15
+ * Move the manifest class to its own file.
16
+ * Document the RODir and Manifest classes.
17
+ * Move operations on the manifest data into the manifest class.
18
+ * Harden getting a missing time from the manifest.
19
+ * Harden getting the id from the manifest.
20
+ * Harden getting the creator and author list.
21
+ * Get the list of history files from the manifest.
22
+ * Ensure that an Agent always has a name.
23
+ * Ensure lists are always returned when necessary.
24
+ * Add separate tests for the Manifest class.
25
+ * Add an exception for invalid aggregates.
26
+ * Add a class to represent an aggregated resource.
27
+ * Cache created_on and authored_on in the manifest.
28
+ * Expose the aggregates method in the File class.
29
+ * Ensure that Manifest#aggregates always returns a list.
30
+ * Add a class to represent an annotation.
31
+ * Add the #annotations method to the Manifest class.
32
+ * Expose the annotations method in the File class.
33
+ * Add Agent#to_json.
34
+ * Refactor to use hashes for internal state storage.
35
+ * Add a utility module for mixing in common functions.
36
+ * Use the utility module to parse time values.
37
+ * Use the utility module to parse URIs.
38
+ * Use the utility module to clean JSON structures.
39
+ * Fixup the to_json methods so that JSON#generate can use them.
40
+ * Add a Util test case and test the parse_time method.
41
+ * Add tests for the Util#parse_uri method.
42
+ * Add tests for the Util#clean_json method.
43
+ * Refactor the annotation tests to share setup.
44
+ * Add json output for the Annotation class.
45
+ * Return "/" by default for Manifest#id.
46
+ * Refactor Manifest for easier serialization.
47
+ * Improve Util#clean_json.
48
+ * Add Manifest#to_json.
49
+ * Add write support for Manifest#id.
50
+ * Write support for Manifest#created_on and #authored_on.
51
+ * Write support for Manifest#created_by.
52
+ * Return duplicate lists from Manifest.
53
+ * Add an edited flag to Manifest to detect changes.
54
+ * Add Manifest write access methods to the File class.
55
+ * Add File#add and File#add_aggregate.
56
+ * Add File#add_history and support in the manifest.
57
+ * Support for adding an author to the authoredBy list.
58
+ * Override File#commit_required? to include the manifest.
59
+ * Annotation: generate id on create, not on access.
60
+ * Fix erroneous Annotation test data.
61
+ * Allow annotation content to be set at creation time.
62
+ * Edit annotation content.
63
+ * Rename Annotation#about to Annotation#target.
64
+ * Add access to the manifest @context element.
65
+ * Create the .ro directory on init if needs be.
66
+ * Write out the manifest when closing the bundle.
67
+ * Don't create an empty Agent for Manifest#created_by.
68
+ * Initialize default manifest @context if missing.
69
+ * Initialize default manifest id if missing.
70
+ * Allow Manifest#add_aggregate to be passed an Aggregate object.
71
+ * Set aggregate mediatype on creation.
72
+ * Add Util.is_absolute_uri? method.
73
+ * Add File#aggregate? to test if an entry is aggregated.
74
+ * Improve Util.is_absolute_uri?().
75
+ * Mangle aggregate paths when building an Aggregate.
76
+ * Enable adding URI aggregates.
77
+ * Handle URIs in File#aggregate?().
78
+ * Override File#find_entry() to cope with URIs.
79
+ * Add URI aggregation tests.
80
+ * Add File#annotation? to test registered annotations.
81
+ * Add File#annotatable?().
82
+ * Add support for adding annotations to the manifest.
83
+ * Keep an internal manifest reference in RODir.
84
+ * Add AnnotationsDir managed directory to RODir.
85
+ * Add File#add_annotation.
86
+ * Manifest#add_author now returns an Agent object.
87
+ * Manifest#add_aggregate now returns an Aggregate object.
88
+ * Manifest#add_annotation now returns an Annotation object.
89
+ * Add tests for annotations with no targets.
90
+ * Use released versions of ucf and zip-container gems.
91
+ * Fix File#add_history documentation.
92
+ * Make Manifest#created_by= more flexible.
93
+ * Update the example manifest test fixture.
94
+ * Add Manifest#remove_annotation.
95
+ * Don't store an aggregate's uri as a URI object.
96
+ * Add Manifest#remove_aggregate.
97
+ * Don't store an agent's uri or orcid as URI objects.
98
+ * Remove the Util.parse_uri() method.
99
+ * Consolidate all require directives into one place.
100
+ * Tests on an empty manifest ({}).
101
+ * Tests on an invalid manifest.
102
+ * Tests on a bundle with an invalid manifest.
103
+ * Factor out the provenance information from the manifest.
104
+ * Factor out the provenance information from aggregates.
105
+ * Add provenance information to annotations.
106
+ * Add Provenance#remove_author.
107
+ * Refactor Manifest#remove_annotation.
108
+ * Allow annotations to be removed by their content field.
109
+ * Override File#remove to ensure manifest is kept up to date.
110
+ * Cleanup annotation content stored in .ro/annotations.
111
+ * Add Util.strip_leading_slash.
112
+ * Add Aggregate#file_entry for convenience.
113
+ * Add File#remove_aggregate.
114
+ * Add a new example script "zip2ro".
115
+ * Add a new example script "dir2ro".
116
+ * Add example and limitations detail to the ReadMe.
117
+
118
+ == Version 0.0.1
119
+
120
+ * Very basic RO Bundle facilities complete (plus examples).
121
+ * Very simple verification of RO Bundle files.
122
+ * API documentation added.
123
+ * Add tests.
124
+
125
+ == About this Changes file
126
+
127
+ This file is, at least in part, generated by the following command:
128
+
129
+ $ git log --pretty=format:"* %s" --reverse --no-merges <commit-hash>..
data/Gemfile ADDED
@@ -0,0 +1,11 @@
1
+ #------------------------------------------------------------------------------
2
+ # Copyright (c) 2014 The University of Manchester, UK.
3
+ #
4
+ # BSD Licenced. See LICENCE.rdoc for details.
5
+ #
6
+ # Author: Robert Haines
7
+ #------------------------------------------------------------------------------
8
+
9
+ source 'https://rubygems.org'
10
+
11
+ gemspec
data/Licence.rdoc ADDED
@@ -0,0 +1,29 @@
1
+ Copyright (c) 2014 The University of Manchester, UK.
2
+
3
+ All rights reserved.
4
+
5
+ Redistribution and use in source and binary forms, with or without
6
+ modification, are permitted provided that the following conditions are met:
7
+
8
+ * Redistributions of source code must retain the above copyright notice,
9
+ this list of conditions and the following disclaimer.
10
+
11
+ * Redistributions in binary form must reproduce the above copyright notice,
12
+ this list of conditions and the following disclaimer in the documentation
13
+ and/or other materials provided with the distribution.
14
+
15
+ * Neither the names of The University of Manchester nor the names of its
16
+ contributors may be used to endorse or promote products derived from this
17
+ software without specific prior written permission.
18
+
19
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
23
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29
+ POSSIBILITY OF SUCH DAMAGE.
data/Rakefile ADDED
@@ -0,0 +1,29 @@
1
+ #------------------------------------------------------------------------------
2
+ # Copyright (c) 2014 The University of Manchester, UK.
3
+ #
4
+ # BSD Licenced. See LICENCE.rdoc for details.
5
+ #
6
+ # Author: Robert Haines
7
+ #------------------------------------------------------------------------------
8
+
9
+ require "bundler/gem_tasks"
10
+ require "rake/testtask"
11
+ require "rdoc/task"
12
+
13
+ task :default => [:test]
14
+
15
+ Rake::TestTask.new do |t|
16
+ t.libs << "test"
17
+ t.test_files = FileList['test/ts_ro_bundle.rb']
18
+ t.verbose = true
19
+ end
20
+
21
+ RDoc::Task.new do |r|
22
+ r.main = "ReadMe.rdoc"
23
+ lib = Dir.glob("lib/**/*.rb")
24
+ r.rdoc_files.include("ReadMe.rdoc", "Licence.rdoc", "Changes.rdoc", lib)
25
+ r.options << "-t Research Object Bundle Ruby Library version " +
26
+ "#{ROBundle::VERSION}"
27
+ r.options << "-N"
28
+ r.options << "--tab-width=2"
29
+ end
data/ReadMe.rdoc ADDED
@@ -0,0 +1,57 @@
1
+ = Research Object Bundle Ruby Library
2
+
3
+ Authors:: Robert Haines
4
+ Contact:: mailto:support@mygrid.org.uk
5
+ Homepage:: http://mygrid.github.io/ruby-ro-bundle
6
+ Source code:: https://github.com/myGrid/ruby-ro-bundle
7
+ Licence:: BSD (See Licence file or http://www.opensource.org/licenses/bsd-license.php)
8
+ Copyright:: (c) 2014 The University of Manchester, UK
9
+
10
+ {<img src="https://codeclimate.com/github/myGrid/ruby-ro-bundle.png" />}[https://codeclimate.com/github/myGrid/ruby-ro-bundle]
11
+ {<img src="https://travis-ci.org/myGrid/ruby-ro-bundle.svg?branch=master" alt="Build Status" />}[https://travis-ci.org/myGrid/ruby-ro-bundle]
12
+ {<img src="https://coveralls.io/repos/myGrid/ruby-ro-bundle/badge.png?branch=master" alt="Coverage Status" />}[https://coveralls.io/r/myGrid/ruby-ro-bundle?branch=master]
13
+
14
+ == Synopsis
15
+
16
+ This is a Ruby library for working with Research Object Bundle files. See the
17
+ {Research Object Bundle}[http://wf4ever.github.io/ro/bundle/] specification
18
+ for more details.
19
+
20
+ <b>This library is a work in progress!</b> Until we release version 1.0.0 you
21
+ can expect the API to change in incompatible ways, although we will try to
22
+ keep this to an absolute minimum. Once version 1.0.0 is released we will be
23
+ following the principles of {Semantic Versioning}[http://semver.org/] for our
24
+ version numbering scheme.
25
+
26
+ == Usage
27
+
28
+ Most of this library's API is provided by two underlying gems. Please consult
29
+ their documentation in addition to this:
30
+
31
+ * {zip-container gem}[https://rubygems.org/gems/zip-container]
32
+ {documentation}[http://mygrid.github.io/ruby-zip-container/]
33
+ * {ucf gem}[https://rubygems.org/gems/ucf]
34
+ {documentation}[http://mygrid.github.io/ruby-ucf]
35
+
36
+ There are some examples of how to use the library provided in the bin
37
+ directory:
38
+
39
+ * <tt>ro-bundle-info</tt>: Print out simple metrics about this RO Bundle. This
40
+ is analogous to the standard <tt>zipinfo</tt> command.
41
+ * <tt>verify-ro-bundle</tt>: Verify that the specified RO Bundle is valid.
42
+ * <tt>dir2ro</tt>: Recursively package up a directory into a RO Bundle. All
43
+ files in the directory are added as aggregates.
44
+ * <tt>zip2ro</tt>: Copy all files from a normal zip file into a RO Bundle. All
45
+ files in the zip file are added as aggregates.
46
+
47
+ See the contents of the tests directory for even more example usage.
48
+
49
+ == What this library cannot do yet
50
+
51
+ The {RO Bundle specification}[http://wf4ever.github.io/ro/bundle/] is largely
52
+ implemented but there are notable gaps at present, including:
53
+
54
+ * Aggregates do not support ORE proxies yet.
55
+ * Extra provenance information cannot yet be added using the <tt>pav:</tt>
56
+ namespace.
57
+ * The <tt>@graph</tt> member is not supported in the top-level manifest.
data/bin/dir2ro ADDED
@@ -0,0 +1,48 @@
1
+ #!/usr/bin/env ruby
2
+ #------------------------------------------------------------------------------
3
+ # Copyright (c) 2014 The University of Manchester, UK.
4
+ #
5
+ # BSD Licenced. See LICENCE.rdoc for details.
6
+ #
7
+ # Author: Robert Haines
8
+ #------------------------------------------------------------------------------
9
+
10
+ require 'rubygems'
11
+ require 'ro-bundle'
12
+
13
+ def usage
14
+ puts "Usage:\n dir2ro <directory> <ro-bundle> [name]"
15
+ exit 1
16
+ end
17
+
18
+ usage unless ARGV.length >= 2
19
+
20
+ dir_name = ARGV[0]
21
+ bundle_file = ARGV[1]
22
+ creator = ARGV[2]
23
+ time_now = Time.now
24
+
25
+ begin
26
+ ROBundle::File.create(bundle_file) do |bundle|
27
+ # Set provenance data.
28
+ bundle.created_by = creator unless creator.nil?
29
+ bundle.created_on = time_now
30
+
31
+ dir_path = Pathname(dir_name)
32
+ Dir[File.join(dir_name, "**", "**")].each do |entry|
33
+ relative_path = Pathname.new(entry).relative_path_from(dir_path).to_s
34
+
35
+ # If the current entry is a directory, create it;
36
+ # if it's a file, add it.
37
+ if ::File.directory?(entry)
38
+ bundle.mkdir(relative_path)
39
+ else
40
+ aggregate = bundle.add(relative_path, entry)
41
+ aggregate.created_on = time_now
42
+ end
43
+ end
44
+ end
45
+ rescue Errno::ENOENT, Zip::Error => err
46
+ puts err.to_s
47
+ exit 1
48
+ end
@@ -0,0 +1,45 @@
1
+ #!/usr/bin/env ruby
2
+ #------------------------------------------------------------------------------
3
+ # Copyright (c) 2014 The University of Manchester, UK.
4
+ #
5
+ # BSD Licenced. See LICENCE.rdoc for details.
6
+ #
7
+ # Author: Robert Haines
8
+ #------------------------------------------------------------------------------
9
+
10
+ require 'rubygems'
11
+ require 'ro-bundle'
12
+
13
+ def usage
14
+ puts "Usage:\n ro-bundle-info <ro-bundle>"
15
+ exit 1
16
+ end
17
+
18
+ usage unless ARGV.length == 1
19
+
20
+ bundle = ARGV[0]
21
+
22
+ begin
23
+ ro = ROBundle::File.open(bundle)
24
+ rescue ZipContainer::MalformedContainerError, ZipContainer::ZipError => err
25
+ puts err.to_s
26
+ exit 1
27
+ end
28
+
29
+ puts "Research Object Bundle: #{ro.to_s}"
30
+ puts "Bundle file size: #{File.size(bundle)} bytes, number of entries: #{ro.size}"
31
+
32
+ total_size = 0
33
+ total_comp = 0
34
+
35
+ ro.each do |entry|
36
+ total_size += entry.size
37
+ total_comp += entry.compressed_size
38
+ comp = entry.compression_method == 0 ? "stor" : "defN"
39
+ size = entry.size.to_s.rjust(8)
40
+ puts "#{size} #{comp} #{entry.time} #{entry.name}"
41
+ end
42
+
43
+ ratio = ((total_size - total_comp) / total_size.to_f) * 100
44
+ puts "%d files, %d bytes uncompressed, %d bytes compressed: %.1f%%" %
45
+ [ro.size, total_size, total_comp, ratio]
@@ -0,0 +1,27 @@
1
+ #!/usr/bin/env ruby
2
+ #------------------------------------------------------------------------------
3
+ # Copyright (c) 2014 The University of Manchester, UK.
4
+ #
5
+ # BSD Licenced. See LICENCE.rdoc for details.
6
+ #
7
+ # Author: Robert Haines
8
+ #------------------------------------------------------------------------------
9
+
10
+ require 'rubygems'
11
+ require 'ro-bundle'
12
+
13
+ def usage
14
+ puts "Usage:\n verify-ro-bundle <ro-bundle-file>"
15
+ exit 1
16
+ end
17
+
18
+ usage unless ARGV.length == 1
19
+
20
+ rofile = ARGV[0]
21
+
22
+ begin
23
+ ROBundle::File.verify!(rofile)
24
+ rescue ZipContainer::MalformedContainerError, ZipContainer::ZipError => err
25
+ puts err.to_s
26
+ exit 1
27
+ end
data/bin/zip2ro ADDED
@@ -0,0 +1,57 @@
1
+ #!/usr/bin/env ruby
2
+ #------------------------------------------------------------------------------
3
+ # Copyright (c) 2014 The University of Manchester, UK.
4
+ #
5
+ # BSD Licenced. See LICENCE.rdoc for details.
6
+ #
7
+ # Author: Robert Haines
8
+ #------------------------------------------------------------------------------
9
+
10
+ require 'rubygems'
11
+ require 'ro-bundle'
12
+
13
+ def usage
14
+ puts "Usage:\n zip2ro <zip-file> <ro-bundle> [name]"
15
+ exit 1
16
+ end
17
+
18
+ usage unless ARGV.length >= 2
19
+
20
+ zip_file = ARGV[0]
21
+ bundle_file = ARGV[1]
22
+ creator = ARGV[2]
23
+ time_now = Time.now
24
+
25
+ begin
26
+ ROBundle::File.create(bundle_file) do |bundle|
27
+ # Set provenance data.
28
+ bundle.created_by = creator unless creator.nil?
29
+ bundle.created_on = time_now
30
+
31
+ Zip::File.open(zip_file) do |zip|
32
+ zip.each do |entry|
33
+
34
+ # If the current entry is a directory, create it;
35
+ # if it's a file, copy it.
36
+ if zip.file.directory?(entry.name)
37
+ bundle.mkdir entry.name
38
+ else
39
+ zip.file.open(entry.name, "r") do |z_file|
40
+
41
+ # Copy the contents of the entry.
42
+ bundle.file.open(entry.name, "w") do |b_file|
43
+ b_file.write z_file.read
44
+ end
45
+
46
+ # Register the new entry as an aggregate of the RO.
47
+ aggregate = bundle.add_aggregate entry.name
48
+ aggregate.created_on = time_now
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
54
+ rescue Errno::ENOENT, Zip::Error => err
55
+ puts err.to_s
56
+ exit 1
57
+ end