ddr-ingesttools 0.1.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: b4d5f514bb0ae159a1fe4fa7d200e7d546ccbc8b
4
+ data.tar.gz: dc3494b83113d2ec8fcb538985c332021916910f
5
+ SHA512:
6
+ metadata.gz: 33eb065f13d1acf0aa7fba7377d8a763832f063d3bc4cf2b67a5fd8bf73bff547621ba60ad53e8a605cd299574e2cd6b7b9ab1558e22c7b726af15be6f7e03da
7
+ data.tar.gz: d33e0dc0f25c06f707003e61050ea7ed170cd0aefdf69d312a65f0dd074203f43201fa5606d8c0143a8a29b86b3d0bf8e645f6ffb03708f57208484904bd2293
@@ -0,0 +1,3 @@
1
+ Gemfile.lock
2
+ pkg
3
+ tmp
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --require spec_helper
@@ -0,0 +1 @@
1
+ 2.3.1
@@ -0,0 +1,5 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.3.1
4
+ cache:
5
+ - bundler
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
@@ -0,0 +1,27 @@
1
+ Copyright (c) Duke University Libraries.
2
+ All rights reserved.
3
+
4
+ Redistribution and use in source and binary forms, with or without modification,
5
+ are permitted provided that the following conditions are met:
6
+
7
+ 1. Redistributions of source code must retain the above copyright notice,
8
+ this list of conditions and the following disclaimer.
9
+
10
+ 2. Redistributions in binary form must reproduce the above copyright notice,
11
+ this list of conditions and the following disclaimer in the documentation
12
+ and/or other materials provided with the distribution.
13
+
14
+ 3. Neither the name of Duke University nor the names of its contributors may
15
+ be used to endorse or promote products derived from this software without
16
+ specific prior written permission.
17
+
18
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
19
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
22
+ ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
25
+ ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1 @@
1
+ Ruby tools supporting the preparation of ingest packages for the Duke Digital Repository.
@@ -0,0 +1,7 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+
4
+ desc 'Run all specs in spec directory'
5
+ RSpec::Core::RakeTask.new(:spec)
6
+
7
+ task :default => :spec
@@ -0,0 +1,40 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'ddr/ingesttools'
4
+ require 'optparse'
5
+
6
+ # Parse command line arguments
7
+ options = {}
8
+ parser = OptionParser.new do |opts|
9
+ opts.banner = 'Usage: convert_dpc_folder.rb [options]'
10
+
11
+ opts.on('-s', '--source SOURCE', 'Path to DPC Folder to be converted') do |v|
12
+ options[:source] = v
13
+ end
14
+
15
+ opts.on('-t', '--target TARGET', 'Path to folder where Standard Ingest Format is to be built') do |v|
16
+ options[:target] = v
17
+ end
18
+
19
+ opts.on('-i', '--item_id_length LENGTH', Integer, 'Number of characters to copy from the beginning of each file name',
20
+ 'to use as the local ID of the item of which that file is a component') do |v|
21
+ options[:item_id_length] = v
22
+ end
23
+ end
24
+
25
+ begin
26
+ parser.parse!
27
+ mandatory = [ :source, :target, :item_id_length]
28
+ missing = mandatory.select{ |param| options[param].nil? }
29
+ unless missing.empty?
30
+ raise OptionParser::MissingArgument.new(missing.join(', '))
31
+ end
32
+ rescue OptionParser::InvalidOption, OptionParser::MissingArgument
33
+ puts $!.to_s
34
+ puts parser
35
+ exit(false)
36
+ end
37
+
38
+ converter_args = [ options[:source], options[:target], options[:item_id_length] ]
39
+ converter = Ddr::IngestTools::DpcFolderConverter::Converter.new(*converter_args)
40
+ converter.call
@@ -0,0 +1,26 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'ddr/ingesttools/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "ddr-ingesttools"
8
+ spec.version = Ddr::IngestTools::VERSION
9
+ spec.authors = ["Jim Coble"]
10
+ spec.email = ["jim.coble@duke.edu"]
11
+ spec.summary = "Ruby tools supporting ingest into the Duke Digital Repository."
12
+ spec.description = "A collection of Ruby tools supporting ingest into the Duke Digital Repository."
13
+ spec.homepage = "https://github.com/duke-libraries/ddr-ingesttools"
14
+ spec.license = "BSD-3-Clause"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_dependency "bagit", "~> 0.4"
22
+
23
+ spec.add_development_dependency "bundler", "~> 1.14"
24
+ spec.add_development_dependency "rake", "~> 12.0"
25
+ spec.add_development_dependency "rspec", "~> 3.0"
26
+ end
@@ -0,0 +1,8 @@
1
+ require_relative 'ingesttools/version'
2
+ require_relative 'ingesttools/dpc_folder_converter'
3
+
4
+ module Ddr
5
+ module IngestTools
6
+
7
+ end
8
+ end
@@ -0,0 +1,35 @@
1
+ require_relative 'dpc_folder_converter/converter'
2
+
3
+ module Ddr::IngestTools
4
+ module DpcFolderConverter
5
+ #Configuration defaults
6
+ @config = {
7
+ included_extensions: [ '.jpg', '.mov', '.mp3', '.mp4', '.pdf', '.tif', '.tiff', '.wav' ],
8
+ csv_options: { :encoding=>"UTF-8", :col_sep=>"\t", :headers=>true, :write_headers=>true,
9
+ :header_converters=>:symbol }
10
+ }
11
+
12
+ @valid_config_keys = @config.keys
13
+
14
+ # Configure through hash
15
+ def self.configure(opts = {})
16
+ opts.each {|k,v| @config[k.to_sym] = v if @valid_config_keys.include?(k.to_sym)}
17
+ end
18
+
19
+ # Configure through yaml file
20
+ def self.configure_with(path_to_yaml_file)
21
+ begin
22
+ config = YAML::load(IO.read(path_to_yaml_file))
23
+ rescue Errno::ENOENT
24
+ log(:warning, "YAML configuration file couldn't be found. Using defaults."); return
25
+ rescue Psych::SyntaxError
26
+ log(:warning, "YAML configuration file contains invalid syntax. Using defaults."); return
27
+ end
28
+ configure(config)
29
+ end
30
+
31
+ def self.config
32
+ @config
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,93 @@
1
+ require 'bagit'
2
+ require 'csv'
3
+ require 'fileutils'
4
+ require 'find'
5
+
6
+ module Ddr::IngestTools::DpcFolderConverter
7
+ class Converter
8
+
9
+ METADATA_HEADERS = [ 'path', 'local_id' ]
10
+
11
+ attr_reader :source, :target, :data_dir, :item_id_length
12
+ attr_accessor :local_id_metadata
13
+
14
+ def initialize(source, target, item_id_length)
15
+ @source = source
16
+ @target = target
17
+ @data_dir = File.join(target, 'data')
18
+ @item_id_length = item_id_length
19
+ @local_id_metadata = {}
20
+ end
21
+
22
+ def call
23
+ FileUtils.mkdir_p data_dir
24
+ find_component_files(source).each { |file| handle_component(file) }
25
+ find_target_files(source).each { |file| handle_target(file) }
26
+ output_metadata
27
+ bagitup
28
+ end
29
+
30
+ private
31
+
32
+ def included_extensions
33
+ Ddr::IngestTools::DpcFolderConverter.config[:included_extensions]
34
+ end
35
+
36
+ def find_component_files(dir)
37
+ files = []
38
+ Find.find(dir) do |path|
39
+ Find.prune if path.include?('targets')
40
+ Find.prune if path.include?('intermediate_files')
41
+ next unless File.file?(path)
42
+ next unless included_extensions.include?(File.extname(path))
43
+ files << path
44
+ end
45
+ files
46
+ end
47
+
48
+ def find_target_files(dir)
49
+ files = []
50
+ Find.find(dir) do |path|
51
+ next unless path.include?('targets')
52
+ next unless File.file?(path)
53
+ next unless included_extensions.include?(File.extname(path))
54
+ files << path
55
+ end
56
+ files
57
+ end
58
+
59
+ def handle_component(file)
60
+ base = File.basename(file, File.extname(file))
61
+ item_id = item_id_length == 0 ? base : base[0, item_id_length]
62
+ FileUtils.mkdir_p(File.join(data_dir, item_id))
63
+ local_id_metadata[item_id] = item_id
64
+ FileUtils.cp file, File.join(data_dir, item_id)
65
+ local_id_metadata[File.join(item_id, File.basename(file))] = base
66
+ end
67
+
68
+ def handle_target(file)
69
+ base = File.basename(file, File.extname(file))
70
+ FileUtils.mkdir_p(File.join(data_dir, 'dpc_targets'))
71
+ FileUtils.cp file, File.join(data_dir, 'dpc_targets')
72
+ local_id_metadata[File.join('dpc_targets', File.basename(file))] = base
73
+ end
74
+
75
+ def output_metadata
76
+ metadata_rows = []
77
+ local_id_metadata.each_pair do |k,v|
78
+ metadata_rows << CSV::Row.new(METADATA_HEADERS, [ k, v ])
79
+ end
80
+ File.open(File.join(data_dir, 'metadata.txt'), 'w') do |file|
81
+ file.puts(METADATA_HEADERS.join(Ddr::IngestTools::DpcFolderConverter.config[:csv_options][:col_sep]))
82
+ metadata_rows.each do |row|
83
+ file.puts(row.to_csv(Ddr::IngestTools::DpcFolderConverter.config[:csv_options]).strip)
84
+ end
85
+ end
86
+ end
87
+
88
+ def bagitup
89
+ bag = BagIt::Bag.new(target)
90
+ bag.manifest!
91
+ end
92
+ end
93
+ end
@@ -0,0 +1,5 @@
1
+ module Ddr
2
+ module IngestTools
3
+ VERSION = '0.1.0.rc1'
4
+ end
5
+ end
@@ -0,0 +1,8 @@
1
+ 59ec01f979a76b968bc579e5cd0ceb3bcf3e629f data/abc001/abc001001.tif
2
+ d0a2f2482783ae3c38d06f3cdeaa1a306cc043ad data/abc001/abc001002.tif
3
+ 38ee72ab417192589f3a54ef1016131c7d7e9e4e data/abc002/abc002001.tif
4
+ c227abc095d3b758051c1c1c9e922494b6b6e0b0 data/abc003/abc003001.wav
5
+ 541af8df7d2c631382bd0ec189476894d0323df5 data/abc003/abc003002.wav
6
+ a08c4d5a76d1b8734487be6ffcba66a9baf475c4 data/dpc_targets/T001.tif
7
+ 40f9993d06945544fa57af88f7c3e9102ecc69e3 data/dpc_targets/T002.tif
8
+ 913699468893882d1dec463f3df1a405c7f32784 data/metadata.txt
@@ -0,0 +1,87 @@
1
+ module Ddr::IngestTools::DpcFolderConverter
2
+
3
+ RSpec.describe Converter do
4
+
5
+ let(:source_directory) { Dir.mktmpdir('dpc') }
6
+ let(:target_directory) { Dir.mktmpdir('sif') }
7
+ let(:data_directory) { File.join(target_directory, 'data') }
8
+ let(:item_id_length) { 6 }
9
+ let(:expected_files) { [
10
+ target_directory,
11
+ File.join(target_directory, 'bag-info.txt'),
12
+ File.join(target_directory, 'bagit.txt'),
13
+ data_directory,
14
+ File.join(data_directory, 'abc001'),
15
+ File.join(data_directory, 'abc001', 'abc001001.tif'),
16
+ File.join(data_directory, 'abc001', 'abc001002.tif'),
17
+ File.join(data_directory, 'abc002'),
18
+ File.join(data_directory, 'abc002', 'abc002001.tif'),
19
+ File.join(data_directory, 'abc003', 'abc003001.wav'),
20
+ File.join(data_directory, 'abc003'),
21
+ File.join(data_directory, 'abc003', 'abc003002.wav'),
22
+ File.join(data_directory, 'dpc_targets'),
23
+ File.join(data_directory, 'dpc_targets', 'T001.tif'),
24
+ File.join(data_directory, 'dpc_targets', 'T002.tif'),
25
+ File.join(data_directory, 'metadata.txt'),
26
+ File.join(target_directory, 'manifest-md5.txt'),
27
+ File.join(target_directory, 'manifest-sha1.txt'),
28
+ File.join(target_directory, 'tagmanifest-md5.txt'),
29
+ File.join(target_directory, 'tagmanifest-sha1.txt')
30
+ ] }
31
+ let(:expected_metadata) { [
32
+ "path\tlocal_id",
33
+ "abc001\tabc001",
34
+ "abc002\tabc002",
35
+ "abc003\tabc003",
36
+ "abc001/abc001001.tif\tabc001001",
37
+ "abc001/abc001002.tif\tabc001002",
38
+ "abc002/abc002001.tif\tabc002001",
39
+ "abc003/abc003001.wav\tabc003001",
40
+ "abc003/abc003002.wav\tabc003002",
41
+ "dpc_targets/T001.tif\tT001",
42
+ "dpc_targets/T002.tif\tT002"
43
+ ] }
44
+
45
+ subject { Converter.new(source_directory, target_directory, item_id_length) }
46
+
47
+ before do
48
+ File.open(File.join(source_directory, 'Thumbs.db'), 'w') { |f| f.write('Thumbs') }
49
+ File.open(File.join(source_directory, 'abc001001.tif'), 'w') { |f| f.write('abc001001') }
50
+ File.open(File.join(source_directory, 'abc001002.tif'), 'w') { |f| f.write('abc001002') }
51
+ File.open(File.join(source_directory, 'abc002001.tif'), 'w') { |f| f.write('abc002001') }
52
+ File.open(File.join(source_directory, 'checksums.txt'), 'w') { |f| f.write('checksums') }
53
+ Dir.mkdir(File.join(source_directory,'g'))
54
+ File.open(File.join(source_directory, 'g', 'abc003001.wav'), 'w') { |f| f.write('abc003001') }
55
+ File.open(File.join(source_directory, 'g', 'abc003002.wav'), 'w') { |f| f.write('abc003002') }
56
+ Dir.mkdir(File.join(source_directory,'targets'))
57
+ File.open(File.join(source_directory, 'targets', 'T001.tif'), 'w') { |f| f.write('T001') }
58
+ File.open(File.join(source_directory, 'targets', 'T002.tif'), 'w') { |f| f.write('T002') }
59
+ end
60
+
61
+ it 'produces the correct standard ingest format directory' do
62
+ subject.call
63
+ expect(Array(Find.find(target_directory))).to match_array(expected_files)
64
+ expect(FileUtils.compare_file(File.join(data_directory, 'abc001', 'abc001001.tif'),
65
+ File.join(source_directory, 'abc001001.tif'))).to be true
66
+ expect(FileUtils.compare_file(File.join(data_directory, 'abc001', 'abc001002.tif'),
67
+ File.join(source_directory, 'abc001002.tif'))).to be true
68
+ expect(FileUtils.compare_file(File.join(data_directory, 'abc002', 'abc002001.tif'),
69
+ File.join(source_directory, 'abc002001.tif'))).to be true
70
+ expect(FileUtils.compare_file(File.join(data_directory, 'abc003', 'abc003001.wav'),
71
+ File.join(source_directory, 'g', 'abc003001.wav'))).to be true
72
+ expect(FileUtils.compare_file(File.join(data_directory, 'abc003', 'abc003002.wav'),
73
+ File.join(source_directory, 'g', 'abc003002.wav'))).to be true
74
+ expect(FileUtils.compare_file(File.join(data_directory, 'dpc_targets', 'T001.tif'),
75
+ File.join(source_directory, 'targets', 'T001.tif'))).to be true
76
+ expect(FileUtils.compare_file(File.join(data_directory, 'dpc_targets', 'T002.tif'),
77
+ File.join(source_directory, 'targets', 'T002.tif'))).to be true
78
+ metadata_lines = File.readlines(File.join(data_directory, 'metadata.txt')).map(&:strip)
79
+ expect(metadata_lines).to match_array(expected_metadata)
80
+ # expect(FileUtils.compare_file(File.join(target_directory, 'manifest-sha1.txt'),
81
+ # File.join(File.dirname(__FILE__), '..', 'fixtures', 'files', 'manifest-sha1.txt'))).to be true
82
+ expect(FileUtils.compare_file(File.join(target_directory, 'manifest-sha1.txt'),
83
+ File.join('spec', 'fixtures', 'files', 'manifest-sha1.txt'))).to be true
84
+ end
85
+
86
+ end
87
+ end
@@ -0,0 +1,105 @@
1
+ require 'ddr/ingesttools'
2
+
3
+ # This file was generated by the `rspec --init` command. Conventionally, all
4
+ # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
5
+ # The generated `.rspec` file contains `--require spec_helper` which will cause
6
+ # this file to always be loaded, without a need to explicitly require it in any
7
+ # files.
8
+ #
9
+ # Given that it is always loaded, you are encouraged to keep this file as
10
+ # light-weight as possible. Requiring heavyweight dependencies from this file
11
+ # will add to the boot time of your test suite on EVERY test run, even for an
12
+ # individual file that may not need all of that loaded. Instead, consider making
13
+ # a separate helper file that requires the additional dependencies and performs
14
+ # the additional setup, and require it from the spec files that actually need
15
+ # it.
16
+ #
17
+ # The `.rspec` file also contains a few flags that are not defaults but that
18
+ # users commonly want.
19
+ #
20
+ # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
21
+ RSpec.configure do |config|
22
+ # rspec-expectations config goes here. You can use an alternate
23
+ # assertion/expectation library such as wrong or the stdlib/minitest
24
+ # assertions if you prefer.
25
+ config.expect_with :rspec do |expectations|
26
+ # This option will default to `true` in RSpec 4. It makes the `description`
27
+ # and `failure_message` of custom matchers include text for helper methods
28
+ # defined using `chain`, e.g.:
29
+ # be_bigger_than(2).and_smaller_than(4).description
30
+ # # => "be bigger than 2 and smaller than 4"
31
+ # ...rather than:
32
+ # # => "be bigger than 2"
33
+ expectations.include_chain_clauses_in_custom_matcher_descriptions = true
34
+ end
35
+
36
+ # rspec-mocks config goes here. You can use an alternate test double
37
+ # library (such as bogus or mocha) by changing the `mock_with` option here.
38
+ config.mock_with :rspec do |mocks|
39
+ # Prevents you from mocking or stubbing a method that does not exist on
40
+ # a real object. This is generally recommended, and will default to
41
+ # `true` in RSpec 4.
42
+ mocks.verify_partial_doubles = true
43
+ end
44
+
45
+ # This option will default to `:apply_to_host_groups` in RSpec 4 (and will
46
+ # have no way to turn it off -- the option exists only for backwards
47
+ # compatibility in RSpec 3). It causes shared context metadata to be
48
+ # inherited by the metadata hash of host groups and examples, rather than
49
+ # triggering implicit auto-inclusion in groups with matching metadata.
50
+ config.shared_context_metadata_behavior = :apply_to_host_groups
51
+
52
+ # The settings below are suggested to provide a good initial experience
53
+ # with RSpec, but feel free to customize to your heart's content.
54
+ =begin
55
+ # This allows you to limit a spec run to individual examples or groups
56
+ # you care about by tagging them with `:focus` metadata. When nothing
57
+ # is tagged with `:focus`, all examples get run. RSpec also provides
58
+ # aliases for `it`, `describe`, and `context` that include `:focus`
59
+ # metadata: `fit`, `fdescribe` and `fcontext`, respectively.
60
+ config.filter_run_when_matching :focus
61
+
62
+ # Allows RSpec to persist some state between runs in order to support
63
+ # the `--only-failures` and `--next-failure` CLI options. We recommend
64
+ # you configure your source control system to ignore this file.
65
+ config.example_status_persistence_file_path = "spec/examples.txt"
66
+
67
+ # Limits the available syntax to the non-monkey patched syntax that is
68
+ # recommended. For more details, see:
69
+ # - http://rspec.info/blog/2012/06/rspecs-new-expectation-syntax/
70
+ # - http://www.teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
71
+ # - http://rspec.info/blog/2014/05/notable-changes-in-rspec-3/#zero-monkey-patching-mode
72
+ config.disable_monkey_patching!
73
+
74
+ # This setting enables warnings. It's recommended, but in some cases may
75
+ # be too noisy due to issues in dependencies.
76
+ config.warnings = true
77
+
78
+ # Many RSpec users commonly either run the entire suite or an individual
79
+ # file, and it's useful to allow more verbose output when running an
80
+ # individual spec file.
81
+ if config.files_to_run.one?
82
+ # Use the documentation formatter for detailed output,
83
+ # unless a formatter has already been configured
84
+ # (e.g. via a command-line flag).
85
+ config.default_formatter = 'doc'
86
+ end
87
+
88
+ # Print the 10 slowest examples and example groups at the
89
+ # end of the spec run, to help surface which specs are running
90
+ # particularly slow.
91
+ config.profile_examples = 10
92
+
93
+ # Run specs in random order to surface order dependencies. If you find an
94
+ # order dependency and want to debug it, you can fix the order by providing
95
+ # the seed, which is printed after each run.
96
+ # --seed 1234
97
+ config.order = :random
98
+
99
+ # Seed global randomization in this process using the `--seed` CLI option.
100
+ # Setting this allows you to use `--seed` to deterministically reproduce
101
+ # test failures related to randomization by passing the same `--seed` value
102
+ # as the one that triggered the failure.
103
+ Kernel.srand config.seed
104
+ =end
105
+ end
metadata ADDED
@@ -0,0 +1,121 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ddr-ingesttools
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0.rc1
5
+ platform: ruby
6
+ authors:
7
+ - Jim Coble
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-03-07 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bagit
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '0.4'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '0.4'
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.14'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.14'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '12.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '12.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '3.0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '3.0'
69
+ description: A collection of Ruby tools supporting ingest into the Duke Digital Repository.
70
+ email:
71
+ - jim.coble@duke.edu
72
+ executables:
73
+ - convert_dpc_folder.rb
74
+ extensions: []
75
+ extra_rdoc_files: []
76
+ files:
77
+ - ".gitignore"
78
+ - ".rspec"
79
+ - ".ruby-version"
80
+ - ".travis.yml"
81
+ - Gemfile
82
+ - LICENSE.txt
83
+ - README.md
84
+ - Rakefile
85
+ - bin/convert_dpc_folder.rb
86
+ - ddr-ingesttools.gemspec
87
+ - lib/ddr/ingesttools.rb
88
+ - lib/ddr/ingesttools/dpc_folder_converter.rb
89
+ - lib/ddr/ingesttools/dpc_folder_converter/converter.rb
90
+ - lib/ddr/ingesttools/version.rb
91
+ - spec/fixtures/files/manifest-sha1.txt
92
+ - spec/integration/dpc_folder_converter_spec.rb
93
+ - spec/spec_helper.rb
94
+ homepage: https://github.com/duke-libraries/ddr-ingesttools
95
+ licenses:
96
+ - BSD-3-Clause
97
+ metadata: {}
98
+ post_install_message:
99
+ rdoc_options: []
100
+ require_paths:
101
+ - lib
102
+ required_ruby_version: !ruby/object:Gem::Requirement
103
+ requirements:
104
+ - - ">="
105
+ - !ruby/object:Gem::Version
106
+ version: '0'
107
+ required_rubygems_version: !ruby/object:Gem::Requirement
108
+ requirements:
109
+ - - ">"
110
+ - !ruby/object:Gem::Version
111
+ version: 1.3.1
112
+ requirements: []
113
+ rubyforge_project:
114
+ rubygems_version: 2.5.1
115
+ signing_key:
116
+ specification_version: 4
117
+ summary: Ruby tools supporting ingest into the Duke Digital Repository.
118
+ test_files:
119
+ - spec/fixtures/files/manifest-sha1.txt
120
+ - spec/integration/dpc_folder_converter_spec.rb
121
+ - spec/spec_helper.rb