tumugi 0.6.3 → 0.7.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/.travis.yml +1 -1
- data/CHANGELOG.md +27 -1
- data/examples/event_callbacks.rb +37 -0
- data/lib/tumugi/cli.rb +14 -6
- data/lib/tumugi/command/new.rb +16 -60
- data/lib/tumugi/command/new/generator.rb +76 -0
- data/lib/tumugi/command/new/plugin_generator.rb +60 -0
- data/lib/tumugi/command/new/project_generator.rb +45 -0
- data/lib/tumugi/command/run.rb +2 -9
- data/lib/tumugi/dag_result_reporter.rb +5 -5
- data/lib/tumugi/data/new/{Gemfile.erb → plugin/Gemfile.erb} +0 -0
- data/lib/tumugi/data/new/{README.md.erb → plugin/README.md.erb} +0 -0
- data/lib/tumugi/data/new/{Rakefile.erb → plugin/Rakefile.erb} +0 -0
- data/lib/tumugi/data/new/{examples → plugin/examples}/example.rb.erb +0 -0
- data/lib/tumugi/data/new/{gemspec.erb → plugin/gemspec.erb} +0 -0
- data/lib/tumugi/data/new/{gitignore.erb → plugin/gitignore.erb} +0 -0
- data/lib/tumugi/data/new/{lib → plugin/lib}/tumugi/plugin/target/target.rb.erb +0 -0
- data/lib/tumugi/data/new/{lib → plugin/lib}/tumugi/plugin/task/task.rb.erb +0 -0
- data/lib/tumugi/data/new/{test → plugin/test}/plugin/target/target_test.rb.erb +0 -0
- data/lib/tumugi/data/new/{test → plugin/test}/plugin/task/task_test.rb.erb +0 -0
- data/lib/tumugi/data/new/{test → plugin/test}/test.rb.erb +0 -0
- data/lib/tumugi/data/new/{test → plugin/test}/test_helper.rb.erb +0 -0
- data/lib/tumugi/data/new/project/Gemfile.erb +3 -0
- data/lib/tumugi/data/new/project/tumugi_config.rb.erb +33 -0
- data/lib/tumugi/data/new/project/workflow.rb.erb +3 -0
- data/lib/tumugi/event.rb +11 -0
- data/lib/tumugi/executor/local_executor.rb +16 -12
- data/lib/tumugi/mixin/human_readable.rb +16 -0
- data/lib/tumugi/parameter/parameter.rb +10 -8
- data/lib/tumugi/task.rb +46 -3
- data/lib/tumugi/task_definition.rb +32 -4
- data/lib/tumugi/version.rb +1 -1
- data/lib/tumugi/workflow.rb +27 -11
- metadata +23 -14
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: e1245ddebd2d69768433b3cfdea9ea0c3e39cff8
|
|
4
|
+
data.tar.gz: f40eded5362a22f951caf384411387758fb668ce
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: e1d78046c13e29e2f0cff749e54cfb020256de583c5561c9664edbabfcdae7a45fc64918b5cb4582a0ea7321e8f87932e0470365f142e12c792b82e432d94bff
|
|
7
|
+
data.tar.gz: b6745f25485a5aaa1e6ad494e468640209839fe77a7952ba955f888554f41764ccd31c6c983b04e6030a82e2e040f51af01d8f8d7c51b097ec62016ea5eb0bd0
|
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,28 @@
|
|
|
1
1
|
# Change Log
|
|
2
2
|
|
|
3
|
-
## [v0.
|
|
3
|
+
## [v0.7.0](https://github.com/tumugi/tumugi/tree/v0.7.0) (2016-11-01)
|
|
4
|
+
[Full Changelog](https://github.com/tumugi/tumugi/compare/v0.6.3...v0.7.0)
|
|
5
|
+
|
|
6
|
+
**Implemented enhancements:**
|
|
7
|
+
|
|
8
|
+
- Force run all tasks in a workflow [\#125](https://github.com/tumugi/tumugi/issues/125)
|
|
9
|
+
- Custom callback on success/retry/failure for each task [\#122](https://github.com/tumugi/tumugi/issues/122)
|
|
10
|
+
- Add secret option for parameter [\#117](https://github.com/tumugi/tumugi/issues/117)
|
|
11
|
+
- Add log about elapsed time for each tasks and workflow [\#116](https://github.com/tumugi/tumugi/issues/116)
|
|
12
|
+
- \[Breaking Change\] Introduce subcommand of `tumugi new` [\#111](https://github.com/tumugi/tumugi/issues/111)
|
|
13
|
+
|
|
14
|
+
**Merged pull requests:**
|
|
15
|
+
|
|
16
|
+
- Introduce success/failure event callback [\#128](https://github.com/tumugi/tumugi/pull/128) ([hakobera](https://github.com/hakobera))
|
|
17
|
+
- Support force run all tasks [\#127](https://github.com/tumugi/tumugi/pull/127) ([hakobera](https://github.com/hakobera))
|
|
18
|
+
- Write workflow and task elapsed time to log [\#124](https://github.com/tumugi/tumugi/pull/124) ([hakobera](https://github.com/hakobera))
|
|
19
|
+
- Filter coverage target files [\#121](https://github.com/tumugi/tumugi/pull/121) ([hakobera](https://github.com/hakobera))
|
|
20
|
+
- Test with jruby-9.1.5.0 on travis [\#120](https://github.com/tumugi/tumugi/pull/120) ([hakobera](https://github.com/hakobera))
|
|
21
|
+
- Introduce new sub commands [\#119](https://github.com/tumugi/tumugi/pull/119) ([hakobera](https://github.com/hakobera))
|
|
22
|
+
- Add param secret option [\#118](https://github.com/tumugi/tumugi/pull/118) ([hakobera](https://github.com/hakobera))
|
|
23
|
+
- Bumpup version to 0.7.0.dev [\#115](https://github.com/tumugi/tumugi/pull/115) ([hakobera](https://github.com/hakobera))
|
|
24
|
+
|
|
25
|
+
## [v0.6.3](https://github.com/tumugi/tumugi/tree/v0.6.3) (2016-08-13)
|
|
4
26
|
[Full Changelog](https://github.com/tumugi/tumugi/compare/v0.6.2...v0.6.3)
|
|
5
27
|
|
|
6
28
|
**Implemented enhancements:**
|
|
@@ -12,6 +34,10 @@
|
|
|
12
34
|
- Fix plugin template [\#112](https://github.com/tumugi/tumugi/pull/112) ([hakobera](https://github.com/hakobera))
|
|
13
35
|
- Fix commad failed error message [\#110](https://github.com/tumugi/tumugi/pull/110) ([hakobera](https://github.com/hakobera))
|
|
14
36
|
|
|
37
|
+
**Merged pull requests:**
|
|
38
|
+
|
|
39
|
+
- Prepare release for 0.6.3 [\#114](https://github.com/tumugi/tumugi/pull/114) ([hakobera](https://github.com/hakobera))
|
|
40
|
+
|
|
15
41
|
## [v0.6.2](https://github.com/tumugi/tumugi/tree/v0.6.2) (2016-08-02)
|
|
16
42
|
[Full Changelog](https://github.com/tumugi/tumugi/compare/v0.6.1...v0.6.2)
|
|
17
43
|
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
task :task1 do
|
|
2
|
+
requires [:task2, :task3]
|
|
3
|
+
run { log 'task1#run' }
|
|
4
|
+
end
|
|
5
|
+
|
|
6
|
+
task :task2 do
|
|
7
|
+
requires [:task4]
|
|
8
|
+
run { raise "error in #{id}" }
|
|
9
|
+
on_retry do
|
|
10
|
+
log 'task2#on_retry'
|
|
11
|
+
end
|
|
12
|
+
on_failure do
|
|
13
|
+
log 'task2#on_failure'
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
task :task3 do
|
|
18
|
+
requires [:task4]
|
|
19
|
+
run { log 'task3#run' }
|
|
20
|
+
on_success do
|
|
21
|
+
log 'task3#on_success'
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
task :task4 do
|
|
26
|
+
run do
|
|
27
|
+
log 'task4#run'
|
|
28
|
+
sleep 1
|
|
29
|
+
end
|
|
30
|
+
on_success do
|
|
31
|
+
log 'task4#on_success'
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
on_failure do
|
|
36
|
+
log 'task1#on_failure'
|
|
37
|
+
end
|
data/lib/tumugi/cli.rb
CHANGED
|
@@ -30,6 +30,7 @@ module Tumugi
|
|
|
30
30
|
map "run" => "run_" # run is thor's reserved word, so this trick is needed
|
|
31
31
|
option :workers, aliases: '-w', type: :numeric, desc: 'Number of workers to run task concurrently'
|
|
32
32
|
option :out, aliases: '-o', desc: 'Output log filename. If not specified, log is write to STDOUT'
|
|
33
|
+
option :all, aliases: '-a', type: :boolean, desc: 'Run all tasks even if target exists', default: false
|
|
33
34
|
common_options
|
|
34
35
|
def run_(task)
|
|
35
36
|
execute(:run, task, options)
|
|
@@ -45,9 +46,14 @@ module Tumugi
|
|
|
45
46
|
execute(:show, task, opts.freeze)
|
|
46
47
|
end
|
|
47
48
|
|
|
48
|
-
desc "new
|
|
49
|
-
def new(name)
|
|
50
|
-
|
|
49
|
+
desc "new type NAME", "Create a new template of type. type is 'plugin' or 'project'"
|
|
50
|
+
def new(type, name)
|
|
51
|
+
generate_project(type, name, options)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
desc "init", "Create an tumugi project template"
|
|
55
|
+
def init(path='')
|
|
56
|
+
generate_project('project', path, force: true)
|
|
51
57
|
end
|
|
52
58
|
|
|
53
59
|
private
|
|
@@ -55,6 +61,7 @@ module Tumugi
|
|
|
55
61
|
def execute(command, task, options)
|
|
56
62
|
logger.info "tumugi v#{Tumugi::VERSION}"
|
|
57
63
|
args = { task: task, options: options }
|
|
64
|
+
logger.info "status: running, command: #{command}, args: #{args}"
|
|
58
65
|
success = Tumugi.workflow.execute(command, task, options)
|
|
59
66
|
unless success
|
|
60
67
|
raise Thor::Error, "execute finished, but failed"
|
|
@@ -64,10 +71,11 @@ module Tumugi
|
|
|
64
71
|
handle_error(command, e, args)
|
|
65
72
|
end
|
|
66
73
|
|
|
67
|
-
def
|
|
74
|
+
def generate_project(type, name, options)
|
|
68
75
|
logger.info "tumugi v#{Tumugi::VERSION}"
|
|
69
|
-
args = { name: name, options: options }
|
|
70
|
-
|
|
76
|
+
args = { type: type, name: name, options: options }
|
|
77
|
+
logger.info "status: running, command: new, args: #{args}"
|
|
78
|
+
Tumugi::Command::New.new.execute(type, name, options)
|
|
71
79
|
logger.info "status: success, command: new, args: #{args}"
|
|
72
80
|
rescue => e
|
|
73
81
|
handle_error("new", e, args)
|
data/lib/tumugi/command/new.rb
CHANGED
|
@@ -1,71 +1,27 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
require_relative './new/plugin_generator'
|
|
2
|
+
require_relative './new/project_generator'
|
|
3
3
|
|
|
4
4
|
module Tumugi
|
|
5
5
|
module Command
|
|
6
6
|
class New
|
|
7
|
-
def execute(name, options={})
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
[ "Gemfile.erb", "Gemfile" ],
|
|
11
|
-
[ "gemspec.erb", "#{full_project_name}.gemspec" ],
|
|
12
|
-
[ "gitignore.erb", ".gitignore" ],
|
|
13
|
-
[ "Rakefile.erb", "Rakefile" ],
|
|
14
|
-
[ "README.md.erb", "README.md" ],
|
|
15
|
-
[ "examples/example.rb.erb", "examples/example.rb" ],
|
|
16
|
-
[ "lib/tumugi/plugin/target/target.rb.erb", "lib/tumugi/plugin/target/#{name}.rb" ],
|
|
17
|
-
[ "lib/tumugi/plugin/task/task.rb.erb", "lib/tumugi/plugin/task/#{name}.rb" ],
|
|
18
|
-
[ "test/test_helper.rb.erb", "test/test_helper.rb" ],
|
|
19
|
-
[ "test/test.rb.erb", "test/#{name}_test.rb" ],
|
|
20
|
-
[ "test/plugin/target/target_test.rb.erb", "test/plugin/target/#{name}_test.rb" ],
|
|
21
|
-
[ "test/plugin/task/task_test.rb.erb", "test/plugin/task/#{name}_test.rb" ],
|
|
22
|
-
]
|
|
23
|
-
|
|
24
|
-
@data_dir = "#{File.expand_path(File.dirname(__FILE__))}/../data/new"
|
|
25
|
-
@dest_dir = "#{(options[:path] || '.')}/#{full_project_name}"
|
|
26
|
-
if File.exist?(@dest_dir)
|
|
27
|
-
puts "#{@dest_dir} is already exists. Please delete it first"
|
|
28
|
-
return false
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
puts "Create #{@dest_dir}"
|
|
32
|
-
FileUtils.mkdir_p(@dest_dir)
|
|
33
|
-
|
|
34
|
-
templates.each do |value|
|
|
35
|
-
src_file, dest_file = value
|
|
36
|
-
eruby = Erubis::Eruby.new(File.read(src_path(src_file)))
|
|
37
|
-
eruby.filename = src_path(src_file)
|
|
38
|
-
context = {
|
|
39
|
-
full_project_name: full_project_name,
|
|
40
|
-
name: name,
|
|
41
|
-
tumugi_version: Tumugi::VERSION,
|
|
42
|
-
}
|
|
43
|
-
puts " Create #{dest_path(dest_file)}"
|
|
44
|
-
FileUtils.mkdir_p(File.dirname(dest_path(dest_file)))
|
|
45
|
-
File.write(dest_path(dest_file), eruby.result(context))
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
puts ""
|
|
49
|
-
puts "Plugin template is successfully generated."
|
|
50
|
-
puts "Next steps:"
|
|
51
|
-
puts ""
|
|
52
|
-
puts " $ cd #{full_project_name}"
|
|
53
|
-
puts " $ git init"
|
|
54
|
-
puts " $ bundle install"
|
|
55
|
-
puts " $ bundle exec rake"
|
|
56
|
-
puts ""
|
|
57
|
-
|
|
58
|
-
return true
|
|
7
|
+
def execute(type, name, options={})
|
|
8
|
+
generator = create_generator(type, name, options)
|
|
9
|
+
generator.generate
|
|
59
10
|
end
|
|
60
11
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
def src_path(file)
|
|
64
|
-
"#{@data_dir}/#{file}"
|
|
12
|
+
def logger
|
|
13
|
+
@logger ||= Tumugi::ScopedLogger.new("tumugi-new")
|
|
65
14
|
end
|
|
66
15
|
|
|
67
|
-
def
|
|
68
|
-
|
|
16
|
+
def create_generator(type, name, options)
|
|
17
|
+
case type
|
|
18
|
+
when "plugin"
|
|
19
|
+
PluginGenerator.new(name, options)
|
|
20
|
+
when "project"
|
|
21
|
+
ProjectGenerator.new(name, options)
|
|
22
|
+
else
|
|
23
|
+
raise Tumugi::TumugiError.new("Unsupported type of new sub command: #{type}")
|
|
24
|
+
end
|
|
69
25
|
end
|
|
70
26
|
end
|
|
71
27
|
end
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
require 'fileutils'
|
|
2
|
+
require 'erubis'
|
|
3
|
+
|
|
4
|
+
module Tumugi
|
|
5
|
+
module Command
|
|
6
|
+
class New
|
|
7
|
+
class Generator
|
|
8
|
+
attr_reader :name, :options
|
|
9
|
+
|
|
10
|
+
def initialize(name, options={})
|
|
11
|
+
@name = name
|
|
12
|
+
@options = options
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def generate
|
|
16
|
+
if File.exist?(dest_dir) && !options[:force]
|
|
17
|
+
logger.error "#{dest_dir} is already exists. Please delete it first"
|
|
18
|
+
return false
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
logger.info "Create #{dest_dir}"
|
|
22
|
+
FileUtils.mkdir_p(dest_dir)
|
|
23
|
+
|
|
24
|
+
templates.each do |value|
|
|
25
|
+
src_file, dest_file = value
|
|
26
|
+
eruby = Erubis::Eruby.new(File.read(src_path(src_file)))
|
|
27
|
+
eruby.filename = src_path(src_file)
|
|
28
|
+
logger.info " Create #{dest_path(dest_file)}"
|
|
29
|
+
FileUtils.mkdir_p(File.dirname(dest_path(dest_file)))
|
|
30
|
+
File.write(dest_path(dest_file), eruby.result(context))
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
unless post_messages.empty?
|
|
34
|
+
post_messages.each{|msg| logger.info msg }
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
true
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def data_dir
|
|
41
|
+
nil
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def dest_dir
|
|
45
|
+
nil
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def templates
|
|
49
|
+
[]
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def context
|
|
53
|
+
{}
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def post_messages
|
|
57
|
+
[]
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def logger
|
|
61
|
+
@logger ||= Tumugi::ScopedLogger.new("tumugi-new")
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
private
|
|
65
|
+
|
|
66
|
+
def src_path(file)
|
|
67
|
+
File.join(data_dir, file)
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def dest_path(file)
|
|
71
|
+
File.join(dest_dir, file)
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
require_relative 'generator'
|
|
2
|
+
|
|
3
|
+
module Tumugi
|
|
4
|
+
module Command
|
|
5
|
+
class New
|
|
6
|
+
class PluginGenerator < Generator
|
|
7
|
+
def data_dir
|
|
8
|
+
"#{File.expand_path(File.dirname(__FILE__))}/../../data/new/plugin"
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def dest_dir
|
|
12
|
+
File.join(options[:path] || '.', full_project_name)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def templates
|
|
16
|
+
[
|
|
17
|
+
[ "Gemfile.erb", "Gemfile" ],
|
|
18
|
+
[ "gemspec.erb", "#{full_project_name}.gemspec" ],
|
|
19
|
+
[ "gitignore.erb", ".gitignore" ],
|
|
20
|
+
[ "Rakefile.erb", "Rakefile" ],
|
|
21
|
+
[ "README.md.erb", "README.md" ],
|
|
22
|
+
[ "examples/example.rb.erb", "examples/example.rb" ],
|
|
23
|
+
[ "lib/tumugi/plugin/target/target.rb.erb", "lib/tumugi/plugin/target/#{name}.rb" ],
|
|
24
|
+
[ "lib/tumugi/plugin/task/task.rb.erb", "lib/tumugi/plugin/task/#{name}.rb" ],
|
|
25
|
+
[ "test/test_helper.rb.erb", "test/test_helper.rb" ],
|
|
26
|
+
[ "test/test.rb.erb", "test/#{name}_test.rb" ],
|
|
27
|
+
[ "test/plugin/target/target_test.rb.erb", "test/plugin/target/#{name}_test.rb" ],
|
|
28
|
+
[ "test/plugin/task/task_test.rb.erb", "test/plugin/task/#{name}_test.rb" ],
|
|
29
|
+
]
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def full_project_name
|
|
33
|
+
"tumugi-plugin-#{name}"
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def context
|
|
37
|
+
{
|
|
38
|
+
full_project_name: full_project_name,
|
|
39
|
+
name: name,
|
|
40
|
+
tumugi_version: Tumugi::VERSION,
|
|
41
|
+
}
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def post_messages
|
|
45
|
+
[
|
|
46
|
+
"",
|
|
47
|
+
"Plugin template is successfully generated.",
|
|
48
|
+
"Next steps:",
|
|
49
|
+
"",
|
|
50
|
+
" $ cd #{full_project_name}",
|
|
51
|
+
" $ git init",
|
|
52
|
+
" $ bundle install",
|
|
53
|
+
" $ bundle exec rake",
|
|
54
|
+
"",
|
|
55
|
+
]
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
require_relative 'generator'
|
|
2
|
+
|
|
3
|
+
module Tumugi
|
|
4
|
+
module Command
|
|
5
|
+
class New
|
|
6
|
+
class ProjectGenerator < Generator
|
|
7
|
+
def data_dir
|
|
8
|
+
"#{File.expand_path(File.dirname(__FILE__))}/../../data/new/project"
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def dest_dir
|
|
12
|
+
File.join(options[:path] || '.', name)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def templates
|
|
16
|
+
[
|
|
17
|
+
[ "Gemfile.erb", "Gemfile" ],
|
|
18
|
+
[ "workflow.rb.erb", "workflow.rb" ],
|
|
19
|
+
[ "tumugi_config.rb.erb", "tumugi_config.rb" ],
|
|
20
|
+
]
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def context
|
|
24
|
+
{
|
|
25
|
+
name: name,
|
|
26
|
+
tumugi_version: Tumugi::VERSION,
|
|
27
|
+
}
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def post_messages
|
|
31
|
+
[
|
|
32
|
+
"",
|
|
33
|
+
"Project template is successfully generated.",
|
|
34
|
+
"Next steps:",
|
|
35
|
+
"",
|
|
36
|
+
name.empty? ? "" : " $ cd #{name}",
|
|
37
|
+
" $ bundle install",
|
|
38
|
+
" $ bundle exec tumugi -f workflow.rb main",
|
|
39
|
+
"",
|
|
40
|
+
]
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
data/lib/tumugi/command/run.rb
CHANGED
|
@@ -6,21 +6,14 @@ module Tumugi
|
|
|
6
6
|
class Run
|
|
7
7
|
def execute(dag, options={})
|
|
8
8
|
worker_num = options[:workers] || Tumugi.config.workers
|
|
9
|
-
executor = Tumugi::Executor::LocalExecutor.new(dag, worker_num: worker_num)
|
|
10
|
-
result =
|
|
9
|
+
executor = Tumugi::Executor::LocalExecutor.new(dag, worker_num: worker_num, run_all: options[:all])
|
|
10
|
+
result = executor.execute
|
|
11
11
|
show_result_report(dag)
|
|
12
12
|
result
|
|
13
13
|
end
|
|
14
14
|
|
|
15
15
|
private
|
|
16
16
|
|
|
17
|
-
def start(executor)
|
|
18
|
-
logger.info "workflow_start: #{Tumugi.workflow.id}"
|
|
19
|
-
result = executor.execute
|
|
20
|
-
logger.info "workflow_end: #{Tumugi.workflow.id}"
|
|
21
|
-
result
|
|
22
|
-
end
|
|
23
|
-
|
|
24
17
|
def show_result_report(dag)
|
|
25
18
|
reporter = Tumugi::DAGResultReporter.new
|
|
26
19
|
report = reporter.show(dag)
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
require 'terminal-table'
|
|
2
|
-
|
|
3
2
|
require 'tumugi/mixin/listable'
|
|
4
3
|
|
|
5
4
|
module Tumugi
|
|
@@ -7,18 +6,19 @@ module Tumugi
|
|
|
7
6
|
include Tumugi::Mixin::Listable
|
|
8
7
|
|
|
9
8
|
def show(dag)
|
|
10
|
-
headings = ['Task', 'Requires', 'Parameters', 'State']
|
|
9
|
+
headings = ['Task', 'Requires', 'Parameters', 'State', 'Elapsed']
|
|
11
10
|
Terminal::Table.new title: "Workflow Result", headings: headings do |t|
|
|
12
11
|
dag.tsort.map.with_index do |task, index|
|
|
13
12
|
proxy = task.class.merged_parameter_proxy
|
|
14
13
|
requires = list(task.requires).map do |r|
|
|
15
14
|
r.id
|
|
16
15
|
end
|
|
17
|
-
params = proxy.params.map do |name,
|
|
18
|
-
|
|
16
|
+
params = proxy.params.map do |name, param|
|
|
17
|
+
val = param.secret? ? '***' : truncate(task.send(name.to_sym).to_s, 25)
|
|
18
|
+
"#{name}=#{val}"
|
|
19
19
|
end
|
|
20
20
|
t << :separator if index != 0
|
|
21
|
-
t << [ task.id, requires.join("\n"), params.join("\n"), task.state ]
|
|
21
|
+
t << [ task.id, requires.join("\n"), params.join("\n"), task.state, task.elapsed_time ]
|
|
22
22
|
end
|
|
23
23
|
end
|
|
24
24
|
end
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
Tumugi.configure do |config|
|
|
2
|
+
##############################################################################
|
|
3
|
+
# Number of worker threads for parallel execution, default value is 1.
|
|
4
|
+
# You can override this value by CLI '-w' option like:
|
|
5
|
+
#
|
|
6
|
+
# $ tumugi run -f workflow.rb main -w 2
|
|
7
|
+
##############################################################################
|
|
8
|
+
# config.workers = 1
|
|
9
|
+
|
|
10
|
+
##############################################################################
|
|
11
|
+
# Max retry count for each task, default value is 3.
|
|
12
|
+
##############################################################################
|
|
13
|
+
# config.max_retry = 3
|
|
14
|
+
|
|
15
|
+
##############################################################################
|
|
16
|
+
# Retry interval seconds for each task, default value is 300 seconds.
|
|
17
|
+
##############################################################################
|
|
18
|
+
# config.retry_interval = 300
|
|
19
|
+
|
|
20
|
+
##############################################################################
|
|
21
|
+
# Timeout seconds for each task, default value is nil, it means no timeout.
|
|
22
|
+
##############################################################################
|
|
23
|
+
# config.timeout = nil
|
|
24
|
+
|
|
25
|
+
##############################################################################
|
|
26
|
+
# If you use plugins and plugins support config section,
|
|
27
|
+
# define it like following.
|
|
28
|
+
##############################################################################
|
|
29
|
+
|
|
30
|
+
# config.section("section_name") do |section|
|
|
31
|
+
# section.key = "value"
|
|
32
|
+
# end
|
|
33
|
+
end
|
data/lib/tumugi/event.rb
ADDED
|
@@ -7,17 +7,18 @@ require 'tumugi/error'
|
|
|
7
7
|
module Tumugi
|
|
8
8
|
module Executor
|
|
9
9
|
class LocalExecutor
|
|
10
|
-
def initialize(dag, worker_num: 1)
|
|
10
|
+
def initialize(dag, worker_num: 1, run_all: false)
|
|
11
11
|
@dag = dag
|
|
12
12
|
@main_task = dag.tsort.last
|
|
13
|
-
@
|
|
13
|
+
@worker_num = worker_num
|
|
14
|
+
@run_all = run_all
|
|
14
15
|
@mutex = Mutex.new
|
|
15
16
|
end
|
|
16
17
|
|
|
17
18
|
def execute
|
|
18
19
|
pool = Concurrent::ThreadPoolExecutor.new(
|
|
19
|
-
min_threads: @
|
|
20
|
-
max_threads: @
|
|
20
|
+
min_threads: @worker_num,
|
|
21
|
+
max_threads: @worker_num
|
|
21
22
|
)
|
|
22
23
|
|
|
23
24
|
setup_task_queue(@dag)
|
|
@@ -27,7 +28,7 @@ module Tumugi
|
|
|
27
28
|
|
|
28
29
|
Concurrent::Future.execute(executor: pool) do
|
|
29
30
|
if !task.runnable?(Time.now)
|
|
30
|
-
logger.trace { "
|
|
31
|
+
logger.trace { "task_not_runnable: #{task.id}" }
|
|
31
32
|
enqueue_task(task)
|
|
32
33
|
else
|
|
33
34
|
begin
|
|
@@ -37,7 +38,8 @@ module Tumugi
|
|
|
37
38
|
task.run
|
|
38
39
|
end
|
|
39
40
|
task.trigger!(:complete)
|
|
40
|
-
logger.info { "task_#{task.state}: #{task.id}" }
|
|
41
|
+
logger.info { "task_#{task.state}: #{task.id}, elapsed_time: #{task.elapsed_time}" }
|
|
42
|
+
task.on_success
|
|
41
43
|
rescue => e
|
|
42
44
|
handle_error(task, e)
|
|
43
45
|
end
|
|
@@ -83,10 +85,10 @@ module Tumugi
|
|
|
83
85
|
|
|
84
86
|
if task.requires_failed?
|
|
85
87
|
task.trigger!(:requires_fail)
|
|
86
|
-
logger.info { "task_#{task.state}: #{task.id} has failed requires task" }
|
|
87
|
-
elsif task.completed?
|
|
88
|
+
logger.info { "task_#{task.state}: #{task.id} has failed requires task, elapsed_time: #{task.elapsed_time}" }
|
|
89
|
+
elsif task.completed? && !@run_all
|
|
88
90
|
task.trigger!(:skip)
|
|
89
|
-
logger.info { "task_#{task.state}: #{task.id} is already completed" }
|
|
91
|
+
logger.info { "task_#{task.state}: #{task.id} is already completed, elapsed_time: #{task.elapsed_time}" }
|
|
90
92
|
else
|
|
91
93
|
break task
|
|
92
94
|
end
|
|
@@ -102,15 +104,17 @@ module Tumugi
|
|
|
102
104
|
def handle_error(task, err)
|
|
103
105
|
if task.retry
|
|
104
106
|
task.trigger!(:pend)
|
|
107
|
+
logger.info { "task_#{task.state}: #{task.id} failed, elapsed_time: #{task.elapsed_time}" }
|
|
105
108
|
logger.error { "#{err.class}: '#{err.message}' - #{task.tries} tries and wait #{task.retry_interval} seconds until the next try." }
|
|
106
109
|
enqueue_task(task)
|
|
110
|
+
task.on_retry
|
|
107
111
|
else
|
|
108
112
|
task.trigger!(:fail)
|
|
113
|
+
logger.info { "task_#{task.state}: #{task.id} failed, elapsed_time: #{task.elapsed_time}" }
|
|
109
114
|
logger.error { "#{err.class}: '#{err.message}' - #{task.tries} tries and reached max retry count, so task #{task.id} failed." }
|
|
110
|
-
|
|
111
|
-
logger.error { err.backtrace.join("\n") }
|
|
115
|
+
task.on_failure
|
|
112
116
|
end
|
|
113
|
-
logger.
|
|
117
|
+
logger.error { err.backtrace.join("\n") }
|
|
114
118
|
end
|
|
115
119
|
|
|
116
120
|
def logger
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
module Tumugi
|
|
2
|
+
module Mixin
|
|
3
|
+
module HumanReadable
|
|
4
|
+
def human_readable_time(seconds)
|
|
5
|
+
[[60, :s], [60, :m], [10000, :h]].map{|count, name|
|
|
6
|
+
if seconds > 0
|
|
7
|
+
seconds, n = seconds.divmod(count)
|
|
8
|
+
"#{sprintf('%02d', n)}"
|
|
9
|
+
else
|
|
10
|
+
'00'
|
|
11
|
+
end
|
|
12
|
+
}.compact.reverse.join(':')
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -20,15 +20,11 @@ module Tumugi
|
|
|
20
20
|
end
|
|
21
21
|
|
|
22
22
|
def auto_bind?
|
|
23
|
-
|
|
24
|
-
false
|
|
25
|
-
else
|
|
26
|
-
@opts[:auto_bind]
|
|
27
|
-
end
|
|
23
|
+
option_as_bool(:auto_bind)
|
|
28
24
|
end
|
|
29
25
|
|
|
30
26
|
def required?
|
|
31
|
-
|
|
27
|
+
option_as_bool(:required)
|
|
32
28
|
end
|
|
33
29
|
|
|
34
30
|
def type
|
|
@@ -43,6 +39,10 @@ module Tumugi
|
|
|
43
39
|
self.class.new(@name, @opts.merge(required: false, default: value))
|
|
44
40
|
end
|
|
45
41
|
|
|
42
|
+
def secret?
|
|
43
|
+
option_as_bool(:secret)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
46
|
private
|
|
47
47
|
|
|
48
48
|
def search_from_workflow_parameters
|
|
@@ -51,13 +51,15 @@ module Tumugi
|
|
|
51
51
|
value ? Converter.convert(type, value) : nil
|
|
52
52
|
end
|
|
53
53
|
|
|
54
|
-
private
|
|
55
|
-
|
|
56
54
|
def validate
|
|
57
55
|
if required? && !default_value.nil?
|
|
58
56
|
raise Tumugi::ParameterError.new("When you set required: true, you cannot set default value")
|
|
59
57
|
end
|
|
60
58
|
end
|
|
59
|
+
|
|
60
|
+
def option_as_bool(key)
|
|
61
|
+
@opts[key].nil? ? false : @opts[key]
|
|
62
|
+
end
|
|
61
63
|
end
|
|
62
64
|
end
|
|
63
65
|
end
|
data/lib/tumugi/task.rb
CHANGED
|
@@ -1,15 +1,18 @@
|
|
|
1
|
+
require 'tumugi/event'
|
|
1
2
|
require 'tumugi/logger/scoped_logger'
|
|
2
3
|
require 'tumugi/mixin/listable'
|
|
3
4
|
require 'tumugi/mixin/task_helper'
|
|
4
5
|
require 'tumugi/mixin/parameterizable'
|
|
6
|
+
require 'tumugi/mixin/human_readable'
|
|
5
7
|
|
|
6
8
|
module Tumugi
|
|
7
9
|
class Task
|
|
8
10
|
include Tumugi::Mixin::Parameterizable
|
|
9
11
|
include Tumugi::Mixin::Listable
|
|
10
12
|
include Tumugi::Mixin::TaskHelper
|
|
13
|
+
include Tumugi::Mixin::HumanReadable
|
|
11
14
|
|
|
12
|
-
attr_reader :visible_at, :tries, :max_retry, :retry_interval
|
|
15
|
+
attr_reader :visible_at, :tries, :max_retry, :retry_interval, :elapsed_time
|
|
13
16
|
|
|
14
17
|
AVAILABLE_STATES = [
|
|
15
18
|
:pending,
|
|
@@ -28,6 +31,8 @@ module Tumugi
|
|
|
28
31
|
@retry_interval = Tumugi.config.retry_interval
|
|
29
32
|
@state = :pending
|
|
30
33
|
@lock = Mutex.new
|
|
34
|
+
@_elapsed_times = []
|
|
35
|
+
@elapsed_time = '00:00:00'
|
|
31
36
|
end
|
|
32
37
|
|
|
33
38
|
def id
|
|
@@ -98,6 +103,27 @@ module Tumugi
|
|
|
98
103
|
ready? && visible?(now)
|
|
99
104
|
end
|
|
100
105
|
|
|
106
|
+
def ready?
|
|
107
|
+
list(_requires).all? { |t| t.instance.completed? }
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
def completed?
|
|
111
|
+
outputs = list(output)
|
|
112
|
+
if outputs.empty?
|
|
113
|
+
success?
|
|
114
|
+
else
|
|
115
|
+
outputs.all?(&:exist?)
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
def requires_failed?
|
|
120
|
+
list(_requires).any? { |t| t.instance.finished? && !t.instance.success? }
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
def runnable?(now)
|
|
124
|
+
ready? && visible?(now)
|
|
125
|
+
end
|
|
126
|
+
|
|
101
127
|
def success?
|
|
102
128
|
case state
|
|
103
129
|
when :completed, :skipped
|
|
@@ -107,15 +133,19 @@ module Tumugi
|
|
|
107
133
|
end
|
|
108
134
|
end
|
|
109
135
|
|
|
110
|
-
def
|
|
136
|
+
def failure?
|
|
111
137
|
case state
|
|
112
|
-
when :
|
|
138
|
+
when :failed, :requires_failed
|
|
113
139
|
true
|
|
114
140
|
else
|
|
115
141
|
false
|
|
116
142
|
end
|
|
117
143
|
end
|
|
118
144
|
|
|
145
|
+
def finished?
|
|
146
|
+
success? or failure?
|
|
147
|
+
end
|
|
148
|
+
|
|
119
149
|
def timeout
|
|
120
150
|
nil # meaning use default timeout
|
|
121
151
|
end
|
|
@@ -132,6 +162,9 @@ module Tumugi
|
|
|
132
162
|
|
|
133
163
|
def trigger!(event)
|
|
134
164
|
@lock.synchronize do
|
|
165
|
+
now = Time.now
|
|
166
|
+
@_elapsed_times[tries] ||= { start: now }
|
|
167
|
+
|
|
135
168
|
s = case event
|
|
136
169
|
when :skip
|
|
137
170
|
:skipped
|
|
@@ -153,10 +186,20 @@ module Tumugi
|
|
|
153
186
|
raise Tumugi::TumugiError.new("Invalid state: #{s}")
|
|
154
187
|
end
|
|
155
188
|
|
|
189
|
+
@_elapsed_times[tries][:end] = now
|
|
190
|
+
@elapsed_time = human_readable_time((@_elapsed_times[tries][:end] - @_elapsed_times[tries][:start]).to_i)
|
|
156
191
|
@state = s
|
|
157
192
|
end
|
|
158
193
|
end
|
|
159
194
|
|
|
195
|
+
# Event callbacks
|
|
196
|
+
Event.all.each do |event|
|
|
197
|
+
class_eval <<-EOS
|
|
198
|
+
def on_#{event}
|
|
199
|
+
end
|
|
200
|
+
EOS
|
|
201
|
+
end
|
|
202
|
+
|
|
160
203
|
# Following methods are internal use only
|
|
161
204
|
|
|
162
205
|
def _requires
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
require 'tumugi/event'
|
|
1
2
|
require 'tumugi/plugin'
|
|
2
3
|
require 'tumugi/task'
|
|
3
4
|
require 'tumugi/logger/logger'
|
|
@@ -64,6 +65,14 @@ module Tumugi
|
|
|
64
65
|
@run = block
|
|
65
66
|
end
|
|
66
67
|
|
|
68
|
+
Event.all.each do |event|
|
|
69
|
+
class_eval <<-EOS
|
|
70
|
+
def on_#{event}(&block)
|
|
71
|
+
@on_#{event} ||= block
|
|
72
|
+
end
|
|
73
|
+
EOS
|
|
74
|
+
end
|
|
75
|
+
|
|
67
76
|
def output_eval(task)
|
|
68
77
|
@out ||= @outputs.is_a?(Proc) ? task.instance_eval(&@outputs) : @outputs
|
|
69
78
|
end
|
|
@@ -72,10 +81,6 @@ module Tumugi
|
|
|
72
81
|
@required_tasks
|
|
73
82
|
end
|
|
74
83
|
|
|
75
|
-
def run_block(task)
|
|
76
|
-
task.instance_eval(&@run)
|
|
77
|
-
end
|
|
78
|
-
|
|
79
84
|
def parent_task_class
|
|
80
85
|
if @opts[:type].is_a?(Class)
|
|
81
86
|
@opts[:type]
|
|
@@ -84,6 +89,15 @@ module Tumugi
|
|
|
84
89
|
end
|
|
85
90
|
end
|
|
86
91
|
|
|
92
|
+
def run_block(task)
|
|
93
|
+
task.instance_eval(&@run)
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def event_block(task, event)
|
|
97
|
+
callback = instance_variable_get("@on_#{event}")
|
|
98
|
+
task.instance_eval(&callback)
|
|
99
|
+
end
|
|
100
|
+
|
|
87
101
|
private
|
|
88
102
|
|
|
89
103
|
def create_task
|
|
@@ -98,6 +112,7 @@ module Tumugi
|
|
|
98
112
|
define_requires_method(task_class)
|
|
99
113
|
define_output_method(task_class)
|
|
100
114
|
define_run_method(task_class)
|
|
115
|
+
define_event_callback_methods(task_class)
|
|
101
116
|
setup_params(task_class)
|
|
102
117
|
task_class
|
|
103
118
|
end
|
|
@@ -138,6 +153,19 @@ module Tumugi
|
|
|
138
153
|
end unless @run.nil?
|
|
139
154
|
end
|
|
140
155
|
|
|
156
|
+
def define_event_callback_methods(task_class)
|
|
157
|
+
td = self
|
|
158
|
+
Event.all.each do |event|
|
|
159
|
+
if instance_variable_get("@on_#{event}")
|
|
160
|
+
task_class.class_eval do
|
|
161
|
+
define_method(:"on_#{event}") do
|
|
162
|
+
td.event_block(self, event)
|
|
163
|
+
end
|
|
164
|
+
end
|
|
165
|
+
end
|
|
166
|
+
end
|
|
167
|
+
end
|
|
168
|
+
|
|
141
169
|
def setup_params(task_class)
|
|
142
170
|
@params.each do |name, opts|
|
|
143
171
|
task_class.param(name, opts)
|
data/lib/tumugi/version.rb
CHANGED
data/lib/tumugi/workflow.rb
CHANGED
|
@@ -5,11 +5,14 @@ require 'tumugi/plugin'
|
|
|
5
5
|
require 'tumugi/target'
|
|
6
6
|
require 'tumugi/command/run'
|
|
7
7
|
require 'tumugi/command/show'
|
|
8
|
+
require 'tumugi/mixin/human_readable'
|
|
8
9
|
|
|
9
10
|
require 'securerandom'
|
|
10
11
|
|
|
11
12
|
module Tumugi
|
|
12
13
|
class Workflow
|
|
14
|
+
include Tumugi::Mixin::HumanReadable
|
|
15
|
+
|
|
13
16
|
attr_reader :id
|
|
14
17
|
attr_accessor :params
|
|
15
18
|
|
|
@@ -22,12 +25,14 @@ module Tumugi
|
|
|
22
25
|
end
|
|
23
26
|
|
|
24
27
|
def execute(command, root_task_id, options)
|
|
28
|
+
@start_time = Time.now
|
|
29
|
+
logger.info "start id: #{id}"
|
|
25
30
|
process_common_options(command, options)
|
|
26
31
|
load_workflow_file(options[:file])
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
32
|
+
result = execute_command(command, root_task_id, options)
|
|
33
|
+
@end_time = Time.now
|
|
34
|
+
logger.info "end id: #{id}, elapsed_time: #{elapsed_time}"
|
|
35
|
+
result
|
|
31
36
|
end
|
|
32
37
|
|
|
33
38
|
def add_task(id, task)
|
|
@@ -55,13 +60,6 @@ module Tumugi
|
|
|
55
60
|
end
|
|
56
61
|
end
|
|
57
62
|
|
|
58
|
-
def create_dag(id)
|
|
59
|
-
dag = Tumugi::DAG.new
|
|
60
|
-
task = find_task(id)
|
|
61
|
-
dag.add_task(task)
|
|
62
|
-
dag
|
|
63
|
-
end
|
|
64
|
-
|
|
65
63
|
def process_common_options(command, options)
|
|
66
64
|
setup_logger(command, options)
|
|
67
65
|
load_config(options)
|
|
@@ -111,5 +109,23 @@ module Tumugi
|
|
|
111
109
|
logger.info "Parameters: #{@params}"
|
|
112
110
|
end
|
|
113
111
|
end
|
|
112
|
+
|
|
113
|
+
def elapsed_time
|
|
114
|
+
human_readable_time((@end_time - @start_time).to_i)
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
def execute_command(command, root_task_id, options)
|
|
118
|
+
dag = create_dag(root_task_id)
|
|
119
|
+
command_module = Kernel.const_get("Tumugi").const_get("Command")
|
|
120
|
+
cmd = command_module.const_get("#{command.to_s.capitalize}").new
|
|
121
|
+
cmd.execute(dag, options)
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
def create_dag(id)
|
|
125
|
+
dag = Tumugi::DAG.new
|
|
126
|
+
task = find_task(id)
|
|
127
|
+
dag.add_task(task)
|
|
128
|
+
dag
|
|
129
|
+
end
|
|
114
130
|
end
|
|
115
131
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: tumugi
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.7.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Kazuyuki Honda
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2016-
|
|
11
|
+
date: 2016-11-01 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: concurrent-ruby
|
|
@@ -184,6 +184,7 @@ files:
|
|
|
184
184
|
- examples/concurrent_task_run.rb
|
|
185
185
|
- examples/config_section.rb
|
|
186
186
|
- examples/data_pipeline.rb
|
|
187
|
+
- examples/event_callbacks.rb
|
|
187
188
|
- examples/fail_first_task.rb
|
|
188
189
|
- examples/fail_intermediate_task.rb
|
|
189
190
|
- examples/fail_last_task.rb
|
|
@@ -198,29 +199,37 @@ files:
|
|
|
198
199
|
- lib/tumugi/atomic_file.rb
|
|
199
200
|
- lib/tumugi/cli.rb
|
|
200
201
|
- lib/tumugi/command/new.rb
|
|
202
|
+
- lib/tumugi/command/new/generator.rb
|
|
203
|
+
- lib/tumugi/command/new/plugin_generator.rb
|
|
204
|
+
- lib/tumugi/command/new/project_generator.rb
|
|
201
205
|
- lib/tumugi/command/run.rb
|
|
202
206
|
- lib/tumugi/command/show.rb
|
|
203
207
|
- lib/tumugi/config.rb
|
|
204
208
|
- lib/tumugi/dag.rb
|
|
205
209
|
- lib/tumugi/dag_result_reporter.rb
|
|
206
|
-
- lib/tumugi/data/new/Gemfile.erb
|
|
207
|
-
- lib/tumugi/data/new/README.md.erb
|
|
208
|
-
- lib/tumugi/data/new/Rakefile.erb
|
|
209
|
-
- lib/tumugi/data/new/examples/example.rb.erb
|
|
210
|
-
- lib/tumugi/data/new/gemspec.erb
|
|
211
|
-
- lib/tumugi/data/new/gitignore.erb
|
|
212
|
-
- lib/tumugi/data/new/lib/tumugi/plugin/target/target.rb.erb
|
|
213
|
-
- lib/tumugi/data/new/lib/tumugi/plugin/task/task.rb.erb
|
|
214
|
-
- lib/tumugi/data/new/test/plugin/target/target_test.rb.erb
|
|
215
|
-
- lib/tumugi/data/new/test/plugin/task/task_test.rb.erb
|
|
216
|
-
- lib/tumugi/data/new/test/test.rb.erb
|
|
217
|
-
- lib/tumugi/data/new/test/test_helper.rb.erb
|
|
210
|
+
- lib/tumugi/data/new/plugin/Gemfile.erb
|
|
211
|
+
- lib/tumugi/data/new/plugin/README.md.erb
|
|
212
|
+
- lib/tumugi/data/new/plugin/Rakefile.erb
|
|
213
|
+
- lib/tumugi/data/new/plugin/examples/example.rb.erb
|
|
214
|
+
- lib/tumugi/data/new/plugin/gemspec.erb
|
|
215
|
+
- lib/tumugi/data/new/plugin/gitignore.erb
|
|
216
|
+
- lib/tumugi/data/new/plugin/lib/tumugi/plugin/target/target.rb.erb
|
|
217
|
+
- lib/tumugi/data/new/plugin/lib/tumugi/plugin/task/task.rb.erb
|
|
218
|
+
- lib/tumugi/data/new/plugin/test/plugin/target/target_test.rb.erb
|
|
219
|
+
- lib/tumugi/data/new/plugin/test/plugin/task/task_test.rb.erb
|
|
220
|
+
- lib/tumugi/data/new/plugin/test/test.rb.erb
|
|
221
|
+
- lib/tumugi/data/new/plugin/test/test_helper.rb.erb
|
|
222
|
+
- lib/tumugi/data/new/project/Gemfile.erb
|
|
223
|
+
- lib/tumugi/data/new/project/tumugi_config.rb.erb
|
|
224
|
+
- lib/tumugi/data/new/project/workflow.rb.erb
|
|
218
225
|
- lib/tumugi/dsl.rb
|
|
219
226
|
- lib/tumugi/error.rb
|
|
227
|
+
- lib/tumugi/event.rb
|
|
220
228
|
- lib/tumugi/executor/local_executor.rb
|
|
221
229
|
- lib/tumugi/file_system.rb
|
|
222
230
|
- lib/tumugi/logger/logger.rb
|
|
223
231
|
- lib/tumugi/logger/scoped_logger.rb
|
|
232
|
+
- lib/tumugi/mixin/human_readable.rb
|
|
224
233
|
- lib/tumugi/mixin/listable.rb
|
|
225
234
|
- lib/tumugi/mixin/parameterizable.rb
|
|
226
235
|
- lib/tumugi/mixin/task_helper.rb
|