valkyrie 0.0.0 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (103) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -3
  3. data/.rubocop.yml +28 -0
  4. data/Gemfile +6 -1
  5. data/README.md +145 -10
  6. data/Rakefile +59 -1
  7. data/bin/console +1 -1
  8. data/config/valkyrie.yml +8 -0
  9. data/db/config.yml +17 -0
  10. data/db/migrate/20160111215816_enable_uuid_extension.rb +6 -0
  11. data/db/migrate/20161007101725_create_orm_resources.rb +10 -0
  12. data/db/migrate/20170124135846_add_model_type_to_orm_resources.rb +6 -0
  13. data/db/migrate/20170531004548_change_model_type_to_internal_model.rb +6 -0
  14. data/db/schema.rb +65 -0
  15. data/db/seeds.rb +8 -0
  16. data/lib/config/database_connection.rb +15 -0
  17. data/lib/generators/valkyrie/resource_generator.rb +27 -0
  18. data/lib/generators/valkyrie/templates/resource.rb.erb +9 -0
  19. data/lib/generators/valkyrie/templates/resource_spec.rb.erb +13 -0
  20. data/lib/valkyrie.rb +76 -1
  21. data/lib/valkyrie/adapter_container.rb +12 -0
  22. data/lib/valkyrie/change_set.rb +84 -0
  23. data/lib/valkyrie/decorators/decorator_list.rb +15 -0
  24. data/lib/valkyrie/decorators/decorator_with_arguments.rb +14 -0
  25. data/lib/valkyrie/derivative_service.rb +42 -0
  26. data/lib/valkyrie/engine.rb +10 -0
  27. data/lib/valkyrie/file_characterization_service.rb +42 -0
  28. data/lib/valkyrie/id.rb +32 -0
  29. data/lib/valkyrie/indexers/access_controls_indexer.rb +19 -0
  30. data/lib/valkyrie/local_file_service.rb +11 -0
  31. data/lib/valkyrie/metadata_adapter.rb +22 -0
  32. data/lib/valkyrie/persist_derivatives.rb +29 -0
  33. data/lib/valkyrie/persistence.rb +14 -0
  34. data/lib/valkyrie/persistence/buffered_persister.rb +28 -0
  35. data/lib/valkyrie/persistence/composite_persister.rb +29 -0
  36. data/lib/valkyrie/persistence/delete_tracking_buffer.rb +21 -0
  37. data/lib/valkyrie/persistence/fedora.rb +11 -0
  38. data/lib/valkyrie/persistence/fedora/list_node.rb +88 -0
  39. data/lib/valkyrie/persistence/fedora/metadata_adapter.rb +45 -0
  40. data/lib/valkyrie/persistence/fedora/ordered_list.rb +146 -0
  41. data/lib/valkyrie/persistence/fedora/ordered_reader.rb +28 -0
  42. data/lib/valkyrie/persistence/fedora/persister.rb +47 -0
  43. data/lib/valkyrie/persistence/fedora/persister/model_converter.rb +199 -0
  44. data/lib/valkyrie/persistence/fedora/persister/orm_converter.rb +338 -0
  45. data/lib/valkyrie/persistence/fedora/persister/resource_factory.rb +21 -0
  46. data/lib/valkyrie/persistence/fedora/query_service.rb +80 -0
  47. data/lib/valkyrie/persistence/memory.rb +8 -0
  48. data/lib/valkyrie/persistence/memory/metadata_adapter.rb +22 -0
  49. data/lib/valkyrie/persistence/memory/persister.rb +58 -0
  50. data/lib/valkyrie/persistence/memory/query_service.rb +86 -0
  51. data/lib/valkyrie/persistence/postgres.rb +6 -0
  52. data/lib/valkyrie/persistence/postgres/metadata_adapter.rb +20 -0
  53. data/lib/valkyrie/persistence/postgres/orm.rb +9 -0
  54. data/lib/valkyrie/persistence/postgres/orm/resource.rb +7 -0
  55. data/lib/valkyrie/persistence/postgres/orm_converter.rb +118 -0
  56. data/lib/valkyrie/persistence/postgres/persister.rb +33 -0
  57. data/lib/valkyrie/persistence/postgres/queries.rb +8 -0
  58. data/lib/valkyrie/persistence/postgres/queries/find_inverse_references_query.rb +31 -0
  59. data/lib/valkyrie/persistence/postgres/queries/find_members_query.rb +33 -0
  60. data/lib/valkyrie/persistence/postgres/queries/find_references_query.rb +33 -0
  61. data/lib/valkyrie/persistence/postgres/query_service.rb +53 -0
  62. data/lib/valkyrie/persistence/postgres/resource_converter.rb +18 -0
  63. data/lib/valkyrie/persistence/postgres/resource_factory.rb +30 -0
  64. data/lib/valkyrie/persistence/solr.rb +6 -0
  65. data/lib/valkyrie/persistence/solr/metadata_adapter.rb +42 -0
  66. data/lib/valkyrie/persistence/solr/model_converter.rb +270 -0
  67. data/lib/valkyrie/persistence/solr/orm_converter.rb +252 -0
  68. data/lib/valkyrie/persistence/solr/persister.rb +32 -0
  69. data/lib/valkyrie/persistence/solr/queries.rb +11 -0
  70. data/lib/valkyrie/persistence/solr/queries/default_paginator.rb +16 -0
  71. data/lib/valkyrie/persistence/solr/queries/find_all_query.rb +33 -0
  72. data/lib/valkyrie/persistence/solr/queries/find_by_id_query.rb +24 -0
  73. data/lib/valkyrie/persistence/solr/queries/find_inverse_references_query.rb +30 -0
  74. data/lib/valkyrie/persistence/solr/queries/find_members_query.rb +43 -0
  75. data/lib/valkyrie/persistence/solr/queries/find_references_query.rb +34 -0
  76. data/lib/valkyrie/persistence/solr/query_service.rb +48 -0
  77. data/lib/valkyrie/persistence/solr/repository.rb +36 -0
  78. data/lib/valkyrie/persistence/solr/resource_factory.rb +24 -0
  79. data/lib/valkyrie/rdf_patches.rb +17 -0
  80. data/lib/valkyrie/resource.rb +106 -0
  81. data/lib/valkyrie/resource/access_controls.rb +13 -0
  82. data/lib/valkyrie/specs/shared_specs.rb +10 -0
  83. data/lib/valkyrie/specs/shared_specs/change_set_persister.rb +60 -0
  84. data/lib/valkyrie/specs/shared_specs/derivative_service.rb +30 -0
  85. data/lib/valkyrie/specs/shared_specs/file.rb +12 -0
  86. data/lib/valkyrie/specs/shared_specs/file_characterization_service.rb +33 -0
  87. data/lib/valkyrie/specs/shared_specs/metadata_adapter.rb +10 -0
  88. data/lib/valkyrie/specs/shared_specs/persister.rb +154 -0
  89. data/lib/valkyrie/specs/shared_specs/queries.rb +128 -0
  90. data/lib/valkyrie/specs/shared_specs/resource.rb +71 -0
  91. data/lib/valkyrie/specs/shared_specs/storage_adapter.rb +44 -0
  92. data/lib/valkyrie/storage.rb +8 -0
  93. data/lib/valkyrie/storage/disk.rb +55 -0
  94. data/lib/valkyrie/storage/fedora.rb +71 -0
  95. data/lib/valkyrie/storage/memory.rb +31 -0
  96. data/lib/valkyrie/storage_adapter.rb +100 -0
  97. data/lib/valkyrie/types.rb +34 -0
  98. data/lib/valkyrie/value_mapper.rb +67 -0
  99. data/lib/valkyrie/version.rb +2 -1
  100. data/lib/valkyrie/vocab/pcdm_use.rb +73 -0
  101. data/valkyrie.gemspec +33 -7
  102. metadata +462 -7
  103. data/.travis.yml +0 -5
@@ -0,0 +1,71 @@
1
+ # frozen_string_literal: true
2
+ module Valkyrie::Storage
3
+ class Fedora
4
+ attr_reader :connection
5
+ PROTOCOL = 'fedora://'
6
+ def initialize(connection:)
7
+ @connection = connection
8
+ end
9
+
10
+ # @param id [Valkyrie::ID]
11
+ # @return [Boolean] true if this adapter can handle this type of identifer
12
+ def handles?(id:)
13
+ id.to_s.start_with?(PROTOCOL)
14
+ end
15
+
16
+ # Return the file associated with the given identifier
17
+ # @param id [Valkyrie::ID]
18
+ # @return [Valkyrie::StorageAdapter::StreamFile]
19
+ def find_by(id:)
20
+ Valkyrie::StorageAdapter::StreamFile.new(id: id, io: response(id: id))
21
+ end
22
+
23
+ # @param file [IO]
24
+ # @param resource [Valkyrie::Resource]
25
+ # @return [Valkyrie::StorageAdapter::StreamFile]
26
+ def upload(file:, resource:)
27
+ # TODO: this is a very naive aproach. Change to PCDM
28
+ identifier = resource.id.to_uri + '/original'
29
+ ActiveFedora::File.new(identifier) do |af|
30
+ af.content = file
31
+ af.save!
32
+ af.metadata.set_value(:type, af.metadata.type + [::RDF::URI('http://pcdm.org/use#OriginalFile')])
33
+ af.metadata.save
34
+ end
35
+ find_by(id: Valkyrie::ID.new(identifier.to_s.sub(/^.+\/\//, PROTOCOL)))
36
+ end
37
+
38
+ class IOProxy
39
+ # @param response [Ldp::Resource::BinarySource]
40
+ attr_reader :size
41
+ def initialize(source, size)
42
+ @source = source
43
+ @size = size
44
+ end
45
+ delegate :each, :read, :rewind, to: :io
46
+
47
+ # There is no streaming support in faraday (https://github.com/lostisland/faraday/pull/604)
48
+ # @return [StringIO]
49
+ def io
50
+ @io ||= StringIO.new(@source.get.response.body)
51
+ end
52
+ end
53
+ private_constant :IOProxy
54
+
55
+ private
56
+
57
+ # @return [IOProxy]
58
+ def response(id:)
59
+ af_file = ActiveFedora::File.new(active_fedora_identifier(id: id))
60
+ IOProxy.new(af_file.ldp_source, af_file.size)
61
+ end
62
+
63
+ # Translate the Valkrie ID into a URL for the fedora file
64
+ # @return [RDF::URI]
65
+ def active_fedora_identifier(id:)
66
+ scheme = URI(ActiveFedora.config.credentials[:url]).scheme
67
+ identifier = id.to_s.sub(PROTOCOL, "#{scheme}://")
68
+ RDF::URI(identifier)
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+ module Valkyrie::Storage
3
+ class Memory
4
+ attr_reader :cache
5
+ def initialize
6
+ @cache = {}
7
+ end
8
+
9
+ # @param file [IO]
10
+ # @param resource [Valkyrie::Resource]
11
+ # @return [Valkyrie::StorageAdapter::StreamFile]
12
+ def upload(file:, resource: nil)
13
+ identifier = Valkyrie::ID.new("memory://#{resource.id}")
14
+ cache[identifier] = Valkyrie::StorageAdapter::StreamFile.new(id: identifier, io: file)
15
+ end
16
+
17
+ # Return the file associated with the given identifier
18
+ # @param id [Valkyrie::ID]
19
+ # @return [Valkyrie::StorageAdapter::StreamFile]
20
+ def find_by(id:)
21
+ return unless handles?(id: id) && cache[id]
22
+ cache[id]
23
+ end
24
+
25
+ # @param id [Valkyrie::ID]
26
+ # @return [Boolean] true if this adapter can handle this type of identifer
27
+ def handles?(id:)
28
+ id.to_s.start_with?("memory://")
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,100 @@
1
+ # frozen_string_literal: true
2
+ module Valkyrie
3
+ class StorageAdapter
4
+ class_attribute :storage_adapters
5
+ self.storage_adapters = {}
6
+ class << self
7
+ # Add a storage adapter to the registry under the provided short name
8
+ # @param storage_adapter [Valkyrie::StorageAdapter]
9
+ # @param short_name [Symbol]
10
+ # @return [void]
11
+ def register(storage_adapter, short_name)
12
+ storage_adapters[short_name] = storage_adapter
13
+ end
14
+
15
+ # @param short_name [Symbol]
16
+ # @return [void]
17
+ def unregister(short_name)
18
+ storage_adapters.delete(short_name)
19
+ end
20
+
21
+ # Find the adapter associated with the provided short name
22
+ # @param short_name [Symbol]
23
+ # @return [Valkyrie::StorageAdapter]
24
+ def find(short_name)
25
+ storage_adapters[short_name]
26
+ end
27
+
28
+ # Search through all registered storage adapters until it finds one that
29
+ # can handle the passed in identifier. The call find_by on that adapter
30
+ # with the given identifier.
31
+ # @param id [Valkyrie::ID]
32
+ # @return [Valkyrie::StorageAdapter::File]
33
+ def find_by(id:)
34
+ storage_adapters.values.find do |storage_adapter|
35
+ storage_adapter.handles?(id: id)
36
+ end.find_by(id: id)
37
+ end
38
+ end
39
+
40
+ class File < Dry::Struct
41
+ attribute :id, Valkyrie::Types::Any
42
+ attribute :io, Valkyrie::Types::Any
43
+ delegate :size, :read, :rewind, to: :io
44
+ def stream
45
+ io
46
+ end
47
+
48
+ def disk_path
49
+ Pathname.new(io.path)
50
+ end
51
+
52
+ # @param id [Valkyre::ID]
53
+ # @param digests [Array<Digest>]
54
+ # @return [Array<Digest>]
55
+ def checksum(digests:)
56
+ io.rewind
57
+ while (chunk = io.read(4096))
58
+ digests.each { |digest| digest.update(chunk) }
59
+ end
60
+
61
+ digests.map(&:to_s)
62
+ end
63
+
64
+ # @param id [Valkyre::ID]
65
+ # @param size [Integer]
66
+ # @param digests [Array<Digest>]
67
+ # @return [Boolean]
68
+ def valid?(size: nil, digests:)
69
+ return false if size && io.size.to_i != size.to_i
70
+ calc_digests = checksum(digests: digests.keys.map { |alg| Digest(alg.upcase).new })
71
+ return false unless digests.values == calc_digests
72
+
73
+ true
74
+ end
75
+ end
76
+
77
+ class StreamFile < File
78
+ def disk_path
79
+ Pathname.new(tmp_file.path)
80
+ end
81
+
82
+ private
83
+
84
+ def tmp_file_name
85
+ id.to_s.tr(':/', '__')
86
+ end
87
+
88
+ def tmp_file_path
89
+ ::File.join(Dir.tmpdir, tmp_file_name)
90
+ end
91
+
92
+ def tmp_file
93
+ @tmp_file ||= ::File.open(tmp_file_path, 'w+b') do |f|
94
+ IO.copy_stream(io, f)
95
+ f
96
+ end
97
+ end
98
+ end
99
+ end
100
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+ module Valkyrie
3
+ ##
4
+ # Namespace for Dry::Types types.
5
+ module Types
6
+ include Dry::Types.module
7
+ # Valkyrie::ID
8
+ ID = Dry::Types::Definition
9
+ .new(Valkyrie::ID)
10
+ .constructor do |input|
11
+ Valkyrie::ID.new(input)
12
+ end
13
+ # Used for casting {Valkyrie::Resources} if possible.
14
+ Anything = Valkyrie::Types::Any.constructor do |value|
15
+ if value.respond_to?(:fetch) && value.fetch(:internal_resource, nil)
16
+ value.fetch(:internal_resource).constantize.new(value)
17
+ else
18
+ value
19
+ end
20
+ end
21
+ # Represents an array of unique values.
22
+ Set = Valkyrie::Types::Coercible::Array.constructor do |value|
23
+ value.select(&:present?).uniq.map do |val|
24
+ Anything[val]
25
+ end
26
+ end.default([])
27
+ Array = Dry::Types['coercible.array'].default([])
28
+ # Used for when an input may be an array, but the output needs to be a
29
+ # single string.
30
+ SingleValuedString = Valkyrie::Types::String.constructor do |value|
31
+ ::Array.wrap(value).first.to_s
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,67 @@
1
+ # frozen_string_literal: true
2
+ module Valkyrie
3
+ ##
4
+ # ValueMapper is a way to handle coordinating extendable casting of values
5
+ # depending on what the value is. It's used in many of the adapters in
6
+ # Valkyrie.
7
+ #
8
+ # Typically a root node is defined as a sub-class ValueMapper to separate
9
+ # value mappers for a distinct purpose, but it's not a requirement.
10
+ #
11
+ # @example Defining a ValueMapper which converts symbols to strings.
12
+ # class ParentMapper < ValueMapper
13
+ # end
14
+ # class Stringify < ValueMapper
15
+ # ParentMapper.register(self)
16
+ # def self.handles?(value)
17
+ # value.kind_of?(Symbol)
18
+ # end
19
+ # def result
20
+ # value.to_s
21
+ # end
22
+ # end
23
+ # @example Use a ValueMapper
24
+ # ParentMapper.for(:symbol).result # => "symbol"
25
+ class ValueMapper
26
+ # Register a value caster.
27
+ # @param value_caster [Valkyrie::ValueMapper]
28
+ def self.register(value_caster)
29
+ self.value_casters += [value_caster]
30
+ end
31
+
32
+ # @return [Array<Valkyrie::ValueMapper>] Registered value casters.
33
+ def self.value_casters
34
+ @value_casters ||= []
35
+ end
36
+
37
+ class << self
38
+ attr_writer :value_casters
39
+ end
40
+
41
+ # Find the value caster for a given value.
42
+ # @param value [Anything] The value to find a caster for.
43
+ def self.for(value)
44
+ (value_casters + [self]).find do |value_caster|
45
+ value_caster.handles?(value)
46
+ end.new(value, self)
47
+ end
48
+
49
+ # Test whether this caster handles a given value.
50
+ # @param value [Anything]
51
+ # @return [Boolean]
52
+ def self.handles?(_value)
53
+ true
54
+ end
55
+
56
+ attr_reader :value, :calling_mapper
57
+ def initialize(value, calling_mapper)
58
+ @value = value
59
+ @calling_mapper = calling_mapper
60
+ end
61
+
62
+ # @return Casted value.
63
+ def result
64
+ value
65
+ end
66
+ end
67
+ end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module Valkyrie
2
- VERSION = "0.0.0"
3
+ VERSION = "0.1.0"
3
4
  end
@@ -0,0 +1,73 @@
1
+ # -*- encoding: utf-8 -*-
2
+ # frozen_string_literal: true
3
+ # This file generated automatically using rdf vocabulary format from http://pcdm.org/use#
4
+ require 'rdf'
5
+ module Valkyrie::Vocab
6
+ # @!parse
7
+ # # Vocabulary for <http://pcdm.org/use#>
8
+ # class PCDMUse < RDF::Vocabulary
9
+ # end
10
+ class PCDMUse < RDF::Vocabulary("http://pcdm.org/use#")
11
+ # Ontology definition
12
+ ontology :"http://pcdm.org/use#",
13
+ comment: %(Ontology for a PCDM extension to add subclasses of PCDM File for the
14
+ different roles files have in relation to the Object they are attached to.),
15
+ "dc:modified": %(2015-05-12),
16
+ "dc:publisher": %(http://www.duraspace.org/),
17
+ "dc:title": %(Portland Common Data Model: Use Extension),
18
+ "owl:versionInfo": %(2015/05/12),
19
+ "rdfs:seeAlso": [%(https://github.com/duraspace/pcdm/wiki), %(https://wiki.duraspace.org/display/hydra/File+Use+Vocabulary)]
20
+
21
+ # Class definitions
22
+ term :ExtractedText,
23
+ comment: %(A textual representation of the Object appropriate for fulltext indexing,
24
+ such as a plaintext version of a document, or OCR text.),
25
+ label: "extracted text",
26
+ "rdf:subClassOf": %(http://pcdm.org/resources#File),
27
+ "rdfs:isDefinedBy": %(pcdmuse:),
28
+ type: "rdfs:Class"
29
+ term :IntermediateFile,
30
+ comment: %(High quality representation of the Object, appropriate for generating
31
+ derivatives or other additional processing.),
32
+ label: "intermediate file",
33
+ "rdf:subClassOf": %(http://pcdm.org/resources#File),
34
+ "rdfs:isDefinedBy": %(pcdmuse:),
35
+ type: "rdfs:Class"
36
+ term :OriginalFile,
37
+ comment: %(The original creation format of a file.),
38
+ label: "original file",
39
+ "rdf:subClassOf": %(http://pcdm.org/resources#File),
40
+ "rdfs:isDefinedBy": %(pcdmuse:),
41
+ type: "rdfs:Class"
42
+ term :PreservationMasterFile,
43
+ comment: %(Best quality representation of the Object appropriate for long-term
44
+ preservation.),
45
+ label: "preservation master file",
46
+ "rdf:subClassOf": %(http://pcdm.org/resources#File),
47
+ "rdfs:isDefinedBy": %(pcdmuse:),
48
+ type: "rdfs:Class"
49
+ term :ServiceFile,
50
+ comment: %(A medium quality representation of the Object appropriate for serving to
51
+ users. Similar to a FADGI "derivative file" but can also be used for born-digital content,
52
+ and is not necessarily derived from another file.),
53
+ label: "service file",
54
+ "rdf:subClassOf": %(http://pcdm.org/resources#File),
55
+ "rdfs:isDefinedBy": %(pcdmuse:),
56
+ type: "rdfs:Class"
57
+ term :ThumbnailImage,
58
+ comment: %(A low resolution image representation of the Object appropriate for using
59
+ as an icon.),
60
+ label: "thumbnail image",
61
+ "rdf:subClassOf": %(http://pcdm.org/resources#File),
62
+ "rdfs:isDefinedBy": %(pcdmuse:),
63
+ type: "rdfs:Class"
64
+ term :Transcript,
65
+ comment: %(A textual representation of the Object appropriate for presenting to users,
66
+ such as subtitles or transcript of a video. Can be used as a substitute or complement to other
67
+ files for accessibility purposes.),
68
+ label: "transcript",
69
+ "rdf:subClassOf": %(http://pcdm.org/resources#ExtractedText),
70
+ "rdfs:isDefinedBy": %(pcdmuse:),
71
+ type: "rdfs:Class"
72
+ end
73
+ end
data/valkyrie.gemspec CHANGED
@@ -1,7 +1,8 @@
1
1
  # coding: utf-8
2
- lib = File.expand_path("../lib", __FILE__)
2
+ # frozen_string_literal: true
3
+ lib = File.expand_path('../lib', __FILE__)
3
4
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
- require "valkyrie/version"
5
+ require 'valkyrie/version'
5
6
 
6
7
  Gem::Specification.new do |spec|
7
8
  spec.name = "valkyrie"
@@ -9,18 +10,43 @@ Gem::Specification.new do |spec|
9
10
  spec.authors = ["Trey Pendragon"]
10
11
  spec.email = ["tpendragon@princeton.edu"]
11
12
 
12
- spec.summary = %q{An ORM using the Data Mapper pattern, specifically built to solve Digital Repository use cases.}
13
+ spec.summary = 'An ORM using the Data Mapper pattern, specifically built to solve Digital Repository use cases.'
13
14
 
14
- spec.homepage = "https://github.com/samvera-labs/valkyrie"
15
-
16
- spec.files = `git ls-files -z`.split("\x0").reject do |f|
15
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
17
16
  f.match(%r{^(test|spec|features)/})
18
17
  end
19
18
  spec.bindir = "exe"
20
19
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
21
20
  spec.require_paths = ["lib"]
22
21
 
23
- spec.add_development_dependency "bundler", "~> 1.15"
22
+ spec.add_dependency 'dry-struct'
23
+ spec.add_dependency 'draper'
24
+ spec.add_dependency 'activemodel'
25
+ spec.add_dependency 'dry-types'
26
+ spec.add_dependency 'rdf'
27
+ spec.add_dependency 'active-fedora'
28
+ spec.add_dependency 'activesupport'
29
+ spec.add_dependency 'activerecord'
30
+ spec.add_dependency 'reform'
31
+ spec.add_dependency 'reform-rails'
32
+ spec.add_dependency 'pg'
33
+ spec.add_dependency 'json-ld'
34
+ spec.add_dependency 'json'
35
+ spec.add_dependency 'active-triples'
36
+ spec.add_dependency 'hydra-access-controls'
37
+ spec.add_dependency 'hydra-derivatives'
38
+ spec.add_dependency 'ruby_tika_app'
39
+
40
+ spec.add_development_dependency "bundler", "~> 1.13"
24
41
  spec.add_development_dependency "rake", "~> 10.0"
25
42
  spec.add_development_dependency "rspec", "~> 3.0"
43
+ spec.add_development_dependency "pry"
44
+ spec.add_development_dependency "pry-byebug"
45
+ spec.add_development_dependency "database_cleaner"
46
+ spec.add_development_dependency "simplecov"
47
+ spec.add_development_dependency "coveralls"
48
+ spec.add_development_dependency "bixby"
49
+ spec.add_development_dependency 'rubocop', '~> 0.48.0'
50
+ spec.add_development_dependency 'rubocop-rails'
51
+ spec.add_development_dependency 'yard'
26
52
  end