lyber-core 4.1.3 → 4.1.4
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.
- checksums.yaml +4 -4
- data/lib/lyber_core.rb +3 -0
- data/lib/lyber_core/base.rb +91 -0
- data/lib/lyber_core/log.rb +24 -35
- data/lib/lyber_core/return_state.rb +9 -11
- data/lib/lyber_core/robot.rb +21 -31
- data/lib/tasks/rdoc.rake +11 -12
- metadata +37 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a1489790b66195312397f9325c4e61119086d903
|
4
|
+
data.tar.gz: e5db26df5720035e46f22360246f680dfbe87b10
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5af41b19bb03d42890596fe374187cbc856d768fedff25b104522b2717a08adc2dff41d5c826455284cd89a7d761906ecb57633c8a0d2419ebd9616f7ab9ce2f
|
7
|
+
data.tar.gz: 0647f4d26c22e049c59bbc814f1dafc5463169e2e0ee687a77d9b0e4051d37ac9015280f7e2bc0fa967a6b47e2a315adaf4fd418adcdc6b712562ff7149fba09
|
data/lib/lyber_core.rb
CHANGED
@@ -0,0 +1,91 @@
|
|
1
|
+
require 'benchmark'
|
2
|
+
require 'active_support'
|
3
|
+
|
4
|
+
module LyberCore
|
5
|
+
# The skeleton of robots, a replacement for LyberCore::Robot
|
6
|
+
# @example To migrate from LyberCore::Robot, replace
|
7
|
+
# class MyRobot
|
8
|
+
# include LyberCore::Robot
|
9
|
+
# def initialize
|
10
|
+
# new(REPOSITORY, WORKFLOW_NAME, ROBOT_NAME)
|
11
|
+
# end
|
12
|
+
# def perform ...
|
13
|
+
# end
|
14
|
+
# @example Usage: implement self.worker and override #perform, as before
|
15
|
+
# class MyRobot < LyberCore::Base
|
16
|
+
# def self.worker
|
17
|
+
# new('sdr', 'preservationIngestWF', 'ingest-poison')
|
18
|
+
# end
|
19
|
+
# def perform ...
|
20
|
+
# end
|
21
|
+
class Base
|
22
|
+
# Called by job-manager: instantiate the Robot and call #work with the druid
|
23
|
+
# @param [String] druid
|
24
|
+
# @note Override the instance method #perform, probably not this one
|
25
|
+
def self.perform(druid)
|
26
|
+
worker.work(druid)
|
27
|
+
end
|
28
|
+
|
29
|
+
# get an instance, without knowing the params for .new()
|
30
|
+
# @return [LyberCore::Base]
|
31
|
+
def self.worker
|
32
|
+
raise NotImplementedError, 'Implement class method self.worker on the subclass'
|
33
|
+
end
|
34
|
+
|
35
|
+
attr_accessor :repo, :workflow_name, :step_name, :check_queued_status, :workflow_service
|
36
|
+
|
37
|
+
def initialize(repo, workflow_name, step_name, opts = {})
|
38
|
+
Signal.trap('QUIT') { puts "#{Process.pid} ignoring SIGQUIT" } # SIGQUIT ignored to let the robot finish
|
39
|
+
@repo = repo
|
40
|
+
@workflow_name = workflow_name
|
41
|
+
@step_name = step_name
|
42
|
+
@check_queued_status = opts.fetch(:check_queued_status, true)
|
43
|
+
@workflow_service = opts.fetch(:workflow_service, Dor::WorkflowService)
|
44
|
+
end
|
45
|
+
|
46
|
+
# @return [Logger]
|
47
|
+
def logger
|
48
|
+
unless @log_init # one time
|
49
|
+
LyberCore::Log.set_logfile($stdout) # let process manager(bluepill) handle logging
|
50
|
+
@log_init = true
|
51
|
+
end
|
52
|
+
LyberCore::Log
|
53
|
+
end
|
54
|
+
|
55
|
+
# Sets up logging, timing and error handling of the job
|
56
|
+
# Calls the #perform method, then sets workflow to 'completed' or 'error' depending on success
|
57
|
+
def work(druid)
|
58
|
+
logger.info "#{druid} processing"
|
59
|
+
return if check_queued_status && !item_queued?(druid)
|
60
|
+
result = nil
|
61
|
+
elapsed = Benchmark.realtime { result = perform(druid) }
|
62
|
+
if result.is_a?(LyberCore::Robot::ReturnState)
|
63
|
+
workflow_state = result.status
|
64
|
+
note = result.note unless result.note.blank?
|
65
|
+
else
|
66
|
+
workflow_state = 'completed' # default
|
67
|
+
end
|
68
|
+
note ||= Socket.gethostname # default
|
69
|
+
workflow_service.update_workflow_status(repo, druid, workflow_name, step_name, workflow_state, elapsed: elapsed, note: note)
|
70
|
+
logger.info "Finished #{druid} in #{format('%0.4f', elapsed)}s"
|
71
|
+
rescue StandardError => e
|
72
|
+
Honeybadger.notify(e) if defined? Honeybadger
|
73
|
+
begin
|
74
|
+
logger.error e.message + "\n" + e.backtrace.join("\n")
|
75
|
+
workflow_service.update_workflow_error_status(repo, druid, workflow_name, step_name, e.message, error_text: Socket.gethostname)
|
76
|
+
rescue StandardError => e2
|
77
|
+
logger.error "Cannot set #{druid} to status='error'\n" + e2.message + "\n" + e2.backtrace.join("\n")
|
78
|
+
raise e2 # send exception to Resque failed queue
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
private
|
83
|
+
|
84
|
+
def item_queued?(druid)
|
85
|
+
status = workflow_service.get_workflow_status(repo, druid, workflow_name, step_name)
|
86
|
+
return true if status =~ /queued/i
|
87
|
+
logger.warn "Item is not queued, but has status of '#{status}'. Will skip processing"
|
88
|
+
false
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
data/lib/lyber_core/log.rb
CHANGED
@@ -1,14 +1,13 @@
|
|
1
|
-
|
2
1
|
module LyberCore
|
3
|
-
|
4
2
|
class LyberCore::Log
|
5
3
|
require 'logger'
|
6
4
|
|
7
5
|
# Default values
|
8
|
-
DEFAULT_LOGFILE =
|
6
|
+
DEFAULT_LOGFILE = '/tmp/lybercore_log.log'.freeze # TODO change to STDOUT?
|
9
7
|
DEFAULT_LOG_LEVEL = Logger::INFO
|
10
|
-
DEFAULT_FORMATTER = proc
|
11
|
-
|
8
|
+
DEFAULT_FORMATTER = proc do |s, t, p, m|
|
9
|
+
"%5s [%s] (%s) %s :: %s\n" % [s, t.strftime('%Y-%m-%d %H:%M:%S'), $$, p, m]
|
10
|
+
end
|
12
11
|
|
13
12
|
# Initial state
|
14
13
|
@@logfile = DEFAULT_LOGFILE
|
@@ -27,27 +26,22 @@ module LyberCore
|
|
27
26
|
|
28
27
|
# The current location of the logfile
|
29
28
|
def Log.logfile
|
30
|
-
|
29
|
+
@@logfile
|
31
30
|
end
|
32
31
|
|
33
|
-
|
34
|
-
|
35
32
|
# Accepts a filename as an argument, and checks to see whether that file can be
|
36
33
|
# opened for writing. If it can be opened, it closes the existing Logger object
|
37
34
|
# and re-opens it with the new logfile location. It raises an exception if it
|
38
35
|
# cannot write to the specified logfile.
|
39
36
|
def Log.set_logfile(new_logfile)
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
raise e, "Couldn't initialize logfile #{new_logfile} because\n#{e.message}: #{e.backtrace.join(%{\n})}}"
|
49
|
-
end
|
50
|
-
|
37
|
+
current_log_level = @@log.level
|
38
|
+
current_formatter = @@log.formatter
|
39
|
+
@@log = Logger.new(new_logfile)
|
40
|
+
@@logfile = new_logfile
|
41
|
+
@@log.level = current_log_level
|
42
|
+
@@log.formatter = current_formatter
|
43
|
+
rescue Exception => e
|
44
|
+
raise e, "Couldn't initialize logfile #{new_logfile} because\n#{e.message}: #{e.backtrace.join(%(\n))}}"
|
51
45
|
end
|
52
46
|
|
53
47
|
# Set the log level.
|
@@ -59,18 +53,16 @@ module LyberCore
|
|
59
53
|
# Logger::INFO (1): generic (useful) information about system operation
|
60
54
|
# Logger::DEBUG (0): low-level information for developers
|
61
55
|
def Log.set_level(loglevel)
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
@@log.level = 0
|
70
|
-
end
|
71
|
-
rescue Exception => e
|
72
|
-
raise e, "Couldn't set log level because\n#{e.message}: #{e.backtrace.join(%{\n})}"
|
56
|
+
if [0, 1, 2, 3, 4].include? loglevel
|
57
|
+
@@log.level = loglevel
|
58
|
+
@@log.debug "Setting LyberCore::Log.level to #{loglevel}"
|
59
|
+
else
|
60
|
+
@@log.warn "I received an invalid option for log level. I expected a number between 0 and 4 but I got #{loglevel}"
|
61
|
+
@@log.warn "I'm setting the loglevel to 0 (debug) because you seem to be having trouble."
|
62
|
+
@@log.level = 0
|
73
63
|
end
|
64
|
+
rescue Exception => e
|
65
|
+
raise e, "Couldn't set log level because\n#{e.message}: #{e.backtrace.join(%(\n))}"
|
74
66
|
end
|
75
67
|
|
76
68
|
# Return the current log level
|
@@ -105,10 +97,7 @@ module LyberCore
|
|
105
97
|
|
106
98
|
def Log.exception_message(e)
|
107
99
|
msg = e.inspect.split($/).join('; ') + "\n"
|
108
|
-
msg << e.backtrace.join("\n") if
|
100
|
+
msg << e.backtrace.join("\n") if e.backtrace
|
109
101
|
end
|
110
|
-
|
111
102
|
end
|
112
|
-
|
113
|
-
|
114
|
-
end
|
103
|
+
end
|
@@ -1,38 +1,36 @@
|
|
1
1
|
# this object defines the allowed states robots can optionally return upon completion
|
2
|
-
# if the return value of the "perform" step is an object of this type and the status value is set an allowed value,
|
2
|
+
# if the return value of the "perform" step is an object of this type and the status value is set an allowed value,
|
3
3
|
# it will be used to set the final workflow state for that druid
|
4
4
|
module LyberCore
|
5
5
|
module Robot
|
6
6
|
class ReturnState
|
7
|
-
|
8
7
|
attr_reader :status
|
9
8
|
attr_accessor :note
|
10
|
-
ALLOWED_RETURN_STATES = %w
|
11
|
-
DEFAULT_RETURN_STATE = 'completed'
|
12
|
-
|
9
|
+
ALLOWED_RETURN_STATES = %w[completed skipped waiting].freeze
|
10
|
+
DEFAULT_RETURN_STATE = 'completed'.freeze
|
11
|
+
|
13
12
|
def self.SKIPPED
|
14
|
-
|
13
|
+
new(status: 'skipped')
|
15
14
|
end
|
16
15
|
|
17
16
|
def self.COMPLETED
|
18
|
-
|
17
|
+
new(status: 'completed')
|
19
18
|
end
|
20
19
|
|
21
20
|
def self.WAITING
|
22
|
-
|
21
|
+
new(status: 'waiting')
|
23
22
|
end
|
24
23
|
|
25
24
|
def initialize(params = {})
|
26
25
|
self.status = params[:status] || DEFAULT_RETURN_STATE
|
27
|
-
self.note = params[:note] ||
|
26
|
+
self.note = params[:note] || ''
|
28
27
|
end
|
29
|
-
|
28
|
+
|
30
29
|
def status=(value)
|
31
30
|
state = value.to_s.downcase
|
32
31
|
raise 'invalid return state' unless ALLOWED_RETURN_STATES.include? state
|
33
32
|
@status = state
|
34
33
|
end
|
35
|
-
|
36
34
|
end
|
37
35
|
end
|
38
36
|
end
|
data/lib/lyber_core/robot.rb
CHANGED
@@ -5,25 +5,20 @@ require 'active_support/core_ext/string/inflections' # camelcase
|
|
5
5
|
|
6
6
|
module LyberCore
|
7
7
|
module Robot
|
8
|
-
|
9
8
|
# Add the ClassMethods to the class this is being mixed into
|
10
|
-
def self.included
|
9
|
+
def self.included(base)
|
11
10
|
base.extend ClassMethods
|
12
11
|
end
|
13
12
|
|
14
13
|
module ClassMethods
|
15
|
-
|
16
14
|
# Called by job-manager on derived-class
|
17
15
|
# Instantiate the Robot and call #work with the passed in druid
|
18
16
|
def perform(druid)
|
19
|
-
|
20
|
-
klazz = self.name.split('::').inject(Object) {|o,c| o.const_get c}
|
21
|
-
bot = klazz.new
|
17
|
+
bot = new
|
22
18
|
bot.work druid
|
23
19
|
end
|
24
20
|
end
|
25
21
|
|
26
|
-
|
27
22
|
# Converts a given step to the Robot class name
|
28
23
|
# Examples:
|
29
24
|
#
|
@@ -35,15 +30,15 @@ module LyberCore
|
|
35
30
|
# @param [Hash] opts
|
36
31
|
# @option :repo_suffix defaults to `Repo`
|
37
32
|
# @return [String] The class name for the robot, e.g., `Robots::DorRepo::Accession:DescriptiveMetadata`
|
38
|
-
def self.step_to_classname
|
33
|
+
def self.step_to_classname(step, opts = {})
|
39
34
|
# generate the robot job class name
|
40
35
|
opts[:repo_suffix] ||= 'Repo'
|
41
36
|
r, w, s = step.split(/:/, 3)
|
42
|
-
|
37
|
+
[
|
43
38
|
'Robots',
|
44
39
|
r.camelcase + opts[:repo_suffix], # 'Dor' conflicts with dor-services
|
45
40
|
w.sub('WF', '').camelcase,
|
46
|
-
s.
|
41
|
+
s.tr('-', '_').camelcase
|
47
42
|
].join('::')
|
48
43
|
end
|
49
44
|
|
@@ -51,7 +46,7 @@ module LyberCore
|
|
51
46
|
attr_reader :workflow_service
|
52
47
|
|
53
48
|
def initialize(repo, workflow_name, step_name, opts = {})
|
54
|
-
Signal.trap(
|
49
|
+
Signal.trap('QUIT') { puts "#{Process.pid} ignoring SIGQUIT" } # SIGQUIT ignored to let the robot finish
|
55
50
|
@repo = repo
|
56
51
|
@workflow_name = workflow_name
|
57
52
|
@step_name = step_name
|
@@ -62,54 +57,49 @@ module LyberCore
|
|
62
57
|
# Sets up logging, timing and error handling of the job
|
63
58
|
# Calls the #perform method, then sets workflow to 'completed' or 'error' depending on success
|
64
59
|
def work(druid)
|
65
|
-
LyberCore::Log.set_logfile($stdout)
|
60
|
+
LyberCore::Log.set_logfile($stdout) # let process manager(bluepill) handle logging
|
66
61
|
LyberCore::Log.info "#{druid} processing"
|
67
62
|
return if @check_queued_status && !item_queued?(druid)
|
68
63
|
|
69
64
|
result = nil
|
70
65
|
elapsed = Benchmark.realtime do
|
71
|
-
result =
|
66
|
+
result = perform druid # implemented in the mixed-in robot class
|
72
67
|
end
|
73
68
|
|
74
69
|
# this is the default note to pass back to workflow service, but it can be overriden by a robot that uses the Lybercore::Robot::ReturnState object to return a status
|
75
70
|
note = Socket.gethostname
|
76
|
-
|
77
|
-
# the final workflow state is determined by the return value of the perform step, if it is a ReturnState object,
|
71
|
+
|
72
|
+
# the final workflow state is determined by the return value of the perform step, if it is a ReturnState object,
|
78
73
|
# we will use the defined status, otherwise default to completed
|
79
74
|
# if a note is passed back, we will also use that instead of the default
|
80
75
|
if result.class == LyberCore::Robot::ReturnState
|
81
76
|
workflow_state = result.status
|
82
77
|
note = result.note unless result.note.blank?
|
83
78
|
else
|
84
|
-
workflow_state = 'completed'
|
79
|
+
workflow_state = 'completed'
|
85
80
|
end
|
86
|
-
|
87
|
-
# update the workflow status from its current state to the state returned by perform (or 'completed' as the default)
|
88
|
-
workflow_service.update_workflow_status @repo, druid, @workflow_name, @step_name, workflow_state, :elapsed => elapsed, :note => note
|
89
|
-
LyberCore::Log.info "Finished #{druid} in #{sprintf("%0.4f",elapsed)}s"
|
90
81
|
|
91
|
-
|
82
|
+
# update the workflow status from its current state to the state returned by perform (or 'completed' as the default)
|
83
|
+
workflow_service.update_workflow_status(@repo, druid, @workflow_name, @step_name, workflow_state, elapsed: elapsed, note: note)
|
84
|
+
LyberCore::Log.info "Finished #{druid} in #{sprintf('%0.4f', elapsed)}s"
|
85
|
+
rescue StandardError => e
|
92
86
|
Honeybadger.notify(e) if defined? Honeybadger
|
93
87
|
begin
|
94
88
|
LyberCore::Log.error e.message + "\n" + e.backtrace.join("\n")
|
95
|
-
workflow_service.update_workflow_error_status
|
96
|
-
rescue => e2
|
89
|
+
workflow_service.update_workflow_error_status(@repo, druid, @workflow_name, @step_name, e.message, error_text: Socket.gethostname)
|
90
|
+
rescue StandardError => e2
|
97
91
|
LyberCore::Log.error "Cannot set #{druid} to status='error'\n" + e2.message + "\n" + e2.backtrace.join("\n")
|
98
92
|
raise e2 # send exception to Resque failed queue
|
99
93
|
end
|
100
94
|
end
|
101
95
|
|
102
|
-
|
96
|
+
private
|
103
97
|
|
104
98
|
def item_queued?(druid)
|
105
99
|
status = workflow_service.get_workflow_status(@repo, druid, @workflow_name, @step_name)
|
106
|
-
if
|
107
|
-
|
108
|
-
|
109
|
-
LyberCore::Log.warn "Item is not queued, but has status of '#{status}'. Will skip processing"
|
110
|
-
return false
|
111
|
-
end
|
100
|
+
return true if status =~ /queued/i
|
101
|
+
LyberCore::Log.warn "Item is not queued, but has status of '#{status}'. Will skip processing"
|
102
|
+
false
|
112
103
|
end
|
113
|
-
|
114
104
|
end
|
115
105
|
end
|
data/lib/tasks/rdoc.rake
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
-
desc
|
2
|
-
task :
|
1
|
+
desc 'Generate RDoc'
|
2
|
+
task doc: ['doc:generate']
|
3
3
|
|
4
4
|
namespace :doc do
|
5
5
|
project_root = File.expand_path(File.join(File.dirname(__FILE__), '..', '..'))
|
@@ -10,23 +10,22 @@ namespace :doc do
|
|
10
10
|
require 'yard/rake/yardoc_task'
|
11
11
|
|
12
12
|
YARD::Rake::YardocTask.new(:generate) do |yt|
|
13
|
-
yt.files = Dir.glob(File.join(project_root, 'lib', '*.rb')) +
|
13
|
+
yt.files = Dir.glob(File.join(project_root, 'lib', '*.rb')) +
|
14
14
|
Dir.glob(File.join(project_root, 'lib', '**', '*.rb')) +
|
15
|
-
|
16
|
-
|
17
|
-
|
15
|
+
[File.join(project_root, 'README.rdoc')] +
|
16
|
+
[File.join(project_root, 'LICENSE')]
|
17
|
+
|
18
18
|
yt.options = ['--output-dir', doc_destination, '--readme', 'README.rdoc']
|
19
19
|
end
|
20
20
|
rescue LoadError
|
21
|
-
desc
|
21
|
+
desc 'Generate YARD Documentation'
|
22
22
|
task :generate do
|
23
|
-
abort
|
23
|
+
abort 'Please install the YARD gem to generate rdoc.'
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|
27
|
-
desc
|
27
|
+
desc 'Remove generated documenation'
|
28
28
|
task :clean do
|
29
|
-
rm_r doc_destination if File.
|
29
|
+
rm_r doc_destination if File.exist?(doc_destination)
|
30
30
|
end
|
31
|
-
|
32
|
-
end
|
31
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: lyber-core
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.1.
|
4
|
+
version: 4.1.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Alpana Pande
|
@@ -16,8 +16,22 @@ authors:
|
|
16
16
|
autorequire:
|
17
17
|
bindir: bin
|
18
18
|
cert_chain: []
|
19
|
-
date:
|
19
|
+
date: 2018-04-16 00:00:00.000000000 Z
|
20
20
|
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
22
|
+
name: activesupport
|
23
|
+
requirement: !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - ">="
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
version: '0'
|
28
|
+
type: :runtime
|
29
|
+
prerelease: false
|
30
|
+
version_requirements: !ruby/object:Gem::Requirement
|
31
|
+
requirements:
|
32
|
+
- - ">="
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: '0'
|
21
35
|
- !ruby/object:Gem::Dependency
|
22
36
|
name: dor-workflow-service
|
23
37
|
requirement: !ruby/object:Gem::Requirement
|
@@ -39,13 +53,13 @@ dependencies:
|
|
39
53
|
- !ruby/object:Gem::Version
|
40
54
|
version: '3'
|
41
55
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
56
|
+
name: coveralls
|
43
57
|
requirement: !ruby/object:Gem::Requirement
|
44
58
|
requirements:
|
45
59
|
- - ">="
|
46
60
|
- !ruby/object:Gem::Version
|
47
61
|
version: '0'
|
48
|
-
type: :
|
62
|
+
type: :development
|
49
63
|
prerelease: false
|
50
64
|
version_requirements: !ruby/object:Gem::Requirement
|
51
65
|
requirements:
|
@@ -95,7 +109,7 @@ dependencies:
|
|
95
109
|
- !ruby/object:Gem::Version
|
96
110
|
version: '3.0'
|
97
111
|
- !ruby/object:Gem::Dependency
|
98
|
-
name:
|
112
|
+
name: rubocop
|
99
113
|
requirement: !ruby/object:Gem::Requirement
|
100
114
|
requirements:
|
101
115
|
- - ">="
|
@@ -109,7 +123,21 @@ dependencies:
|
|
109
123
|
- !ruby/object:Gem::Version
|
110
124
|
version: '0'
|
111
125
|
- !ruby/object:Gem::Dependency
|
112
|
-
name:
|
126
|
+
name: rubocop-rspec
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - "~>"
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '1.24'
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - "~>"
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '1.24'
|
139
|
+
- !ruby/object:Gem::Dependency
|
140
|
+
name: yard
|
113
141
|
requirement: !ruby/object:Gem::Requirement
|
114
142
|
requirements:
|
115
143
|
- - ">="
|
@@ -134,6 +162,7 @@ files:
|
|
134
162
|
- LICENSE
|
135
163
|
- README.md
|
136
164
|
- lib/lyber_core.rb
|
165
|
+
- lib/lyber_core/base.rb
|
137
166
|
- lib/lyber_core/log.rb
|
138
167
|
- lib/lyber_core/return_state.rb
|
139
168
|
- lib/lyber_core/robot.rb
|
@@ -158,8 +187,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
158
187
|
version: 1.3.6
|
159
188
|
requirements: []
|
160
189
|
rubyforge_project:
|
161
|
-
rubygems_version: 2.6.
|
190
|
+
rubygems_version: 2.6.11
|
162
191
|
signing_key:
|
163
192
|
specification_version: 4
|
164
193
|
summary: Core services used by the SUL Digital Library
|
165
194
|
test_files: []
|
195
|
+
has_rdoc:
|