druid-tools 0.2.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. data/.gitignore +16 -0
  2. data/.rvmrc +1 -0
  3. data/Gemfile +4 -0
  4. data/LICENSE +20 -0
  5. data/README.md +80 -0
  6. data/Rakefile +7 -0
  7. data/VERSION +1 -0
  8. data/doc/classes/DruidTools.html +132 -0
  9. data/doc/classes/DruidTools/DifferentContentExistsError.html +111 -0
  10. data/doc/classes/DruidTools/Druid.html +352 -0
  11. data/doc/classes/DruidTools/Druid.src/M000001.html +18 -0
  12. data/doc/classes/DruidTools/Druid.src/M000002.html +18 -0
  13. data/doc/classes/DruidTools/Druid.src/M000003.html +18 -0
  14. data/doc/classes/DruidTools/Druid.src/M000004.html +24 -0
  15. data/doc/classes/DruidTools/Druid.src/M000005.html +18 -0
  16. data/doc/classes/DruidTools/Druid.src/M000006.html +18 -0
  17. data/doc/classes/DruidTools/Druid.src/M000007.html +20 -0
  18. data/doc/classes/DruidTools/Druid.src/M000008.html +25 -0
  19. data/doc/classes/DruidTools/Druid.src/M000009.html +20 -0
  20. data/doc/classes/DruidTools/Druid.src/M000010.html +27 -0
  21. data/doc/classes/DruidTools/Druid.src/M000011.html +24 -0
  22. data/doc/classes/DruidTools/Druid.src/M000012.html +29 -0
  23. data/doc/classes/DruidTools/InvalidDruidError.html +111 -0
  24. data/doc/classes/DruidTools/SameContentExistsError.html +111 -0
  25. data/doc/created.rid +1 -0
  26. data/doc/files/lib/druid-tools_rb.html +108 -0
  27. data/doc/files/lib/druid_tools/druid_rb.html +108 -0
  28. data/doc/files/lib/druid_tools/exceptions_rb.html +101 -0
  29. data/doc/files/lib/druid_tools/version_rb.html +101 -0
  30. data/doc/files/lib/druid_tools_rb.html +110 -0
  31. data/doc/files/spec/druid_tools_spec_rb.html +115 -0
  32. data/doc/files/spec/spec_helper_rb.html +114 -0
  33. data/doc/fr_class_index.html +28 -0
  34. data/doc/fr_file_index.html +30 -0
  35. data/doc/fr_method_index.html +38 -0
  36. data/doc/index.html +24 -0
  37. data/doc/rdoc-style.css +208 -0
  38. data/druid-tools.gemspec +21 -0
  39. data/lib/druid-tools.rb +1 -0
  40. data/lib/druid_tools.rb +5 -0
  41. data/lib/druid_tools/druid.rb +127 -0
  42. data/lib/druid_tools/exceptions.rb +5 -0
  43. data/lib/druid_tools/version.rb +3 -0
  44. data/spec/druid_tools_spec.rb +255 -0
  45. data/spec/spec_helper.rb +3 -0
  46. metadata +133 -0
@@ -0,0 +1,21 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |gem|
4
+ gem.authors = ['Michael Klein', 'Darren Hardy']
5
+ gem.email = ['mbklein@stanford.edu']
6
+ gem.description = 'Tools to manipulate DRUID trees and content directories'
7
+ gem.summary = 'Tools to manipulate DRUID trees and content directories'
8
+ gem.homepage = 'http://github.com/sul-dlss/druid-tools'
9
+ gem.licenses = ['ALv2', 'Stanford University Libraries']
10
+ gem.has_rdoc = true
11
+
12
+ gem.files = `git ls-files`.split($\)
13
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
14
+ gem.test_files = gem.files.grep(%r{^spec/})
15
+ gem.name = 'druid-tools'
16
+ gem.require_paths = ['lib']
17
+ gem.version = File.read('VERSION').strip
18
+
19
+ gem.add_development_dependency 'rake', '>= 10.1.0'
20
+ gem.add_development_dependency 'rspec', '>= 2.14.0'
21
+ end
@@ -0,0 +1 @@
1
+ require 'druid_tools'
@@ -0,0 +1,5 @@
1
+ module DruidTools
2
+ require 'druid_tools/version'
3
+ require 'druid_tools/druid'
4
+ require 'druid_tools/exceptions'
5
+ end
@@ -0,0 +1,127 @@
1
+ require 'pathname'
2
+
3
+ module DruidTools
4
+ class Druid
5
+ attr_accessor :druid, :base
6
+
7
+ class << self
8
+ attr_accessor :prefix
9
+
10
+ # @return [Regexp] matches druid:aa111aa1111 or aa111aa1111
11
+ def pattern
12
+ /\A(?:#{self.prefix}:)?([a-z]{2})(\d{3})([a-z]{2})(\d{4})\z/
13
+ end
14
+
15
+ # @return [String] suitable for use in [Dir#glob]
16
+ def glob
17
+ "{#{self.prefix}:,}[a-z][a-z][0-9][0-9][0-9][a-z][a-z][0-9][0-9][0-9][0-9]"
18
+ end
19
+
20
+ # @param [String] druid id
21
+ # @return [Boolean] true if druid matches pattern; otherwise false
22
+ def valid?(druid)
23
+ return druid =~ pattern ? true : false
24
+ end
25
+
26
+ end
27
+ self.prefix = 'druid'
28
+
29
+ [:content, :metadata, :temp].each do |dir_type|
30
+ self.class_eval <<-EOC
31
+ def #{dir_type}_dir(create=true)
32
+ path("#{dir_type}",create)
33
+ end
34
+
35
+ def find_#{dir_type}(path)
36
+ find(:#{dir_type},path)
37
+ end
38
+ EOC
39
+ end
40
+
41
+ # @param druid [String] A valid druid
42
+ # @param base [String] The directory used by #path
43
+ def initialize(druid, base='.')
44
+ druid = druid.to_s unless druid.is_a? String
45
+ unless self.class.valid?(druid)
46
+ raise ArgumentError, "Invalid DRUID: '#{druid}'"
47
+ end
48
+ druid = [self.class.prefix,druid].join(':') unless druid =~ /^#{self.class.prefix}:/
49
+ @base = base
50
+ @druid = druid
51
+ end
52
+
53
+ def id
54
+ @druid.scan(self.class.pattern).flatten.join('')
55
+ end
56
+
57
+ def tree
58
+ @druid.scan(self.class.pattern).flatten + [id]
59
+ end
60
+
61
+ def path(extra=nil, create=false)
62
+ result = File.join(*([base,tree,extra].compact))
63
+ mkdir(extra) if create and not File.exists?(result)
64
+ result
65
+ end
66
+
67
+ def mkdir(extra=nil)
68
+ new_path = path(extra)
69
+ if(File.symlink? new_path)
70
+ raise DruidTools::DifferentContentExistsError, "Unable to create directory, link already exists: #{new_path}"
71
+ end
72
+ if(File.directory? new_path)
73
+ raise DruidTools::SameContentExistsError, "The directory already exists: #{new_path}"
74
+ end
75
+ FileUtils.mkdir_p(new_path)
76
+ end
77
+
78
+ def find(type, path)
79
+ possibles = [self.path(type.to_s),self.path,File.expand_path('..',self.path)]
80
+ loc = possibles.find { |p| File.exists?(File.join(p,path)) }
81
+ loc.nil? ? nil : File.join(loc,path)
82
+ end
83
+
84
+ # @param [String] type The type of directory being sought ('content', 'metadata', or 'temp')
85
+ # @param [Array<String>,String] filelist The files that are expected to be present in the directory
86
+ # @return [Pathname] Search for and return the pathname of the directory that contains the list of files.
87
+ # Raises an exception unless a directory is found that contains all the files in the list.
88
+ def find_filelist_parent(type, filelist)
89
+ raise "File list not specified" if filelist.nil? or filelist.empty?
90
+ filelist = [filelist] unless filelist.is_a?(Array)
91
+ search_dir = Pathname(self.path(type))
92
+ directories = [search_dir, search_dir.parent, search_dir.parent.parent]
93
+ found_dir = directories.find { |pathname| pathname.join(filelist[0]).exist? }
94
+ raise "#{type} dir not found for '#{filelist[0]}' when searching '#{search_dir}'" if found_dir.nil?
95
+ filelist.each do |filename|
96
+ raise "File '#{filename}' not found in #{type} dir s'#{found_dir}'" unless found_dir.join(filename).exist?
97
+ end
98
+ found_dir
99
+ end
100
+
101
+ def mkdir_with_final_link(source, extra=nil)
102
+ new_path = path(extra)
103
+ if(File.directory?(new_path) && !File.symlink?(new_path))
104
+ raise DruidTools::DifferentContentExistsError, "Unable to create link, directory already exists: #{new_path}"
105
+ end
106
+ real_path = File.expand_path('..',new_path)
107
+ FileUtils.mkdir_p(real_path)
108
+ FileUtils.ln_s(source, new_path, :force=>true)
109
+ end
110
+
111
+ def rmdir(extra=nil)
112
+ parts = tree
113
+ parts << extra unless extra.nil?
114
+ while parts.length > 0
115
+ dir = File.join(base, *parts)
116
+ begin
117
+ FileUtils.rm(File.join(dir,'.DS_Store'), :force => true)
118
+ FileUtils.rmdir(dir)
119
+ rescue Errno::ENOTEMPTY
120
+ break
121
+ end
122
+ parts.pop
123
+ end
124
+ end
125
+
126
+ end
127
+ end
@@ -0,0 +1,5 @@
1
+ module DruidTools
2
+ class SameContentExistsError < Exception; end
3
+ class DifferentContentExistsError < Exception; end
4
+ class InvalidDruidError < Exception; end
5
+ end
@@ -0,0 +1,3 @@
1
+ module DruidTools
2
+ VERSION = File.read(File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'VERSION'))).to_s.strip
3
+ end
@@ -0,0 +1,255 @@
1
+ #require File.expand_path('../spec_helper',__FILE__)
2
+ #puts $LOAD_PATH.join("\n")
3
+ require 'druid-tools'
4
+
5
+ describe DruidTools::Druid do
6
+ before (:all) do
7
+ @fixture_dir = File.expand_path("../fixtures",__FILE__)
8
+ FileUtils.rm_rf(File.join(@fixture_dir,'cd'))
9
+ @druid_1 = 'druid:cd456ef7890'
10
+ @tree_1 = File.join(@fixture_dir,'cd/456/ef/7890/cd456ef7890')
11
+ @druid_2 = 'druid:cd456gh1234'
12
+ @tree_2 = File.join(@fixture_dir,'cd/456/gh/1234/cd456gh1234')
13
+ end
14
+
15
+ after(:each) do
16
+ FileUtils.rm_rf(File.join(@fixture_dir,'cd'))
17
+ end
18
+
19
+ it "should be able to validate druid strings using the valid? class method" do
20
+ tests = [
21
+ # Expected Input druid
22
+ [true, 'druid:aa000bb0001'],
23
+ [true, 'aa000bb0001'],
24
+ [false, 'Aa000bb0001'],
25
+ [false, "xxx\naa000bb0001"],
26
+ [false, 'aaa000bb0001'],
27
+ [false, 'druidX:aa000bb0001'],
28
+ [false, ':aa000bb0001'],
29
+ [true, 'aa123bb1234'],
30
+ [false, 'aa12bb1234'],
31
+ [false, 'aa1234bb1234'],
32
+ [false, 'aa123bb123'],
33
+ [false, 'aa123bb12345'],
34
+ [false, 'a123bb1234'],
35
+ [false, 'aaa123bb1234'],
36
+ [false, 'aa123b1234'],
37
+ [false, 'aa123bbb1234'],
38
+ [false, 'druid:az918AZ9381'.upcase],
39
+ [true, 'druid:az918AZ9381'.downcase],
40
+ [true, 'druid:zz943vx1492']
41
+ ]
42
+ tests.each do |exp, dru|
43
+ DruidTools::Druid.valid?(dru).should == exp
44
+ end
45
+ end
46
+
47
+ it "should provide the full druid including the prefix" do
48
+ DruidTools::Druid.new('druid:cd456ef7890',@fixture_dir).druid.should == 'druid:cd456ef7890'
49
+ DruidTools::Druid.new('cd456ef7890',@fixture_dir).druid.should == 'druid:cd456ef7890'
50
+ end
51
+
52
+ it "should extract the ID from the stem" do
53
+ DruidTools::Druid.new('druid:cd456ef7890',@fixture_dir).id.should == 'cd456ef7890'
54
+ DruidTools::Druid.new('cd456ef7890',@fixture_dir).id.should == 'cd456ef7890'
55
+ end
56
+
57
+ it "should raise an exception if the druid is invalid" do
58
+ lambda { DruidTools::Druid.new('nondruid:cd456ef7890',@fixture_dir) }.should raise_error(ArgumentError)
59
+ lambda { DruidTools::Druid.new('druid:cd4567ef890',@fixture_dir) }.should raise_error(ArgumentError)
60
+ end
61
+
62
+ it "should build a druid tree from a druid" do
63
+ druid = DruidTools::Druid.new(@druid_1,@fixture_dir)
64
+ druid.tree.should == ['cd','456','ef','7890','cd456ef7890']
65
+ druid.path.should == @tree_1
66
+ end
67
+
68
+ it "should create and destroy druid directories" do
69
+ File.exists?(@tree_1).should be_false
70
+ File.exists?(@tree_2).should be_false
71
+
72
+ druid_1 = DruidTools::Druid.new(@druid_1,@fixture_dir)
73
+ druid_2 = DruidTools::Druid.new(@druid_2,@fixture_dir)
74
+
75
+ druid_1.mkdir
76
+ File.exists?(@tree_1).should be_true
77
+ File.exists?(@tree_2).should be_false
78
+
79
+ druid_2.mkdir
80
+ File.exists?(@tree_1).should be_true
81
+ File.exists?(@tree_2).should be_true
82
+
83
+ druid_2.rmdir
84
+ File.exists?(@tree_1).should be_true
85
+ File.exists?(@tree_2).should be_false
86
+
87
+ druid_1.rmdir
88
+ File.exists?(@tree_1).should be_false
89
+ File.exists?(@tree_2).should be_false
90
+ File.exists?(File.join(@fixture_dir,'cd')).should be_false
91
+ end
92
+
93
+ describe "alternate prefixes" do
94
+ before :all do
95
+ DruidTools::Druid.prefix = 'sulair'
96
+ end
97
+
98
+ after :all do
99
+ DruidTools::Druid.prefix = 'druid'
100
+ end
101
+
102
+ it "should handle alternate prefixes" do
103
+ lambda { DruidTools::Druid.new('druid:cd456ef7890',@fixture_dir) }.should raise_error(ArgumentError)
104
+ DruidTools::Druid.new('sulair:cd456ef7890',@fixture_dir).id.should == 'cd456ef7890'
105
+ DruidTools::Druid.new('cd456ef7890',@fixture_dir).druid.should == 'sulair:cd456ef7890'
106
+ end
107
+ end
108
+
109
+ describe "content directories" do
110
+ it "should know where its content goes" do
111
+ druid = DruidTools::Druid.new(@druid_1,@fixture_dir)
112
+ druid.content_dir(false).should == File.join(@tree_1,'content')
113
+ druid.metadata_dir(false).should == File.join(@tree_1,'metadata')
114
+ druid.temp_dir(false).should == File.join(@tree_1,'temp')
115
+
116
+ File.exists?(File.join(@tree_1,'content')).should be_false
117
+ File.exists?(File.join(@tree_1,'metadata')).should be_false
118
+ File.exists?(File.join(@tree_1,'temp')).should be_false
119
+ end
120
+
121
+ it "should create its content directories on the fly" do
122
+ druid = DruidTools::Druid.new(@druid_1,@fixture_dir)
123
+ druid.content_dir.should == File.join(@tree_1,'content')
124
+ druid.metadata_dir.should == File.join(@tree_1,'metadata')
125
+ druid.temp_dir.should == File.join(@tree_1,'temp')
126
+
127
+ File.exists?(File.join(@tree_1,'content')).should be_true
128
+ File.exists?(File.join(@tree_1,'metadata')).should be_true
129
+ File.exists?(File.join(@tree_1,'temp')).should be_true
130
+ end
131
+
132
+ it "should match glob" do
133
+ druid = DruidTools::Druid.new(@druid_1,@fixture_dir)
134
+ druid.mkdir
135
+ Dir.glob(File.join(File.dirname(druid.path), DruidTools::Druid::glob)).size.should == 1
136
+ end
137
+ end
138
+
139
+ describe "content discovery" do
140
+ before :all do
141
+ @druid = DruidTools::Druid.new(@druid_1,@fixture_dir)
142
+ @filelist = %w(1 2 3 4).collect { |num| "someFile#{num}" }
143
+ end
144
+
145
+ it "should find content in content directories" do
146
+ location = @druid.content_dir
147
+ File.open(File.join(location,'someContent'),'w') { |f| f.write 'This is the content' }
148
+ @druid.find_content('someContent').should == File.join(location,'someContent')
149
+ end
150
+
151
+ it "should find content in the root directory" do
152
+ location = @druid.path(nil,true)
153
+ File.open(File.join(location,'someContent'),'w') { |f| f.write 'This is the content' }
154
+ @druid.find_content('someContent').should == File.join(location,'someContent')
155
+ end
156
+
157
+ it "should find content in the leaf directory" do
158
+ location = File.expand_path('..',@druid.path(nil,true))
159
+ File.open(File.join(location,'someContent'),'w') { |f| f.write 'This is the content' }
160
+ @druid.find_content('someContent').should == File.join(location,'someContent')
161
+ end
162
+
163
+ it "should not find content in the wrong content directory" do
164
+ location = @druid.metadata_dir
165
+ File.open(File.join(location,'someContent'),'w') { |f| f.write 'This is the content' }
166
+ @druid.find_content('someContent').should be_nil
167
+ end
168
+
169
+ it "should not find content in a higher-up directory" do
170
+ location = File.expand_path('../..',@druid.path(nil,true))
171
+ File.open(File.join(location,'someContent'),'w') { |f| f.write 'This is the content' }
172
+ @druid.find_content('someContent').should be_nil
173
+ end
174
+
175
+ it "should find a filelist in the content directory" do
176
+ location = Pathname(@druid.content_dir)
177
+ @filelist.each do |filename|
178
+ location.join(filename).open('w') { |f| f.write "This is #{filename}" }
179
+ end
180
+ @druid.find_filelist_parent('content',@filelist).should == location
181
+ end
182
+
183
+ it "should find a filelist in the root directory" do
184
+ location = Pathname(@druid.path(nil,true))
185
+ @filelist.each do |filename|
186
+ location.join(filename).open('w') { |f| f.write "This is #{filename}" }
187
+ end
188
+ @druid.find_filelist_parent('content',@filelist).should == location
189
+ end
190
+
191
+ it "should find a filelist in the leaf directory" do
192
+ location = Pathname(File.expand_path('..',@druid.path(nil,true)))
193
+ @filelist.each do |filename|
194
+ location.join(filename).open('w') { |f| f.write "This is #{filename}" }
195
+ end
196
+ @druid.find_filelist_parent('content',@filelist).should == location
197
+ end
198
+
199
+ it "should raise an exception if the first file in the filelist is not found" do
200
+ location = Pathname(@druid.content_dir)
201
+ lambda{@druid.find_filelist_parent('content',@filelist)}.should raise_exception(/content dir not found for 'someFile1' when searching/)
202
+ end
203
+
204
+ it "should raise an exception if any other file in the filelist is not found" do
205
+ location = Pathname(@druid.content_dir)
206
+ location.join(@filelist.first).open('w') { |f| f.write "This is #{@filelist.first}" }
207
+ lambda{@druid.find_filelist_parent('content',@filelist)}.should raise_exception(/File 'someFile2' not found/)
208
+ end
209
+
210
+ end
211
+
212
+ describe "#mkdir error handling" do
213
+ it "raises SameContentExistsError if the directory already exists" do
214
+ druid_2 = DruidTools::Druid.new(@druid_2,@fixture_dir)
215
+ druid_2.mkdir
216
+ lambda { druid_2.mkdir }.should raise_error(DruidTools::SameContentExistsError)
217
+ end
218
+
219
+ it "raises DifferentContentExistsError if a link already exists in the workspace for this druid" do
220
+ source_dir = '/tmp/content_dir'
221
+ FileUtils.mkdir_p(source_dir)
222
+ dr = DruidTools::Druid.new(@druid_2,@fixture_dir)
223
+ dr.mkdir_with_final_link(source_dir)
224
+ lambda { dr.mkdir }.should raise_error(DruidTools::DifferentContentExistsError)
225
+ end
226
+ end
227
+
228
+ describe "#mkdir_with_final_link" do
229
+
230
+ before(:each) do
231
+ @source_dir = '/tmp/content_dir'
232
+ FileUtils.mkdir_p(@source_dir)
233
+ @dr = DruidTools::Druid.new(@druid_2,@fixture_dir)
234
+ end
235
+
236
+ it "creates a druid tree in the workspace with the final directory being a link to the passed in source" do
237
+ @dr.mkdir_with_final_link(@source_dir)
238
+
239
+ File.should be_symlink(@dr.path)
240
+ File.readlink(@tree_2).should == @source_dir
241
+ end
242
+
243
+ it "should not error out if the link to source already exists" do
244
+ @dr.mkdir_with_final_link(@source_dir)
245
+ File.should be_symlink(@dr.path)
246
+ File.readlink(@tree_2).should == @source_dir
247
+ end
248
+
249
+ it "raises DifferentContentExistsError if a directory already exists in the workspace for this druid" do
250
+ @dr.mkdir(@fixture_dir)
251
+ lambda { @dr.mkdir_with_final_link(@source_di) }.should raise_error(DruidTools::DifferentContentExistsError)
252
+ end
253
+ end
254
+
255
+ end
@@ -0,0 +1,3 @@
1
+ #$LOAD_PATH.unshift(File.expand_path('../../lib',__FILE__))
2
+
3
+ require 'bundler/setup'
metadata ADDED
@@ -0,0 +1,133 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: druid-tools
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.6
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Michael Klein
9
+ - Darren Hardy
10
+ autorequire:
11
+ bindir: bin
12
+ cert_chain: []
13
+ date: 2013-10-15 00:00:00.000000000 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: rake
17
+ requirement: !ruby/object:Gem::Requirement
18
+ none: false
19
+ requirements:
20
+ - - ! '>='
21
+ - !ruby/object:Gem::Version
22
+ version: 10.1.0
23
+ type: :development
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ none: false
27
+ requirements:
28
+ - - ! '>='
29
+ - !ruby/object:Gem::Version
30
+ version: 10.1.0
31
+ - !ruby/object:Gem::Dependency
32
+ name: rspec
33
+ requirement: !ruby/object:Gem::Requirement
34
+ none: false
35
+ requirements:
36
+ - - ! '>='
37
+ - !ruby/object:Gem::Version
38
+ version: 2.14.0
39
+ type: :development
40
+ prerelease: false
41
+ version_requirements: !ruby/object:Gem::Requirement
42
+ none: false
43
+ requirements:
44
+ - - ! '>='
45
+ - !ruby/object:Gem::Version
46
+ version: 2.14.0
47
+ description: Tools to manipulate DRUID trees and content directories
48
+ email:
49
+ - mbklein@stanford.edu
50
+ executables: []
51
+ extensions: []
52
+ extra_rdoc_files: []
53
+ files:
54
+ - .gitignore
55
+ - .rvmrc
56
+ - Gemfile
57
+ - LICENSE
58
+ - README.md
59
+ - Rakefile
60
+ - VERSION
61
+ - doc/classes/DruidTools.html
62
+ - doc/classes/DruidTools/DifferentContentExistsError.html
63
+ - doc/classes/DruidTools/Druid.html
64
+ - doc/classes/DruidTools/Druid.src/M000001.html
65
+ - doc/classes/DruidTools/Druid.src/M000002.html
66
+ - doc/classes/DruidTools/Druid.src/M000003.html
67
+ - doc/classes/DruidTools/Druid.src/M000004.html
68
+ - doc/classes/DruidTools/Druid.src/M000005.html
69
+ - doc/classes/DruidTools/Druid.src/M000006.html
70
+ - doc/classes/DruidTools/Druid.src/M000007.html
71
+ - doc/classes/DruidTools/Druid.src/M000008.html
72
+ - doc/classes/DruidTools/Druid.src/M000009.html
73
+ - doc/classes/DruidTools/Druid.src/M000010.html
74
+ - doc/classes/DruidTools/Druid.src/M000011.html
75
+ - doc/classes/DruidTools/Druid.src/M000012.html
76
+ - doc/classes/DruidTools/InvalidDruidError.html
77
+ - doc/classes/DruidTools/SameContentExistsError.html
78
+ - doc/created.rid
79
+ - doc/files/lib/druid-tools_rb.html
80
+ - doc/files/lib/druid_tools/druid_rb.html
81
+ - doc/files/lib/druid_tools/exceptions_rb.html
82
+ - doc/files/lib/druid_tools/version_rb.html
83
+ - doc/files/lib/druid_tools_rb.html
84
+ - doc/files/spec/druid_tools_spec_rb.html
85
+ - doc/files/spec/spec_helper_rb.html
86
+ - doc/fr_class_index.html
87
+ - doc/fr_file_index.html
88
+ - doc/fr_method_index.html
89
+ - doc/index.html
90
+ - doc/rdoc-style.css
91
+ - druid-tools.gemspec
92
+ - lib/druid-tools.rb
93
+ - lib/druid_tools.rb
94
+ - lib/druid_tools/druid.rb
95
+ - lib/druid_tools/exceptions.rb
96
+ - lib/druid_tools/version.rb
97
+ - spec/druid_tools_spec.rb
98
+ - spec/spec_helper.rb
99
+ homepage: http://github.com/sul-dlss/druid-tools
100
+ licenses:
101
+ - ALv2
102
+ - Stanford University Libraries
103
+ post_install_message:
104
+ rdoc_options: []
105
+ require_paths:
106
+ - lib
107
+ required_ruby_version: !ruby/object:Gem::Requirement
108
+ none: false
109
+ requirements:
110
+ - - ! '>='
111
+ - !ruby/object:Gem::Version
112
+ version: '0'
113
+ segments:
114
+ - 0
115
+ hash: -3564401623141727809
116
+ required_rubygems_version: !ruby/object:Gem::Requirement
117
+ none: false
118
+ requirements:
119
+ - - ! '>='
120
+ - !ruby/object:Gem::Version
121
+ version: '0'
122
+ segments:
123
+ - 0
124
+ hash: -3564401623141727809
125
+ requirements: []
126
+ rubyforge_project:
127
+ rubygems_version: 1.8.23
128
+ signing_key:
129
+ specification_version: 3
130
+ summary: Tools to manipulate DRUID trees and content directories
131
+ test_files:
132
+ - spec/druid_tools_spec.rb
133
+ - spec/spec_helper.rb