gush 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/.travis.yml +13 -0
- data/Gemfile +1 -1
- data/README.md +51 -29
- data/bin/gush +7 -1
- data/gush.gemspec +10 -11
- data/lib/gush/cli/overview.rb +138 -0
- data/lib/gush/cli.rb +23 -125
- data/lib/gush/client.rb +47 -36
- data/lib/gush/configuration.rb +3 -5
- data/lib/gush/errors.rb +4 -3
- data/lib/gush/graph.rb +88 -0
- data/lib/gush/job.rb +34 -88
- data/lib/gush/json.rb +12 -0
- data/lib/gush/worker.rb +7 -20
- data/lib/gush/workflow.rb +66 -41
- data/lib/gush.rb +3 -3
- data/spec/features/workflows_spec.rb +31 -0
- data/spec/lib/gush/client_spec.rb +29 -32
- data/spec/lib/gush/job_spec.rb +38 -42
- data/spec/lib/gush/worker_spec.rb +30 -59
- data/spec/lib/gush/workflow_spec.rb +71 -123
- data/spec/lib/gush_spec.rb +1 -1
- data/spec/spec_helper.rb +26 -29
- metadata +39 -43
- data/lib/gush/logger_builder.rb +0 -15
- data/lib/gush/metadata.rb +0 -24
- data/lib/gush/null_logger.rb +0 -6
- data/lib/gush/version.rb +0 -3
- data/spec/lib/gush/logger_builder_spec.rb +0 -25
- data/spec/lib/gush/null_logger_spec.rb +0 -15
- data/spec/redis.conf +0 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7fa19439bb45ef12b63b393f7956aca1edd96ebe
|
4
|
+
data.tar.gz: 0ce4dc6cdc209c66e33248da59390b017a54a4e7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 79fa056cf641d929d5f61985a12cc734a9fd4946c3b6ada2d31fd1bbec3b34b2bb7fd2dbc22821a0e42710a37baa1fc72955e867fcbab7a1582cea2ba82df9db
|
7
|
+
data.tar.gz: 229f3550ff30f57ff4cb27eb0cd177d962cd604be9f2d9e8b420172a4543461eef3c430f00096287d88a136e7dacd5b11160d133dab94c7831171b076368fee2
|
data/.travis.yml
ADDED
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Gush
|
1
|
+
# Gush [](https://travis-ci.org/pokonski/gush)
|
2
2
|
|
3
3
|
Gush is a parallel workflow runner using only Redis as its message broker and Sidekiq for workers.
|
4
4
|
|
@@ -18,21 +18,9 @@ Or install it yourself as:
|
|
18
18
|
|
19
19
|
## Usage
|
20
20
|
|
21
|
-
Your project should contain a file called `Gushfile.rb` which loads all the necessary workflows for Sidekiq to use.
|
22
|
-
|
23
|
-
Example:
|
24
|
-
|
25
|
-
```ruby
|
26
|
-
require_relative './lib/your_project'
|
27
|
-
|
28
|
-
Dir[Rowlf.root.join("workflows/**/*.rb")].each do |file|
|
29
|
-
require file
|
30
|
-
end
|
31
|
-
```
|
32
|
-
|
33
21
|
### Defining workflows
|
34
22
|
|
35
|
-
The DSL for defining jobs consists of a single `run` method.
|
23
|
+
The DSL for defining jobs consists of a single `run` method.
|
36
24
|
Here is a complete example of a workflow you can create:
|
37
25
|
|
38
26
|
```ruby
|
@@ -63,6 +51,7 @@ bundle exec gush viz SampleWorkflow
|
|
63
51
|
For the Workflow above, the graph will look like this:
|
64
52
|
|
65
53
|

|
54
|
+
|
66
55
|
### Defining jobs
|
67
56
|
|
68
57
|
Jobs are classes inheriting from `Gush::Job`:
|
@@ -76,35 +65,54 @@ class FetchJob1 < Gush::Job
|
|
76
65
|
end
|
77
66
|
```
|
78
67
|
|
79
|
-
### Running
|
68
|
+
### Running workflows
|
80
69
|
|
81
|
-
|
70
|
+
Now that we have defined our workflow we can use it:
|
82
71
|
|
83
|
-
|
72
|
+
#### 1. Initialize and save it
|
84
73
|
|
74
|
+
```ruby
|
75
|
+
flow = SampleWorkflow.new
|
76
|
+
flow.save # saves workflow and its jobs to Redis
|
85
77
|
```
|
86
|
-
bundle exec gush create SampleWorkflow
|
87
|
-
```
|
88
78
|
|
89
|
-
|
79
|
+
**or:** you can also use a shortcut:
|
80
|
+
|
81
|
+
```ruby
|
82
|
+
flow = SampleWorkflow.create
|
83
|
+
```
|
90
84
|
|
91
|
-
#### 2.
|
85
|
+
#### 2. Start workflow
|
92
86
|
|
93
|
-
|
87
|
+
First you need to start Sidekiq workers:
|
94
88
|
|
95
89
|
```
|
96
90
|
bundle exec gush workers
|
97
91
|
```
|
98
92
|
|
99
|
-
|
100
|
-
|
101
|
-
Use your workflow_id returned by `create` command.
|
93
|
+
and then start your workflow:
|
102
94
|
|
95
|
+
```ruby
|
96
|
+
flow.start!
|
103
97
|
```
|
104
|
-
|
98
|
+
|
99
|
+
Now Gush will start processing jobs in background using Sidekiq
|
100
|
+
in the order defined in `configure` method inside Workflow.
|
101
|
+
|
102
|
+
|
103
|
+
### Checking status:
|
104
|
+
|
105
|
+
#### In Ruby:
|
106
|
+
|
107
|
+
```ruby
|
108
|
+
flow.reload
|
109
|
+
flow.status
|
110
|
+
#=> :running|:pending|:finished|:failed
|
105
111
|
```
|
106
112
|
|
107
|
-
|
113
|
+
`reload` is needed to see the latest status, since workflows are updated asynchronously.
|
114
|
+
|
115
|
+
#### Via CLI:
|
108
116
|
|
109
117
|
- of a specific workflow:
|
110
118
|
|
@@ -113,15 +121,29 @@ bundle gush start <workflow_id>
|
|
113
121
|
```
|
114
122
|
|
115
123
|
- of all created workflows:
|
116
|
-
|
124
|
+
|
117
125
|
```
|
118
126
|
bundle gush list
|
119
127
|
```
|
120
128
|
|
129
|
+
### Requiring workflows inside your projects
|
130
|
+
|
131
|
+
**Skip this step if using Gush inside Rails application, workflows will already be loaded**
|
132
|
+
|
133
|
+
When using Gush and its CLI commands you need a Gushfile.rb in root directory.
|
134
|
+
Gushfile should require all your Workflows and jobs, for example:
|
135
|
+
|
136
|
+
```ruby
|
137
|
+
require_relative './lib/your_project'
|
138
|
+
|
139
|
+
Dir[Rails.root.join("app/workflows/**/*.rb")].each do |file|
|
140
|
+
require file
|
141
|
+
end
|
142
|
+
```
|
121
143
|
|
122
144
|
## Contributing
|
123
145
|
|
124
|
-
1. Fork it ( http://github.com/
|
146
|
+
1. Fork it ( http://github.com/pokonski/gush/fork )
|
125
147
|
2. Create your feature branch (`git checkout -b my-new-feature`)
|
126
148
|
3. Commit your changes (`git commit -am 'Add some feature'`)
|
127
149
|
4. Push to the branch (`git push origin my-new-feature`)
|
data/bin/gush
CHANGED
@@ -9,4 +9,10 @@ $:.unshift File.expand_path("../../lib", bin_file)
|
|
9
9
|
|
10
10
|
require 'gush'
|
11
11
|
|
12
|
-
|
12
|
+
begin
|
13
|
+
Gush::CLI.start(ARGV)
|
14
|
+
rescue Gush::WorkflowNotFound
|
15
|
+
puts "Workflow not found".red
|
16
|
+
rescue Gush::DependencyLevelTooDeep
|
17
|
+
puts "Dependency level too deep. Perhaps you have a dependency cycle?".red
|
18
|
+
end
|
data/gush.gemspec
CHANGED
@@ -1,11 +1,10 @@
|
|
1
1
|
# coding: utf-8
|
2
2
|
lib = File.expand_path('../lib', __FILE__)
|
3
3
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
-
require 'gush/version'
|
5
4
|
|
6
5
|
Gem::Specification.new do |spec|
|
7
6
|
spec.name = "gush"
|
8
|
-
spec.version =
|
7
|
+
spec.version = "0.1"
|
9
8
|
spec.authors = ["Piotrek Okoński"]
|
10
9
|
spec.email = ["piotrek@okonski.org"]
|
11
10
|
spec.summary = "Fast and distributed workflow runner using only Sidekiq and Redis"
|
@@ -17,15 +16,15 @@ Gem::Specification.new do |spec|
|
|
17
16
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
18
17
|
spec.require_paths = ["lib"]
|
19
18
|
|
20
|
-
spec.add_dependency "sidekiq", "~> 3.
|
21
|
-
spec.add_dependency "yajl-ruby"
|
22
|
-
spec.add_dependency "redis", "~> 3.
|
23
|
-
spec.add_dependency "hiredis", "~> 0.
|
24
|
-
spec.add_dependency "ruby-graphviz"
|
25
|
-
spec.add_dependency "terminal-table"
|
26
|
-
spec.add_dependency "colorize"
|
27
|
-
spec.add_dependency "thor"
|
28
|
-
spec.add_dependency "launchy"
|
19
|
+
spec.add_dependency "sidekiq", "~> 3.3.4"
|
20
|
+
spec.add_dependency "yajl-ruby", "~> 1.2.1"
|
21
|
+
spec.add_dependency "redis", "~> 3.2.1"
|
22
|
+
spec.add_dependency "hiredis", "~> 0.6.0"
|
23
|
+
spec.add_dependency "ruby-graphviz", "~> 1.2.2"
|
24
|
+
spec.add_dependency "terminal-table", "~> 1.4.5"
|
25
|
+
spec.add_dependency "colorize", "~> 0.7.7"
|
26
|
+
spec.add_dependency "thor", "~> 0.19.1"
|
27
|
+
spec.add_dependency "launchy", "~> 2.4.3"
|
29
28
|
spec.add_development_dependency "bundler", "~> 1.5"
|
30
29
|
spec.add_development_dependency "rake"
|
31
30
|
spec.add_development_dependency "rspec", '~> 3.0.0'
|
@@ -0,0 +1,138 @@
|
|
1
|
+
module Gush
|
2
|
+
class CLI
|
3
|
+
class Overview
|
4
|
+
attr_reader :workflow
|
5
|
+
|
6
|
+
def initialize(workflow)
|
7
|
+
@workflow = workflow
|
8
|
+
end
|
9
|
+
|
10
|
+
def table
|
11
|
+
Terminal::Table.new(rows: rows)
|
12
|
+
end
|
13
|
+
|
14
|
+
def status
|
15
|
+
if workflow.failed?
|
16
|
+
failed_status
|
17
|
+
elsif workflow.running?
|
18
|
+
running_status
|
19
|
+
elsif workflow.finished?
|
20
|
+
"done".green
|
21
|
+
elsif workflow.stopped?
|
22
|
+
"stopped".red
|
23
|
+
else
|
24
|
+
"pending".light_white
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def jobs_list(jobs)
|
29
|
+
"\nJobs list:\n".tap do |output|
|
30
|
+
jobs_by_type(jobs).each do |job|
|
31
|
+
output << job_to_list_element(job)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
def rows
|
38
|
+
[].tap do |rows|
|
39
|
+
columns.each_pair do |name, value|
|
40
|
+
rows << [{alignment: :center, value: name}, value]
|
41
|
+
rows << :separator if name != "Status"
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def columns
|
47
|
+
{
|
48
|
+
"ID" => workflow.id,
|
49
|
+
"Name" => workflow.class.to_s,
|
50
|
+
"Jobs" => workflow.jobs.count,
|
51
|
+
"Failed jobs" => failed_jobs_count.red,
|
52
|
+
"Succeeded jobs" => succeeded_jobs_count.green,
|
53
|
+
"Enqueued jobs" => enqueued_jobs_count.yellow,
|
54
|
+
"Running jobs" => running_jobs_count.blue,
|
55
|
+
"Remaining jobs" => remaining_jobs_count,
|
56
|
+
"Status" => status
|
57
|
+
}
|
58
|
+
end
|
59
|
+
|
60
|
+
def running_status
|
61
|
+
finished = succeeded_jobs_count.to_i
|
62
|
+
status = "running".yellow
|
63
|
+
status += "\n#{finished}/#{total_jobs_count} [#{(finished*100)/total_jobs_count}%]"
|
64
|
+
end
|
65
|
+
|
66
|
+
def failed_status
|
67
|
+
status = "failed".light_red
|
68
|
+
status += "\n#{failed_job} failed"
|
69
|
+
end
|
70
|
+
|
71
|
+
def job_to_list_element(job)
|
72
|
+
name = job.name
|
73
|
+
case
|
74
|
+
when job.failed?
|
75
|
+
"[✗] #{name.red} \n"
|
76
|
+
when job.finished?
|
77
|
+
"[✓] #{name.green} \n"
|
78
|
+
when job.enqueued?
|
79
|
+
"[•] #{name.yellow} \n"
|
80
|
+
when job.running?
|
81
|
+
"[•] #{name.blue} \n"
|
82
|
+
else
|
83
|
+
"[ ] #{name} \n"
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def jobs_by_type(type)
|
88
|
+
return sorted_jobs if type == :all
|
89
|
+
jobs.select{|j| j.public_send("#{type}?") }
|
90
|
+
end
|
91
|
+
|
92
|
+
def sorted_jobs
|
93
|
+
workflow.jobs.sort_by do |job|
|
94
|
+
case
|
95
|
+
when job.failed?
|
96
|
+
0
|
97
|
+
when job.finished?
|
98
|
+
1
|
99
|
+
when job.enqueued?
|
100
|
+
2
|
101
|
+
when job.running?
|
102
|
+
3
|
103
|
+
else
|
104
|
+
4
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
def failed_job
|
110
|
+
workflow.jobs.find(&:failed).name
|
111
|
+
end
|
112
|
+
|
113
|
+
def total_jobs_count
|
114
|
+
workflow.jobs.count
|
115
|
+
end
|
116
|
+
|
117
|
+
def failed_jobs_count
|
118
|
+
workflow.jobs.count(&:failed?).to_s
|
119
|
+
end
|
120
|
+
|
121
|
+
def succeeded_jobs_count
|
122
|
+
workflow.jobs.count(&:succeeded?).to_s
|
123
|
+
end
|
124
|
+
|
125
|
+
def enqueued_jobs_count
|
126
|
+
workflow.jobs.count(&:enqueued?).to_s
|
127
|
+
end
|
128
|
+
|
129
|
+
def running_jobs_count
|
130
|
+
workflow.jobs.count(&:running?).to_s
|
131
|
+
end
|
132
|
+
|
133
|
+
def remaining_jobs_count
|
134
|
+
workflow.jobs.count{|j| [j.finished, j.failed, j.enqueued].none? }.to_s
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
data/lib/gush/cli.rb
CHANGED
@@ -22,6 +22,7 @@ module Gush
|
|
22
22
|
config.namespace = options.fetch("namespace", config.namespace)
|
23
23
|
config.environment = options.fetch("environment", config.environment)
|
24
24
|
end
|
25
|
+
load_gushfile
|
25
26
|
end
|
26
27
|
|
27
28
|
desc "create [WorkflowClass]", "Registers new workflow"
|
@@ -29,18 +30,12 @@ module Gush
|
|
29
30
|
workflow = client.create_workflow(name)
|
30
31
|
puts "Workflow created with id: #{workflow.id}"
|
31
32
|
puts "Start it with command: gush start #{workflow.id}"
|
32
|
-
rescue
|
33
|
-
puts "Workflow not found."
|
34
33
|
end
|
35
34
|
|
36
35
|
desc "start [workflow_id]", "Starts Workflow with given ID"
|
37
36
|
def start(*args)
|
38
37
|
id = args.shift
|
39
38
|
client.start_workflow(id, args)
|
40
|
-
rescue WorkflowNotFound
|
41
|
-
puts "Workflow not found."
|
42
|
-
rescue DependencyLevelTooDeep
|
43
|
-
puts "Dependency level too deep. Perhaps you have a dependency cycle?"
|
44
39
|
end
|
45
40
|
|
46
41
|
desc "create_and_start [WorkflowClass]", "Create and instantly start the new workflow"
|
@@ -48,18 +43,12 @@ module Gush
|
|
48
43
|
workflow = client.create_workflow(name)
|
49
44
|
client.start_workflow(workflow.id, args)
|
50
45
|
puts "Created and started workflow with id: #{workflow.id}"
|
51
|
-
rescue WorkflowNotFound
|
52
|
-
puts "Workflow not found."
|
53
|
-
rescue DependencyLevelTooDeep
|
54
|
-
puts "Dependency level too deep. Perhaps you have a dependency cycle?"
|
55
46
|
end
|
56
47
|
|
57
48
|
desc "stop [workflow_id]", "Stops Workflow with given ID"
|
58
49
|
def stop(*args)
|
59
50
|
id = args.shift
|
60
51
|
client.stop_workflow(id)
|
61
|
-
rescue WorkflowNotFound
|
62
|
-
puts "Workflow not found."
|
63
52
|
end
|
64
53
|
|
65
54
|
desc "clear", "Clears all jobs from Sidekiq queue"
|
@@ -77,16 +66,12 @@ module Gush
|
|
77
66
|
display_overview_for(workflow) unless options[:skip_overview]
|
78
67
|
|
79
68
|
display_jobs_list_for(workflow, options[:jobs]) unless options[:skip_jobs]
|
80
|
-
rescue WorkflowNotFound
|
81
|
-
puts "Workflow not found."
|
82
69
|
end
|
83
70
|
|
84
71
|
desc "rm [workflow_id]", "Delete workflow with given ID"
|
85
72
|
def rm(workflow_id)
|
86
73
|
workflow = client.find_workflow(workflow_id)
|
87
74
|
client.destroy_workflow(workflow)
|
88
|
-
rescue WorkflowNotFound
|
89
|
-
puts "Workflow not found."
|
90
75
|
end
|
91
76
|
|
92
77
|
desc "list", "Lists all workflows with their statuses"
|
@@ -112,44 +97,10 @@ module Gush
|
|
112
97
|
desc "viz [WorkflowClass]", "Displays graph, visualising job dependencies"
|
113
98
|
def viz(name)
|
114
99
|
client
|
115
|
-
workflow = name.constantize.new
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
g[:center] = true
|
120
|
-
g.node[:shape] = "ellipse"
|
121
|
-
g.node[:style] = "filled"
|
122
|
-
g.node[:color] = "#555555"
|
123
|
-
g.node[:fillcolor] = "white"
|
124
|
-
g.edge[:dir] = "forward"
|
125
|
-
g.edge[:penwidth] = 1
|
126
|
-
g.edge[:color] = "#555555"
|
127
|
-
start = g.start(shape: 'diamond', fillcolor: '#CFF09E')
|
128
|
-
end_node = g.end(shape: 'diamond', fillcolor: '#F56991')
|
129
|
-
|
130
|
-
|
131
|
-
workflow.nodes.each do |job|
|
132
|
-
name = job.class.to_s
|
133
|
-
g.add_nodes(name)
|
134
|
-
|
135
|
-
if job.incoming.empty?
|
136
|
-
g.add_edges(start, name)
|
137
|
-
end
|
138
|
-
|
139
|
-
|
140
|
-
if job.outgoing.empty?
|
141
|
-
g.add_edges(name, end_node)
|
142
|
-
else
|
143
|
-
job.outgoing.each do |out|
|
144
|
-
g.add_edges(name, out)
|
145
|
-
end
|
146
|
-
end
|
147
|
-
end
|
148
|
-
|
149
|
-
g.output(png: Pathname.new(Dir.tmpdir).join("graph.png"))
|
150
|
-
end
|
151
|
-
|
152
|
-
Launchy.open(Pathname.new(Dir.tmpdir).join("graph.png").to_s)
|
100
|
+
workflow = name.constantize.new
|
101
|
+
graph = Graph.new(workflow)
|
102
|
+
graph.viz
|
103
|
+
Launchy.open graph.path
|
153
104
|
end
|
154
105
|
|
155
106
|
private
|
@@ -158,88 +109,35 @@ module Gush
|
|
158
109
|
@client ||= Client.new
|
159
110
|
end
|
160
111
|
|
161
|
-
def
|
162
|
-
|
163
|
-
|
164
|
-
"id" => workflow.id,
|
165
|
-
"name" => workflow.class.to_s,
|
166
|
-
"jobs" => workflow.nodes.count,
|
167
|
-
"failed jobs" => workflow.nodes.count(&:failed?).to_s.red,
|
168
|
-
"succeeded jobs" => workflow.nodes.count(&:succeeded?).to_s.green,
|
169
|
-
"enqueued jobs" => workflow.nodes.count(&:enqueued?).to_s.yellow,
|
170
|
-
"running jobs" => workflow.nodes.count(&:running?).to_s.blue,
|
171
|
-
"remaining jobs" => workflow.nodes.count{|j| [j.finished, j.failed, j.enqueued].all? {|b| !b} },
|
172
|
-
"status" => status_for(workflow)
|
173
|
-
}
|
174
|
-
|
175
|
-
columns.each_pair do |name, value|
|
176
|
-
rows << [{alignment: :center, value: name}, value]
|
177
|
-
rows << :separator if name != "status"
|
178
|
-
end
|
112
|
+
def overview(workflow)
|
113
|
+
CLI::Overview.new(workflow)
|
114
|
+
end
|
179
115
|
|
180
|
-
|
116
|
+
def display_overview_for(workflow)
|
117
|
+
puts overview(workflow).table
|
181
118
|
end
|
182
119
|
|
183
120
|
def status_for(workflow)
|
184
|
-
|
185
|
-
status = "failed".light_red
|
186
|
-
status += "\n#{workflow.nodes.find(&:failed).name} failed"
|
187
|
-
elsif workflow.running?
|
188
|
-
status = "running".yellow
|
189
|
-
finished = workflow.nodes.count {|job| job.finished }
|
190
|
-
total = workflow.nodes.count
|
191
|
-
status += "\n#{finished}/#{total} [#{(finished*100)/total}%]"
|
192
|
-
elsif workflow.finished?
|
193
|
-
status = "done".green
|
194
|
-
elsif workflow.stopped?
|
195
|
-
status = "stopped".red
|
196
|
-
else
|
197
|
-
status = "pending".light_white
|
198
|
-
end
|
121
|
+
overview(workflow).status
|
199
122
|
end
|
200
123
|
|
201
124
|
def display_jobs_list_for(workflow, jobs)
|
202
|
-
puts
|
203
|
-
|
204
|
-
jobs_by_type(workflow, jobs).each do |job|
|
205
|
-
name = job.name
|
206
|
-
puts case
|
207
|
-
when job.failed?
|
208
|
-
"[✗] #{name.red}"
|
209
|
-
when job.finished?
|
210
|
-
"[✓] #{name.green}"
|
211
|
-
when job.enqueued?
|
212
|
-
"[•] #{name.yellow}"
|
213
|
-
when job.running?
|
214
|
-
"[•] #{name.blue}"
|
215
|
-
else
|
216
|
-
"[ ] #{name}"
|
217
|
-
end
|
218
|
-
end
|
219
|
-
end
|
220
|
-
|
221
|
-
def jobs_by_type(workflow, type)
|
222
|
-
jobs = workflow.nodes.sort_by do |job|
|
223
|
-
case
|
224
|
-
when job.failed?
|
225
|
-
0
|
226
|
-
when job.finished?
|
227
|
-
1
|
228
|
-
when job.enqueued?
|
229
|
-
2
|
230
|
-
when job.running?
|
231
|
-
3
|
232
|
-
else
|
233
|
-
4
|
234
|
-
end
|
235
|
-
end
|
236
|
-
|
237
|
-
jobs.select!{|j| j.public_send("#{type}?") } unless type == :all
|
238
|
-
jobs
|
125
|
+
puts overview(workflow).jobs_list(jobs)
|
239
126
|
end
|
240
127
|
|
241
128
|
def gushfile
|
242
129
|
Pathname.pwd.join(options[:gushfile])
|
243
130
|
end
|
131
|
+
|
132
|
+
def load_gushfile
|
133
|
+
file = client.configuration.gushfile
|
134
|
+
if !@gushfile.exist?
|
135
|
+
raise Thor::Error, "#{file} not found, please add it to your project".colorize(:red)
|
136
|
+
end
|
137
|
+
|
138
|
+
require file
|
139
|
+
rescue LoadError
|
140
|
+
raise Thor::Error, "failed to require #{file}".colorize(:red)
|
141
|
+
end
|
244
142
|
end
|
245
143
|
end
|