libis-workflow 2.0.25 → 2.0.28
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/.coveralls.yml +1 -1
- data/.gitignore +36 -36
- data/.travis.yml +32 -32
- data/Gemfile +4 -4
- data/LICENSE +20 -20
- data/README.md +380 -380
- data/Rakefile +6 -6
- data/lib/libis/exceptions.rb +6 -6
- data/lib/libis/workflow.rb +41 -41
- data/lib/libis/workflow/action.rb +24 -24
- data/lib/libis/workflow/base/dir_item.rb +13 -13
- data/lib/libis/workflow/base/file_item.rb +80 -80
- data/lib/libis/workflow/base/job.rb +83 -83
- data/lib/libis/workflow/base/logging.rb +66 -66
- data/lib/libis/workflow/base/run.rb +97 -95
- data/lib/libis/workflow/base/work_item.rb +173 -173
- data/lib/libis/workflow/base/workflow.rb +149 -149
- data/lib/libis/workflow/config.rb +22 -22
- data/lib/libis/workflow/dir_item.rb +10 -10
- data/lib/libis/workflow/file_item.rb +15 -15
- data/lib/libis/workflow/job.rb +28 -28
- data/lib/libis/workflow/message_registry.rb +30 -30
- data/lib/libis/workflow/run.rb +34 -34
- data/lib/libis/workflow/status.rb +133 -133
- data/lib/libis/workflow/task.rb +318 -316
- data/lib/libis/workflow/task_group.rb +72 -71
- data/lib/libis/workflow/task_runner.rb +34 -34
- data/lib/libis/workflow/version.rb +5 -5
- data/lib/libis/workflow/work_item.rb +37 -37
- data/lib/libis/workflow/worker.rb +42 -42
- data/lib/libis/workflow/workflow.rb +20 -20
- data/libis-workflow.gemspec +38 -38
- data/spec/items.rb +2 -2
- data/spec/items/test_dir_item.rb +13 -13
- data/spec/items/test_file_item.rb +16 -16
- data/spec/items/test_run.rb +8 -8
- data/spec/spec_helper.rb +8 -8
- data/spec/task_spec.rb +15 -15
- data/spec/tasks/camelize_name.rb +12 -12
- data/spec/tasks/checksum_tester.rb +32 -32
- data/spec/tasks/collect_files.rb +47 -47
- data/spec/workflow_spec.rb +154 -154
- metadata +3 -3
@@ -1,149 +1,149 @@
|
|
1
|
-
require 'libis/tools/parameter'
|
2
|
-
require 'libis/workflow/task_group'
|
3
|
-
require 'libis/tools/extend/hash'
|
4
|
-
|
5
|
-
module Libis
|
6
|
-
module Workflow
|
7
|
-
module Base
|
8
|
-
|
9
|
-
# This is the base module for Workflows.
|
10
|
-
#
|
11
|
-
# This module lacks the implementation for the data attributes. It functions as an interface that describes the
|
12
|
-
# common functionality regardless of the storage implementation. These attributes require some implementation:
|
13
|
-
#
|
14
|
-
# - name: [String] the name of the Workflow. The name will be used to identify the workflow. Each time a workflow
|
15
|
-
# is executed, a Run will be created. The Run will get a name that starts with the workflow name and ends with
|
16
|
-
# the date and time the Run was started. As such this name attribute serves as an identifier and should be
|
17
|
-
# treated as such. If possible is should be unique.
|
18
|
-
# - description: [String] more information about the workflow.
|
19
|
-
# - config: [Hash] detailed configuration for the workflow. The application assumes it behaves as a Hash and will
|
20
|
-
# access it with [], merge! and delete methods. If your implementation decides to implement it with another
|
21
|
-
# object, it should implement above methods. The config Hash requires the following keys:
|
22
|
-
# - input: [Hash] all input parameter definitions where the key is the parameter name and the value is another
|
23
|
-
# Hash with arguments for the parameter definition. It typically contains the following arguments:
|
24
|
-
# - default: default value if no value specified when the workflow is executed
|
25
|
-
# - propagate_to: the task name (or path) and parameter name that any set value for this parameter will be
|
26
|
-
# propagated to. The syntax is <task name|task path>[#<parameter name>]. It the #<parameter name> part
|
27
|
-
# is not present, the same name as the input parameter is used. If you want to push the value to
|
28
|
-
# multiple task parameters, you can either supply an array of propagate paths or put them in a string
|
29
|
-
# separated by a ','.
|
30
|
-
# - tasks: [Array] task definitions that define the order in which the tasks should be executed for the workflow.
|
31
|
-
# A task definition is a Hash with the following values:
|
32
|
-
# - class: [String] the class name of the task including the module names
|
33
|
-
# - name: [String] optional if class is present. A friendly name for the task that will be used in the logs.
|
34
|
-
# - tasks: [Array] a list of subtask defintions for this task.
|
35
|
-
#
|
36
|
-
# Additionally the task definition Hash may specify values for any other parameter that the task knows of.
|
37
|
-
# All tasks have some fixed parameters. For more information about these see the documentation of
|
38
|
-
# the task class.
|
39
|
-
#
|
40
|
-
# A task definition does not require to have a 'class' entry. If not present the default
|
41
|
-
# ::Libis::Workflow::TaskGroup class will be instatiated. It will do nothing itself, but will execute the
|
42
|
-
# subtasks on the item(s). In such case a 'name' is mandatory.
|
43
|
-
#
|
44
|
-
# These values should be set by calling the #configure method which takes a Hash as argument with :name,
|
45
|
-
# :description, :input and :tasks keys.
|
46
|
-
#
|
47
|
-
# A minimal in-memory implementation could be:
|
48
|
-
#
|
49
|
-
# class Workflow
|
50
|
-
# include ::Libis::Workflow::Base::Workflow
|
51
|
-
#
|
52
|
-
# attr_accessor :name, :description, :config
|
53
|
-
#
|
54
|
-
# def initialize
|
55
|
-
# @name = ''
|
56
|
-
# @description = ''
|
57
|
-
# @config = Hash.new
|
58
|
-
# end
|
59
|
-
#
|
60
|
-
# end
|
61
|
-
#
|
62
|
-
module Workflow
|
63
|
-
|
64
|
-
module ClassMethods
|
65
|
-
def require_all
|
66
|
-
Libis::Workflow::Config.require_all(File.join(File.dirname(__FILE__), '..', 'tasks'))
|
67
|
-
# noinspection RubyResolve
|
68
|
-
Libis::Workflow::Config.require_all(Libis::Workflow::Config.taskdir)
|
69
|
-
# noinspection RubyResolve
|
70
|
-
Libis::Workflow::Config.require_all(Libis::Workflow::Config.itemdir)
|
71
|
-
end
|
72
|
-
end
|
73
|
-
|
74
|
-
def self.included(base)
|
75
|
-
base.extend ClassMethods
|
76
|
-
end
|
77
|
-
|
78
|
-
def configure(cfg)
|
79
|
-
self.name = cfg.delete('name') || self.class.name
|
80
|
-
self.description = cfg.delete('description') || ''
|
81
|
-
self.config['input'] = {}
|
82
|
-
self.config['tasks'] = []
|
83
|
-
self.config.merge! cfg
|
84
|
-
|
85
|
-
self.class.require_all
|
86
|
-
|
87
|
-
self.config
|
88
|
-
end
|
89
|
-
|
90
|
-
def input
|
91
|
-
self.config.key_strings_to_symbols(recursive: true)[:input].inject({}) do |hash, input_def|
|
92
|
-
name = input_def.first
|
93
|
-
default = input_def.last[:default]
|
94
|
-
parameter = ::Libis::Tools::Parameter.new name, default
|
95
|
-
input_def.last.each { |k, v| parameter[k] = v }
|
96
|
-
hash[name] = parameter
|
97
|
-
hash
|
98
|
-
end
|
99
|
-
rescue
|
100
|
-
{}
|
101
|
-
end
|
102
|
-
|
103
|
-
# @param [Hash] options
|
104
|
-
def prepare_input(options)
|
105
|
-
options = options.key_strings_to_symbols
|
106
|
-
result = {}
|
107
|
-
self.input.each do |key, parameter|
|
108
|
-
if options.has_key?(key)
|
109
|
-
value = parameter.parse(options[key])
|
110
|
-
elsif !parameter[:default].nil?
|
111
|
-
value = parameter[:default]
|
112
|
-
else
|
113
|
-
next
|
114
|
-
end
|
115
|
-
propagate_to = []
|
116
|
-
propagate_to = parameter[:propagate_to] if parameter[:propagate_to].is_a? Array
|
117
|
-
propagate_to = parameter[:propagate_to].split(/[\s,;]+/) if parameter[:propagate_to].is_a? String
|
118
|
-
result[key] = value if propagate_to.empty?
|
119
|
-
propagate_to.each do |target|
|
120
|
-
task_name, param_name = target.split('#')
|
121
|
-
param_name ||= key.to_s
|
122
|
-
result[task_name] ||= {}
|
123
|
-
result[task_name][param_name] = value
|
124
|
-
end
|
125
|
-
end
|
126
|
-
result
|
127
|
-
end
|
128
|
-
|
129
|
-
def tasks(parent = nil)
|
130
|
-
self.config['tasks'].map do |cfg|
|
131
|
-
instantize_task(parent || nil, cfg)
|
132
|
-
end
|
133
|
-
end
|
134
|
-
|
135
|
-
def instantize_task(parent, cfg)
|
136
|
-
task_class = Libis::Workflow::TaskGroup
|
137
|
-
task_class = cfg['class'].constantize if cfg['class']
|
138
|
-
# noinspection RubyArgCount
|
139
|
-
task_instance = task_class.new(parent, cfg)
|
140
|
-
cfg['tasks'] && cfg['tasks'].map do |task_cfg|
|
141
|
-
task_instance << instantize_task(task_instance, task_cfg)
|
142
|
-
end
|
143
|
-
task_instance
|
144
|
-
end
|
145
|
-
|
146
|
-
end
|
147
|
-
end
|
148
|
-
end
|
149
|
-
end
|
1
|
+
require 'libis/tools/parameter'
|
2
|
+
require 'libis/workflow/task_group'
|
3
|
+
require 'libis/tools/extend/hash'
|
4
|
+
|
5
|
+
module Libis
|
6
|
+
module Workflow
|
7
|
+
module Base
|
8
|
+
|
9
|
+
# This is the base module for Workflows.
|
10
|
+
#
|
11
|
+
# This module lacks the implementation for the data attributes. It functions as an interface that describes the
|
12
|
+
# common functionality regardless of the storage implementation. These attributes require some implementation:
|
13
|
+
#
|
14
|
+
# - name: [String] the name of the Workflow. The name will be used to identify the workflow. Each time a workflow
|
15
|
+
# is executed, a Run will be created. The Run will get a name that starts with the workflow name and ends with
|
16
|
+
# the date and time the Run was started. As such this name attribute serves as an identifier and should be
|
17
|
+
# treated as such. If possible is should be unique.
|
18
|
+
# - description: [String] more information about the workflow.
|
19
|
+
# - config: [Hash] detailed configuration for the workflow. The application assumes it behaves as a Hash and will
|
20
|
+
# access it with [], merge! and delete methods. If your implementation decides to implement it with another
|
21
|
+
# object, it should implement above methods. The config Hash requires the following keys:
|
22
|
+
# - input: [Hash] all input parameter definitions where the key is the parameter name and the value is another
|
23
|
+
# Hash with arguments for the parameter definition. It typically contains the following arguments:
|
24
|
+
# - default: default value if no value specified when the workflow is executed
|
25
|
+
# - propagate_to: the task name (or path) and parameter name that any set value for this parameter will be
|
26
|
+
# propagated to. The syntax is <task name|task path>[#<parameter name>]. It the #<parameter name> part
|
27
|
+
# is not present, the same name as the input parameter is used. If you want to push the value to
|
28
|
+
# multiple task parameters, you can either supply an array of propagate paths or put them in a string
|
29
|
+
# separated by a ','.
|
30
|
+
# - tasks: [Array] task definitions that define the order in which the tasks should be executed for the workflow.
|
31
|
+
# A task definition is a Hash with the following values:
|
32
|
+
# - class: [String] the class name of the task including the module names
|
33
|
+
# - name: [String] optional if class is present. A friendly name for the task that will be used in the logs.
|
34
|
+
# - tasks: [Array] a list of subtask defintions for this task.
|
35
|
+
#
|
36
|
+
# Additionally the task definition Hash may specify values for any other parameter that the task knows of.
|
37
|
+
# All tasks have some fixed parameters. For more information about these see the documentation of
|
38
|
+
# the task class.
|
39
|
+
#
|
40
|
+
# A task definition does not require to have a 'class' entry. If not present the default
|
41
|
+
# ::Libis::Workflow::TaskGroup class will be instatiated. It will do nothing itself, but will execute the
|
42
|
+
# subtasks on the item(s). In such case a 'name' is mandatory.
|
43
|
+
#
|
44
|
+
# These values should be set by calling the #configure method which takes a Hash as argument with :name,
|
45
|
+
# :description, :input and :tasks keys.
|
46
|
+
#
|
47
|
+
# A minimal in-memory implementation could be:
|
48
|
+
#
|
49
|
+
# class Workflow
|
50
|
+
# include ::Libis::Workflow::Base::Workflow
|
51
|
+
#
|
52
|
+
# attr_accessor :name, :description, :config
|
53
|
+
#
|
54
|
+
# def initialize
|
55
|
+
# @name = ''
|
56
|
+
# @description = ''
|
57
|
+
# @config = Hash.new
|
58
|
+
# end
|
59
|
+
#
|
60
|
+
# end
|
61
|
+
#
|
62
|
+
module Workflow
|
63
|
+
|
64
|
+
module ClassMethods
|
65
|
+
def require_all
|
66
|
+
Libis::Workflow::Config.require_all(File.join(File.dirname(__FILE__), '..', 'tasks'))
|
67
|
+
# noinspection RubyResolve
|
68
|
+
Libis::Workflow::Config.require_all(Libis::Workflow::Config.taskdir)
|
69
|
+
# noinspection RubyResolve
|
70
|
+
Libis::Workflow::Config.require_all(Libis::Workflow::Config.itemdir)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def self.included(base)
|
75
|
+
base.extend ClassMethods
|
76
|
+
end
|
77
|
+
|
78
|
+
def configure(cfg)
|
79
|
+
self.name = cfg.delete('name') || self.class.name
|
80
|
+
self.description = cfg.delete('description') || ''
|
81
|
+
self.config['input'] = {}
|
82
|
+
self.config['tasks'] = []
|
83
|
+
self.config.merge! cfg
|
84
|
+
|
85
|
+
self.class.require_all
|
86
|
+
|
87
|
+
self.config
|
88
|
+
end
|
89
|
+
|
90
|
+
def input
|
91
|
+
self.config.key_strings_to_symbols(recursive: true)[:input].inject({}) do |hash, input_def|
|
92
|
+
name = input_def.first
|
93
|
+
default = input_def.last[:default]
|
94
|
+
parameter = ::Libis::Tools::Parameter.new name, default
|
95
|
+
input_def.last.each { |k, v| parameter[k] = v }
|
96
|
+
hash[name] = parameter
|
97
|
+
hash
|
98
|
+
end
|
99
|
+
rescue
|
100
|
+
{}
|
101
|
+
end
|
102
|
+
|
103
|
+
# @param [Hash] options
|
104
|
+
def prepare_input(options)
|
105
|
+
options = options.key_strings_to_symbols
|
106
|
+
result = {}
|
107
|
+
self.input.each do |key, parameter|
|
108
|
+
if options.has_key?(key)
|
109
|
+
value = parameter.parse(options[key])
|
110
|
+
elsif !parameter[:default].nil?
|
111
|
+
value = parameter[:default]
|
112
|
+
else
|
113
|
+
next
|
114
|
+
end
|
115
|
+
propagate_to = []
|
116
|
+
propagate_to = parameter[:propagate_to] if parameter[:propagate_to].is_a? Array
|
117
|
+
propagate_to = parameter[:propagate_to].split(/[\s,;]+/) if parameter[:propagate_to].is_a? String
|
118
|
+
result[key] = value if propagate_to.empty?
|
119
|
+
propagate_to.each do |target|
|
120
|
+
task_name, param_name = target.split('#')
|
121
|
+
param_name ||= key.to_s
|
122
|
+
result[task_name] ||= {}
|
123
|
+
result[task_name][param_name] = value
|
124
|
+
end
|
125
|
+
end
|
126
|
+
result
|
127
|
+
end
|
128
|
+
|
129
|
+
def tasks(parent = nil)
|
130
|
+
self.config['tasks'].map do |cfg|
|
131
|
+
instantize_task(parent || nil, cfg)
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
def instantize_task(parent, cfg)
|
136
|
+
task_class = Libis::Workflow::TaskGroup
|
137
|
+
task_class = cfg['class'].constantize if cfg['class']
|
138
|
+
# noinspection RubyArgCount
|
139
|
+
task_instance = task_class.new(parent, cfg)
|
140
|
+
cfg['tasks'] && cfg['tasks'].map do |task_cfg|
|
141
|
+
task_instance << instantize_task(task_instance, task_cfg)
|
142
|
+
end
|
143
|
+
task_instance
|
144
|
+
end
|
145
|
+
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
@@ -1,22 +1,22 @@
|
|
1
|
-
require 'libis/tools/config'
|
2
|
-
|
3
|
-
module Libis
|
4
|
-
module Workflow
|
5
|
-
|
6
|
-
# noinspection RubyConstantNamingConvention
|
7
|
-
Config = ::Libis::Tools::Config
|
8
|
-
|
9
|
-
Config.define_singleton_method(:require_all) do |dir|
|
10
|
-
Dir.glob(File.join(dir, '*.rb')).each do |filename|
|
11
|
-
# noinspection RubyResolve
|
12
|
-
require filename
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
Config.require_all(File.join(File.dirname(__FILE__), 'tasks'))
|
17
|
-
Config[:workdir] = './work'
|
18
|
-
Config[:taskdir] = './tasks'
|
19
|
-
Config[:itemdir] = './items'
|
20
|
-
|
21
|
-
end
|
22
|
-
end
|
1
|
+
require 'libis/tools/config'
|
2
|
+
|
3
|
+
module Libis
|
4
|
+
module Workflow
|
5
|
+
|
6
|
+
# noinspection RubyConstantNamingConvention
|
7
|
+
Config = ::Libis::Tools::Config
|
8
|
+
|
9
|
+
Config.define_singleton_method(:require_all) do |dir|
|
10
|
+
Dir.glob(File.join(dir, '*.rb')).each do |filename|
|
11
|
+
# noinspection RubyResolve
|
12
|
+
require filename
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
Config.require_all(File.join(File.dirname(__FILE__), 'tasks'))
|
17
|
+
Config[:workdir] = './work'
|
18
|
+
Config[:taskdir] = './tasks'
|
19
|
+
Config[:itemdir] = './items'
|
20
|
+
|
21
|
+
end
|
22
|
+
end
|
@@ -1,10 +1,10 @@
|
|
1
|
-
require 'libis/workflow/file_item'
|
2
|
-
|
3
|
-
module Libis
|
4
|
-
module Workflow
|
5
|
-
|
6
|
-
class DirItem < ::Libis::Workflow::FileItem
|
7
|
-
end
|
8
|
-
|
9
|
-
end
|
10
|
-
end
|
1
|
+
require 'libis/workflow/file_item'
|
2
|
+
|
3
|
+
module Libis
|
4
|
+
module Workflow
|
5
|
+
|
6
|
+
class DirItem < ::Libis::Workflow::FileItem
|
7
|
+
end
|
8
|
+
|
9
|
+
end
|
10
|
+
end
|
@@ -1,15 +1,15 @@
|
|
1
|
-
require 'digest'
|
2
|
-
|
3
|
-
require 'libis/workflow/base/file_item'
|
4
|
-
require 'libis/workflow/work_item'
|
5
|
-
|
6
|
-
module Libis
|
7
|
-
module Workflow
|
8
|
-
|
9
|
-
# noinspection RubyResolve
|
10
|
-
class FileItem < ::Libis::Workflow::WorkItem
|
11
|
-
include ::Libis::Workflow::Base::FileItem
|
12
|
-
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
1
|
+
require 'digest'
|
2
|
+
|
3
|
+
require 'libis/workflow/base/file_item'
|
4
|
+
require 'libis/workflow/work_item'
|
5
|
+
|
6
|
+
module Libis
|
7
|
+
module Workflow
|
8
|
+
|
9
|
+
# noinspection RubyResolve
|
10
|
+
class FileItem < ::Libis::Workflow::WorkItem
|
11
|
+
include ::Libis::Workflow::Base::FileItem
|
12
|
+
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
data/lib/libis/workflow/job.rb
CHANGED
@@ -1,28 +1,28 @@
|
|
1
|
-
require 'libis/workflow/base/job'
|
2
|
-
require 'libis/workflow/workflow'
|
3
|
-
require 'libis/workflow/run'
|
4
|
-
|
5
|
-
module Libis
|
6
|
-
module Workflow
|
7
|
-
|
8
|
-
class Job
|
9
|
-
include ::Libis::Workflow::Base::Job
|
10
|
-
|
11
|
-
attr_accessor :name, :description, :workflow, :run_object, :input
|
12
|
-
|
13
|
-
def initialize
|
14
|
-
@name = ''
|
15
|
-
@description = ''
|
16
|
-
@input = Hash.new
|
17
|
-
@workflow = ::Libis::Workflow::Workflow.new
|
18
|
-
@run_object = ::Libis::Workflow::Run.new
|
19
|
-
end
|
20
|
-
|
21
|
-
def logger
|
22
|
-
::Libis::Workflow::Config.logger
|
23
|
-
end
|
24
|
-
|
25
|
-
end
|
26
|
-
|
27
|
-
end
|
28
|
-
end
|
1
|
+
require 'libis/workflow/base/job'
|
2
|
+
require 'libis/workflow/workflow'
|
3
|
+
require 'libis/workflow/run'
|
4
|
+
|
5
|
+
module Libis
|
6
|
+
module Workflow
|
7
|
+
|
8
|
+
class Job
|
9
|
+
include ::Libis::Workflow::Base::Job
|
10
|
+
|
11
|
+
attr_accessor :name, :description, :workflow, :run_object, :input
|
12
|
+
|
13
|
+
def initialize
|
14
|
+
@name = ''
|
15
|
+
@description = ''
|
16
|
+
@input = Hash.new
|
17
|
+
@workflow = ::Libis::Workflow::Workflow.new
|
18
|
+
@run_object = ::Libis::Workflow::Run.new
|
19
|
+
end
|
20
|
+
|
21
|
+
def logger
|
22
|
+
::Libis::Workflow::Config.logger
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|