ro-bundle 0.1.0

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