flow-lite 1.0.0 → 1.0.1
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/README.md +108 -17
- data/lib/flow-lite.rb +88 -21
- data/lib/flow-lite/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1f61f94156b9718eb74e5a99f9e9c1128f067588
|
4
|
+
data.tar.gz: b3da7ea83777db3cbe01609ae431bd4ce043ef1d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 49523aa490c50d6b4602090df7c135899f234b9649c406c6f5ca22967bc976732e3a3c5d6589b6c8ebdd31049651b53d2096a038e611a20a1aa5aa5b85f1565f
|
7
|
+
data.tar.gz: 4321ffd322f70a5288f68d697b4020a8389ac45f273c4f3fd88c7d5e54f104e48e6b1d5be32ee130df158472a69a64e97d0705f2f5380a03e2b474d25132ea37
|
data/README.md
CHANGED
@@ -10,6 +10,7 @@ flow-lite gem - (yet) another (lite) workflow engine; let's you define your work
|
|
10
10
|
|
11
11
|
|
12
12
|
|
13
|
+
|
13
14
|
## Usage
|
14
15
|
|
15
16
|
|
@@ -19,12 +20,12 @@ Define the workflow steps in a Flowfile. Example:
|
|
19
20
|
``` ruby
|
20
21
|
step :first_step do
|
21
22
|
puts "first_step"
|
22
|
-
second_step # note: you can call other steps
|
23
|
+
step :second_step # note: you can call other steps with step
|
23
24
|
end
|
24
25
|
|
25
26
|
step :second_step do
|
26
27
|
puts "second_step"
|
27
|
-
third_step
|
28
|
+
step :third_step
|
28
29
|
end
|
29
30
|
|
30
31
|
step :third_step do
|
@@ -39,7 +40,28 @@ Example:
|
|
39
40
|
$ flow first_step
|
40
41
|
```
|
41
42
|
|
42
|
-
Note: By default the `flow` command line tool reads in
|
43
|
+
Note: By default the `flow` command line tool reads in and looks for `flowfile`, `Flowfile`, `flowfile.rb`, `Flowfile.rb`
|
44
|
+
in that order.
|
45
|
+
Use the `-f/--flowfile` option to use a different file
|
46
|
+
and use the `-r/--require` to (auto-)require
|
47
|
+
some extra libraries or scripts.
|
48
|
+
By default for now the "prelude / prolog" that always
|
49
|
+
gets auto-required includes:
|
50
|
+
|
51
|
+
``` ruby
|
52
|
+
require 'pp'
|
53
|
+
require 'time'
|
54
|
+
require 'date'
|
55
|
+
require 'json'
|
56
|
+
require 'yaml'
|
57
|
+
require 'fileutils'
|
58
|
+
|
59
|
+
require 'uri'
|
60
|
+
require 'net/http'
|
61
|
+
require 'net/https'
|
62
|
+
```
|
63
|
+
|
64
|
+
Tip: See the [`flow-lite.rb`](https://github.com/rubycoco/git/blob/master/flow-lite/lib/flow-lite.rb) source for the definite always up-to-date list.
|
43
65
|
|
44
66
|
|
45
67
|
That's it for now.
|
@@ -66,14 +88,17 @@ flowfile = Flow::Flowfile.load( <<TXT )
|
|
66
88
|
end
|
67
89
|
TXT
|
68
90
|
|
69
|
-
flow = flowfile.
|
70
|
-
|
71
|
-
flow.
|
72
|
-
flow.
|
91
|
+
flow = flowfile.flow_class.new # (auto-)build a flow class (see Note 1)
|
92
|
+
# and construct/return a new instance
|
93
|
+
flow.step_hello #=> "Hello, world!"
|
94
|
+
flow.step_hola #=> "¡Hola, mundo!"
|
95
|
+
flow.step( :hello ) #=> "Hello, world!"
|
96
|
+
flow.step( :hola ) #=> "¡Hola, mundo!"
|
97
|
+
flow.class.step_methods #=> [:hello, :hola]
|
73
98
|
|
74
99
|
# or use ruby's (regular) message/metaprogramming machinery
|
75
|
-
flow.send( :
|
76
|
-
flow.send( :
|
100
|
+
flow.send( :step_hello ) #=> "Hello, world!"
|
101
|
+
flow.send( :step_hola ) #=> "¡Hola, mundo!"
|
77
102
|
# or try
|
78
103
|
flow.class.instance_methods.grep( /^step_/ ) #=> [:step_hello, :step_hola]
|
79
104
|
# ...
|
@@ -95,19 +120,40 @@ gets used to (auto-) build (via metaprogramming) a flow class like:
|
|
95
120
|
|
96
121
|
``` ruby
|
97
122
|
class Greeter < Flow::Base
|
98
|
-
def
|
123
|
+
def step_hello
|
99
124
|
puts "Hello, world!"
|
100
125
|
end
|
101
|
-
alias_method :step_hello, :hello
|
102
126
|
|
103
|
-
def
|
127
|
+
def step_hola
|
104
128
|
puts "¡Hola, mundo!"
|
105
129
|
end
|
106
|
-
alias_method :step_hola, :hola
|
107
130
|
end
|
108
131
|
```
|
109
132
|
|
110
133
|
|
134
|
+
Note: Behind the stage the metaprogramming "class macro"
|
135
|
+
`define_step( symbol, method )`
|
136
|
+
or `define_step( symbol ) { block }` defined in `Flow::Base`
|
137
|
+
gets used, thus,
|
138
|
+
if you want to create steps in a "hand-coded" class
|
139
|
+
use:
|
140
|
+
|
141
|
+
|
142
|
+
``` ruby
|
143
|
+
class Greeter < Flow::Base
|
144
|
+
define_step :hello do
|
145
|
+
puts "Hello, world!"
|
146
|
+
end
|
147
|
+
|
148
|
+
define_step :hola do
|
149
|
+
puts "¡Hola, mundo!"
|
150
|
+
end
|
151
|
+
end
|
152
|
+
```
|
153
|
+
|
154
|
+
|
155
|
+
|
156
|
+
|
111
157
|
|
112
158
|
**Tips & Tricks**
|
113
159
|
|
@@ -115,7 +161,7 @@ Auto-include pre-build / pre-defined steps. Use a (regular) Module e.g.:
|
|
115
161
|
|
116
162
|
``` ruby
|
117
163
|
module GitHubActions
|
118
|
-
def
|
164
|
+
def step_setup
|
119
165
|
# setup ssh
|
120
166
|
ssh_key = ENV['SSH_KEY']
|
121
167
|
ssh_path = File.expand_path( '~/.ssh' )
|
@@ -133,8 +179,6 @@ module GitHubActions
|
|
133
179
|
|
134
180
|
# ...
|
135
181
|
end
|
136
|
-
# optional - for auto-discovery add a step alias
|
137
|
-
alias_method :step_setup, :setup
|
138
182
|
end
|
139
183
|
```
|
140
184
|
|
@@ -150,7 +194,54 @@ end
|
|
150
194
|
Flow::Base.include( GitHubActions )
|
151
195
|
```
|
152
196
|
|
153
|
-
Now all your flows can (re)use `setup` or any other methods you define.
|
197
|
+
Now all your flows can (re)use `setup` or any other step methods you define.
|
198
|
+
|
199
|
+
|
200
|
+
|
201
|
+
|
202
|
+
## Real World Examples
|
203
|
+
|
204
|
+
**Collect GitHub Statistics**
|
205
|
+
|
206
|
+
Use GitHub Actions to collect
|
207
|
+
GitHub Statistics via GitHub API calls
|
208
|
+
and update the JSON datasets
|
209
|
+
in the `/cache.github` repo at the `yorobot` org(anization):
|
210
|
+
|
211
|
+
``` ruby
|
212
|
+
step :clone do
|
213
|
+
Mono.clone( '@yorobot/cache.github' )
|
214
|
+
end
|
215
|
+
|
216
|
+
|
217
|
+
step :update do
|
218
|
+
Hubba.config.data_dir = Mono.real_path( '@yorobot/cache.github' )
|
219
|
+
|
220
|
+
username = 'geraldb'
|
221
|
+
h = Hubba.reposet( username )
|
222
|
+
pp h
|
223
|
+
|
224
|
+
Hubba.update_stats( h )
|
225
|
+
Hubba.update_traffic( h )
|
226
|
+
puts "Done."
|
227
|
+
end
|
228
|
+
|
229
|
+
|
230
|
+
step :push do
|
231
|
+
msg = "auto-update week #{Date.today.cweek}"
|
232
|
+
|
233
|
+
Mono.open( '@yorobot/cache.github' ) do |proj|
|
234
|
+
if proj.changes?
|
235
|
+
proj.add( "." )
|
236
|
+
proj.commit( msg )
|
237
|
+
proj.push
|
238
|
+
end
|
239
|
+
end
|
240
|
+
end
|
241
|
+
```
|
242
|
+
|
243
|
+
(Sources: [`Flowfile`](https://github.com/yorobot/backup/blob/master/Flowfile.rb), [`workflows/update.yml`](https://github.com/yorobot/backup/blob/master/.github/workflows/update.yml) @ `yorobot/backup`)
|
244
|
+
|
154
245
|
|
155
246
|
|
156
247
|
|
data/lib/flow-lite.rb
CHANGED
@@ -44,25 +44,70 @@ end # class Step
|
|
44
44
|
|
45
45
|
|
46
46
|
class Base ## base class for flow class (auto)-constructed/build from flowfile
|
47
|
-
def self.define_step(
|
48
|
-
|
47
|
+
def self.define_step( name_or_names, &block )
|
48
|
+
names = if name_or_names.is_a?( Array )
|
49
|
+
name_or_names
|
50
|
+
else
|
51
|
+
[name_or_names] ## assume single symbol (name); wrap in array
|
52
|
+
end
|
53
|
+
names = names.map {|name| name.to_sym } ## make sure we always use symbols
|
54
|
+
|
55
|
+
|
56
|
+
name = names[0]
|
49
57
|
puts "[flow] adding step >#{name}<..."
|
50
|
-
define_method( name, &
|
51
|
-
alias_method( :"step_#{name}", name ) ## (auto-)add step_<name> alias
|
58
|
+
define_method( :"step_#{name}", &block )
|
52
59
|
|
53
|
-
alt_names =
|
60
|
+
alt_names = names[1..-1]
|
54
61
|
alt_names.each do |alt_name|
|
55
62
|
puts "[flow] adding alias >#{alt_name}< for >#{name}<..."
|
56
|
-
alias_method( alt_name, name )
|
63
|
+
alias_method( :"step_#{alt_name}", :"step_#{name}" )
|
64
|
+
end
|
65
|
+
end # method self.define_step
|
66
|
+
|
67
|
+
|
68
|
+
|
69
|
+
## run step by symbol/name (e.g. step :hello - etc.)
|
70
|
+
def step( name )
|
71
|
+
name = :"step_#{name}" ## note: make sure we always use symbols
|
72
|
+
if respond_to?( name )
|
73
|
+
send( name )
|
74
|
+
else
|
75
|
+
puts "!! ERROR: step definition >#{name}< not found; cannot run/execute - known (defined) steps include:"
|
76
|
+
pp self.class.step_methods #=> e.g. [:hello, ...]
|
77
|
+
exit 1
|
57
78
|
end
|
79
|
+
end # method step
|
80
|
+
|
81
|
+
def self.step_methods
|
82
|
+
names = instance_methods.reduce([]) do |names, name|
|
83
|
+
names << $1.to_sym if name =~ /^step_(.+)/
|
84
|
+
names
|
85
|
+
end
|
86
|
+
names
|
58
87
|
end
|
59
88
|
end # class Base
|
60
89
|
|
61
90
|
|
62
91
|
|
92
|
+
|
63
93
|
class Flowfile
|
94
|
+
|
95
|
+
## find flowfile path by convention
|
96
|
+
## check for name by convention in this order:
|
97
|
+
FLOWFILES = ['flowfile', 'Flowfile',
|
98
|
+
'flowfile.rb', 'Flowfile.rb']
|
99
|
+
def self.find_file
|
100
|
+
FLOWFILES.each do |name|
|
101
|
+
return "./#{name}" if File.exist?( "./#{name}" )
|
102
|
+
end
|
103
|
+
|
104
|
+
STDERR.puts "!! ERROR - no flowfile found, sorry - looking for: #{FLOWFILES.join(', ')} in (#{Dir.pwd})"
|
105
|
+
exit 1
|
106
|
+
end # method self.find_file
|
107
|
+
|
108
|
+
|
64
109
|
## convenience method - use like Flowfile.load_file()
|
65
|
-
def self.load_file( path=
|
110
|
+
def self.load_file( path=find_file )
|
66
111
|
code = File.open( path, 'r:utf-8' ) { |f| f.read }
|
67
112
|
load( code )
|
68
113
|
end
|
@@ -76,9 +121,13 @@ class Flowfile
|
|
76
121
|
|
77
122
|
|
78
123
|
|
79
|
-
def flow
|
124
|
+
def flow
|
125
|
+
## todo/check: always return a new instance why? why not?
|
126
|
+
flow_class.new
|
127
|
+
end
|
128
|
+
|
129
|
+
def flow_class
|
80
130
|
@flow_class ||= build_flow_class
|
81
|
-
@flow_class.new ## todo/check: always return a new instance why? why not?
|
82
131
|
end
|
83
132
|
|
84
133
|
def build_flow_class
|
@@ -86,7 +135,7 @@ class Flowfile
|
|
86
135
|
klass = Class.new( Base )
|
87
136
|
|
88
137
|
steps.each do |step|
|
89
|
-
klass.define_step( step )
|
138
|
+
klass.define_step( step.names, &step.block )
|
90
139
|
end
|
91
140
|
|
92
141
|
klass
|
@@ -106,21 +155,15 @@ class Flowfile
|
|
106
155
|
@steps << Step.new( name, block )
|
107
156
|
end
|
108
157
|
|
109
|
-
|
110
158
|
def run( name )
|
111
|
-
|
112
|
-
|
113
|
-
flow.send( name )
|
114
|
-
else
|
115
|
-
puts "!! ERROR: step definition >#{name}< not found; cannot run/execute - known steps include:"
|
116
|
-
pp @steps
|
117
|
-
exit 1
|
118
|
-
end
|
159
|
+
## todo/check: always return/use a new instance why? why not?
|
160
|
+
flow_class.new.step( name )
|
119
161
|
end
|
120
162
|
end # class Flowfile
|
121
163
|
|
122
164
|
|
123
165
|
|
166
|
+
|
124
167
|
class Tool
|
125
168
|
def self.main( args=ARGV )
|
126
169
|
options = {}
|
@@ -128,17 +171,41 @@ class Tool
|
|
128
171
|
parser.on( '-f FILENAME', '--flowfile FILENAME' ) do |filename|
|
129
172
|
options[:flowfile] = filename
|
130
173
|
end
|
174
|
+
|
175
|
+
## note:
|
176
|
+
## you can add many/multiple modules
|
177
|
+
## e.g. -r gitti -r mono etc.
|
178
|
+
parser.on( '-r NAME', '--require NAME') do |name|
|
179
|
+
options[:requires] ||= []
|
180
|
+
options[:requires] << name
|
181
|
+
end
|
131
182
|
end.parse!( args )
|
132
183
|
|
133
|
-
|
184
|
+
|
185
|
+
## check for any (dynamic/auto) requires
|
186
|
+
if options[:requires]
|
187
|
+
names = options[:requires]
|
188
|
+
names.each do |name|
|
189
|
+
## todo/check: add some error/exception handling here - why? why not?
|
190
|
+
puts "[flow] (auto-)require >#{name}<..."
|
191
|
+
require( name )
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
|
196
|
+
path = options[:flowfile] || Flowfile.find_file
|
197
|
+
|
198
|
+
|
199
|
+
puts "[flow] loading >#{path}<..."
|
134
200
|
flowfile = Flowfile.load_file( path )
|
135
201
|
|
202
|
+
|
136
203
|
## allow multipe steps getting called - why? why not?
|
137
204
|
## flow setup clone update etc??
|
138
205
|
args.each do |arg|
|
139
206
|
flowfile.run( arg )
|
140
207
|
end
|
141
|
-
end
|
208
|
+
end # method self.main
|
142
209
|
end # class Tool
|
143
210
|
|
144
211
|
end # module Flow
|
data/lib/flow-lite/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: flow-lite
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Gerald Bauer
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-10-
|
11
|
+
date: 2020-10-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rdoc
|