ductwork 0.1.0 → 0.2.0
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/CHANGELOG.md +6 -0
- data/README.md +3 -0
- data/lib/ductwork/dsl/definition_builder.rb +39 -11
- data/lib/ductwork/engine.rb +10 -0
- data/lib/ductwork/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 10cf03c4f8237368de710c2ee604a9d20cf40c2dcebfda776fe490a38ba26aad
|
|
4
|
+
data.tar.gz: fd44065015e06a493905b493b847df2de01d779f7451662b186a458cb1cc9977
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 712b5f00ad1a1a1c736dd186f04dce4a85f2ba3d57df234a5d1182d91483530f0722c9a153e1a4f8517142657ffc8f486e39e6bcd51c28b66f4df5a5958e5455
|
|
7
|
+
data.tar.gz: 18c7d56494dc4251310e73bffe47c56e80820634dce555ac2e8d2d46b65973242adc621004dada1efa94cb353063ab650bcb833cec2c7d0cffd635727b808fa1
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# Ductwork Changelog
|
|
2
2
|
|
|
3
|
+
## [0.2.0]
|
|
4
|
+
|
|
5
|
+
- fix: allow steps to be chained while pipeline is expanded or divided (before collapsing or combining) - before this incorrectly raised a `CollapseError` or `CombineError`
|
|
6
|
+
- feat: validate argument(s) passed to step transition DSL methods to be valid step class
|
|
7
|
+
- feat: validate all pipeline definitions on rails boot
|
|
8
|
+
|
|
3
9
|
## [0.1.0]
|
|
4
10
|
|
|
5
11
|
- Initial release - see [documentation](https://docs.getductwork.io/) for details
|
data/README.md
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
# Ductwork
|
|
2
2
|
|
|
3
|
+
[](https://github.com/ductwork/ductwork/actions/workflows/main.yml)
|
|
4
|
+
[](https://rubygems.org/gems/ductwork)
|
|
5
|
+
|
|
3
6
|
A Ruby pipeline framework.
|
|
4
7
|
|
|
5
8
|
Ductwork lets you build complex pipelines quickly and easily using intuitive Ruby tooling and a natural DSL. No need to learn complicated unified object models or stand up separate runner instances—just write Ruby code and let Ductwork handle the orchestration.
|
|
@@ -12,9 +12,12 @@ module Ductwork
|
|
|
12
12
|
nodes: [],
|
|
13
13
|
edges: {},
|
|
14
14
|
}
|
|
15
|
+
@divisions = 0
|
|
16
|
+
@expansions = 0
|
|
15
17
|
end
|
|
16
18
|
|
|
17
19
|
def start(klass)
|
|
20
|
+
validate_classes!(klass)
|
|
18
21
|
validate_start_once!
|
|
19
22
|
add_new_nodes(klass)
|
|
20
23
|
|
|
@@ -24,6 +27,7 @@ module Ductwork
|
|
|
24
27
|
# NOTE: there is a bug here that does not allow the user to reuse step
|
|
25
28
|
# classes in the same pipeline. i'll fix this later
|
|
26
29
|
def chain(klass)
|
|
30
|
+
validate_classes!(klass)
|
|
27
31
|
validate_definition_started!(action: "chaining")
|
|
28
32
|
add_edge_to_last_node(klass, type: :chain)
|
|
29
33
|
add_new_nodes(klass)
|
|
@@ -32,10 +36,13 @@ module Ductwork
|
|
|
32
36
|
end
|
|
33
37
|
|
|
34
38
|
def divide(to:)
|
|
39
|
+
validate_classes!(to)
|
|
35
40
|
validate_definition_started!(action: "dividing chain")
|
|
36
41
|
add_edge_to_last_node(*to, type: :divide)
|
|
37
42
|
add_new_nodes(*to)
|
|
38
43
|
|
|
44
|
+
@divisions += 1
|
|
45
|
+
|
|
39
46
|
if block_given?
|
|
40
47
|
branches = to.map do |klass|
|
|
41
48
|
Ductwork::DSL::BranchBuilder
|
|
@@ -49,9 +56,12 @@ module Ductwork
|
|
|
49
56
|
end
|
|
50
57
|
|
|
51
58
|
def combine(into:)
|
|
59
|
+
validate_classes!(into)
|
|
52
60
|
validate_definition_started!(action: "combining steps")
|
|
53
61
|
validate_definition_divided!
|
|
54
62
|
|
|
63
|
+
@divisions -= 1
|
|
64
|
+
|
|
55
65
|
last_nodes = definition[:nodes].reverse.select do |node|
|
|
56
66
|
definition[:edges][node].empty?
|
|
57
67
|
end
|
|
@@ -67,23 +77,31 @@ module Ductwork
|
|
|
67
77
|
end
|
|
68
78
|
|
|
69
79
|
def expand(to:)
|
|
80
|
+
validate_classes!(to)
|
|
70
81
|
validate_definition_started!(action: "expanding chain")
|
|
71
82
|
add_edge_to_last_node(to, type: :expand)
|
|
72
83
|
add_new_nodes(to)
|
|
73
84
|
|
|
85
|
+
@expansions += 1
|
|
86
|
+
|
|
74
87
|
self
|
|
75
88
|
end
|
|
76
89
|
|
|
77
90
|
def collapse(into:)
|
|
91
|
+
validate_classes!(into)
|
|
78
92
|
validate_definition_started!(action: "collapsing steps")
|
|
79
93
|
validate_definition_expanded!
|
|
80
94
|
add_edge_to_last_node(into, type: :collapse)
|
|
81
95
|
add_new_nodes(into)
|
|
82
96
|
|
|
97
|
+
@expansions -= 1
|
|
98
|
+
|
|
83
99
|
self
|
|
84
100
|
end
|
|
85
101
|
|
|
86
102
|
def on_halt(klass)
|
|
103
|
+
validate_classes!(klass)
|
|
104
|
+
|
|
87
105
|
definition[:metadata] ||= {}
|
|
88
106
|
definition[:metadata][:on_halt] = {}
|
|
89
107
|
definition[:metadata][:on_halt][:klass] = klass.name
|
|
@@ -99,7 +117,25 @@ module Ductwork
|
|
|
99
117
|
|
|
100
118
|
private
|
|
101
119
|
|
|
102
|
-
attr_reader :definition
|
|
120
|
+
attr_reader :definition, :divisions, :expansions
|
|
121
|
+
|
|
122
|
+
def validate_classes!(klasses)
|
|
123
|
+
valid = Array(klasses).all? do |klass|
|
|
124
|
+
klass.is_a?(Class) &&
|
|
125
|
+
klass.method_defined?(:execute) &&
|
|
126
|
+
klass.instance_method(:execute).arity.zero?
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
if !valid
|
|
130
|
+
word = if Array(klasses).length > 1
|
|
131
|
+
"Arguments"
|
|
132
|
+
else
|
|
133
|
+
"Argument"
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
raise ArgumentError, "#{word} must be a valid step class"
|
|
137
|
+
end
|
|
138
|
+
end
|
|
103
139
|
|
|
104
140
|
def validate_start_once!
|
|
105
141
|
if definition[:nodes].any?
|
|
@@ -114,25 +150,17 @@ module Ductwork
|
|
|
114
150
|
end
|
|
115
151
|
|
|
116
152
|
def validate_definition_divided!
|
|
117
|
-
if
|
|
153
|
+
if divisions.zero?
|
|
118
154
|
raise CombineError, "Must divide pipeline definition before combining steps"
|
|
119
155
|
end
|
|
120
156
|
end
|
|
121
157
|
|
|
122
158
|
def validate_definition_expanded!
|
|
123
|
-
if
|
|
159
|
+
if expansions.zero?
|
|
124
160
|
raise CollapseError, "Must expand pipeline definition before collapsing steps"
|
|
125
161
|
end
|
|
126
162
|
end
|
|
127
163
|
|
|
128
|
-
def last_edge
|
|
129
|
-
last_edge_node = definition[:nodes].reverse.find do |node|
|
|
130
|
-
definition[:edges][node].any?
|
|
131
|
-
end
|
|
132
|
-
|
|
133
|
-
definition.dig(:edges, last_edge_node, -1)
|
|
134
|
-
end
|
|
135
|
-
|
|
136
164
|
def add_new_nodes(*klasses)
|
|
137
165
|
definition[:nodes].push(*klasses.map(&:name))
|
|
138
166
|
klasses.each do |klass|
|
data/lib/ductwork/engine.rb
CHANGED
|
@@ -10,5 +10,15 @@ module Ductwork
|
|
|
10
10
|
Ductwork.configuration ||= Ductwork::Configuration.new
|
|
11
11
|
Ductwork.configuration.logger ||= Rails.logger
|
|
12
12
|
end
|
|
13
|
+
|
|
14
|
+
initializer "ductwork.validate_definitions", after: :load_config_initializers do
|
|
15
|
+
ActiveSupport.on_load(:active_record) do
|
|
16
|
+
# Load steps and pipelines so definition validation runs and bugs
|
|
17
|
+
# can be caught simply by booting the app or running tests
|
|
18
|
+
loader = Rails.autoloaders.main
|
|
19
|
+
loader.eager_load_dir(Rails.root.join("app/steps"))
|
|
20
|
+
loader.eager_load_dir(Rails.root.join("app/pipelines"))
|
|
21
|
+
end
|
|
22
|
+
end
|
|
13
23
|
end
|
|
14
24
|
end
|
data/lib/ductwork/version.rb
CHANGED