tumugi 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: fe91c5dd14b1c75b8562de885608d52d9f8ff927
4
- data.tar.gz: 7ce1c778ca4614bb5a9a4be2e04ac1d75dc59a5b
3
+ metadata.gz: c2ac1c29b7d48bd8d12b5f62b3cd177ca1f34109
4
+ data.tar.gz: 81f64f2898be4b90207549d547260fb333858c2d
5
5
  SHA512:
6
- metadata.gz: 5005eed43b4ec6261c0870c89afe93609c516719541f67dd9ef683f1b0742b6ed8e8dedb574eb578485612856d3096aab64198ef55c8e8cefead786d3f538663
7
- data.tar.gz: 3208bf2657f87d7f76dd39a568e9ec356c549ddfca95986e8f879d3ac0b88b2c017ab150159b3cec7b653c37e9fdd86cda56414f1df817f228879bf061c18cee
6
+ metadata.gz: ef38cfe6332a2d809899750b958683ccaef7890b563b7352150c36c75ae46051238e7c3235b64dbe407eb86744cb35b178e3a6a6b97884d9c842dfa54058c86f
7
+ data.tar.gz: 7d6a1fbcb68dafacbaf3adb0c60da3c132b345d1623ef3dd7ec34057a2bc0796a6af880c10d6c5ab7c3554a80ecda20f040ad5400e3c96865931c57b64abf0ca
@@ -1,12 +1,31 @@
1
1
  # Change Log
2
2
 
3
+ ## [v0.3.0](https://github.com/tumugi/tumugi/tree/v0.3.0) (2016-05-07)
4
+ [Full Changelog](https://github.com/tumugi/tumugi/compare/v0.2.0...v0.3.0)
5
+
6
+ **Implemented enhancements:**
7
+
8
+ - Show result report [\#23](https://github.com/tumugi/tumugi/issues/23)
9
+ - Support parameter [\#21](https://github.com/tumugi/tumugi/issues/21)
10
+
11
+ **Fixed bugs:**
12
+
13
+ - Fix workflow dead locked when some task failed [\#25](https://github.com/tumugi/tumugi/pull/25) ([hakobera](https://github.com/hakobera))
14
+
15
+ **Merged pull requests:**
16
+
17
+ - Update README [\#26](https://github.com/tumugi/tumugi/pull/26) ([hakobera](https://github.com/hakobera))
18
+ - Implement workflow run result report [\#24](https://github.com/tumugi/tumugi/pull/24) ([hakobera](https://github.com/hakobera))
19
+ - Implement parameter feature [\#22](https://github.com/tumugi/tumugi/pull/22) ([hakobera](https://github.com/hakobera))
20
+
3
21
  ## [v0.2.0](https://github.com/tumugi/tumugi/tree/v0.2.0) (2016-05-02)
4
22
  [Full Changelog](https://github.com/tumugi/tumugi/compare/v0.1.0...v0.2.0)
5
23
 
6
24
  **Implemented enhancements:**
7
25
 
8
- - Implement plugin architecture [\#18](https://github.com/tumugi/tumugi/pull/18) ([hakobera](https://github.com/hakobera))
9
- - \[Breaking change\] Change eval scope of output, run method [\#14](https://github.com/tumugi/tumugi/pull/14) ([hakobera](https://github.com/hakobera))
26
+ - \[Breaking Change\] Support plugin [\#15](https://github.com/tumugi/tumugi/issues/15)
27
+ - Add required\_ruby\_version to gemspec [\#19](https://github.com/tumugi/tumugi/pull/19) ([hakobera](https://github.com/hakobera))
28
+ - \[Breaking Change\] Change eval scope of output, run method [\#14](https://github.com/tumugi/tumugi/pull/14) ([hakobera](https://github.com/hakobera))
10
29
  - \[Breaking Change\] Add Task\#logger and Task\#log method [\#12](https://github.com/tumugi/tumugi/pull/12) ([hakobera](https://github.com/hakobera))
11
30
  - Update command description / Set file options mandatory [\#11](https://github.com/tumugi/tumugi/pull/11) ([hakobera](https://github.com/hakobera))
12
31
 
@@ -18,6 +37,8 @@
18
37
 
19
38
  - Use bundler cache on travis [\#17](https://github.com/tumugi/tumugi/pull/17) ([hakobera](https://github.com/hakobera))
20
39
  - Add gem version badge to README [\#16](https://github.com/tumugi/tumugi/pull/16) ([hakobera](https://github.com/hakobera))
40
+ - Prepare for release v0.2.0 [\#20](https://github.com/tumugi/tumugi/pull/20) ([hakobera](https://github.com/hakobera))
41
+ - \[Breaking Change\] Implement plugin architecture [\#18](https://github.com/tumugi/tumugi/pull/18) ([hakobera](https://github.com/hakobera))
21
42
  - Add changelog of v0.1.0 [\#10](https://github.com/tumugi/tumugi/pull/10) ([hakobera](https://github.com/hakobera))
22
43
 
23
44
  ## [v0.1.0](https://github.com/tumugi/tumugi/tree/v0.1.0) (2016-04-28)
data/README.md CHANGED
@@ -69,7 +69,33 @@ Save these code into `workflow.rb`,
69
69
  then run this script by `tumugi` command like this:
70
70
 
71
71
  ```bash
72
- $ tumugi workflow.rb task1
72
+ $ tumugi run -f workflow.rb task1
73
+ I, [2016-05-06T22:58:28.271234 #76156] INFO -- : start: task4
74
+ I, [2016-05-06T22:58:28.271310 #76156] INFO -- : run: task4
75
+ I, [2016-05-06T22:58:28.271386 #76156] INFO -- : task4#run
76
+ I, [2016-05-06T22:58:29.276218 #76156] INFO -- : completed: task4
77
+ I, [2016-05-06T22:58:29.276373 #76156] INFO -- : start: task2
78
+ I, [2016-05-06T22:58:29.276437 #76156] INFO -- : run: task2
79
+ I, [2016-05-06T22:58:29.276546 #76156] INFO -- : task2#run
80
+ I, [2016-05-06T22:58:29.276606 #76156] INFO -- : completed: task2
81
+ I, [2016-05-06T22:58:29.276650 #76156] INFO -- : start: task3
82
+ I, [2016-05-06T22:58:29.276688 #76156] INFO -- : run: task3
83
+ I, [2016-05-06T22:58:29.276733 #76156] INFO -- : task3#run
84
+ I, [2016-05-06T22:58:29.276765 #76156] INFO -- : completed: task3
85
+ I, [2016-05-06T22:58:29.276798 #76156] INFO -- : start: task1
86
+ I, [2016-05-06T22:58:29.276823 #76156] INFO -- : run: task1
87
+ I, [2016-05-06T22:58:29.276861 #76156] INFO -- : task1#run
88
+ I, [2016-05-06T22:58:29.276899 #76156] INFO -- : completed: task1
89
+ I, [2016-05-06T22:58:29.278919 #76156] INFO -- : Result report:
90
+ +-------+----------+------------+-----------+
91
+ | Task | Requires | Parameters | State |
92
+ +-------+----------+------------+-----------+
93
+ | task1 | task2 | | completed |
94
+ | | task3 | | |
95
+ | task3 | task4 | | completed |
96
+ | task2 | task4 | | completed |
97
+ | task4 | | | completed |
98
+ +-------+----------+------------+-----------+
73
99
  ```
74
100
 
75
101
  ## Development
@@ -0,0 +1,20 @@
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 { log 'task2#run' }
9
+ end
10
+
11
+ task :task3 do
12
+ requires [:task4]
13
+ run { log 'task3#run' }
14
+ end
15
+
16
+ task :task4 do
17
+ run do
18
+ raise "error in #{id}"
19
+ end
20
+ end
@@ -0,0 +1,21 @@
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
+ end
10
+
11
+ task :task3 do
12
+ requires [:task4]
13
+ run { log 'task3#run' }
14
+ end
15
+
16
+ task :task4 do
17
+ run do
18
+ log 'task4#run'
19
+ sleep 1
20
+ end
21
+ end
@@ -0,0 +1,21 @@
1
+ task :task1 do
2
+ requires [:task2, :task3]
3
+ run { raise "error in #{id}" }
4
+ end
5
+
6
+ task :task2 do
7
+ requires [:task4]
8
+ run { log 'task2#run' }
9
+ end
10
+
11
+ task :task3 do
12
+ requires [:task4]
13
+ run { log 'task3#run' }
14
+ end
15
+
16
+ task :task4 do
17
+ run do
18
+ log 'task4#run'
19
+ sleep 1
20
+ end
21
+ end
@@ -0,0 +1,31 @@
1
+ task :task1 do
2
+ param :key1, required: true #=> 'value1', get value from CLI parameter
3
+ param :key2 #=> 'value2', get value from Environment variables
4
+
5
+ requires :task2
6
+ run do
7
+ log "key1=#{key1}" # You can get param as task property
8
+ log "key2=#{key2}"
9
+ end
10
+ end
11
+
12
+ task :task2 do
13
+ # If you want do disable auto binding feature, set `auto_bind: false`
14
+ param :key1, auto_bind: false #=> nil
15
+ param :key2
16
+ param_set :key2, 'value2' #=> 'value'
17
+
18
+ requires :task3
19
+ run do
20
+ log "key1=#{key1}"
21
+ log "key2=#{key2}"
22
+ end
23
+ end
24
+
25
+ task :task3 do
26
+ param :key3, default: 'default value' #=> 'default value', get value from :default when binding value does not found
27
+
28
+ run do
29
+ log "key3=#{key3}"
30
+ end
31
+ end
@@ -0,0 +1,4 @@
1
+ Tumugi.config do |c|
2
+ c.max_retry = 3
3
+ c.retry_interval = 1
4
+ end
@@ -7,8 +7,11 @@ require 'tumugi/command/show'
7
7
 
8
8
  module Tumugi
9
9
  class Application
10
+ attr_accessor :params
11
+
10
12
  def initialize
11
13
  @tasks = {}
14
+ @params = {}
12
15
  end
13
16
 
14
17
  def execute(command, root_task_id, options)
@@ -9,6 +9,11 @@ module Tumugi
9
9
  def common_options
10
10
  option :file, aliases: '-f', desc: 'Task definition file name', required: true
11
11
  option :config, aliases: '-c', desc: 'Configuration file name', default: 'tumugi.rb'
12
+ option :params, aliases: '-p', type: :hash, desc: 'Task parameters'
13
+ end
14
+
15
+ def exit_on_failure?
16
+ true
12
17
  end
13
18
  end
14
19
 
@@ -44,6 +49,9 @@ module Tumugi
44
49
  if config_file && File.exists?(config_file) && File.extname(config_file) == '.rb'
45
50
  load(config_file)
46
51
  end
52
+
53
+ params = options[:params]
54
+ Tumugi.application.params = params if params
47
55
  end
48
56
  end
49
57
  end
@@ -1,23 +1,37 @@
1
1
  require 'parallel'
2
2
  require 'retriable'
3
+ require 'terminal-table'
4
+ require 'thor'
5
+
6
+ require 'tumugi/mixin/listable'
3
7
 
4
8
  module Tumugi
5
9
  module Command
6
10
  class Run
11
+ include Tumugi::Mixin::Listable
12
+
7
13
  def execute(dag, options={})
8
14
  workers = options[:workers] || Tumugi.config.workers
9
15
  settings = { in_threads: workers }
16
+ logger = Tumugi.logger
10
17
 
11
- Tumugi.logger.verbose! if options[:verbose]
12
- Tumugi.logger.quiet! if options[:quiet]
18
+ logger.verbose! if options[:verbose]
19
+ logger.quiet! if options[:quiet]
13
20
 
14
21
  Parallel.each(dag.tsort, settings) do |t|
15
- Tumugi.logger.info "start: #{t.id}"
16
- until t.ready?
22
+ logger.info "start: #{t.id}"
23
+ until t.ready? || t.requires_failed?
17
24
  sleep 1
18
25
  end
19
- unless t.completed?
20
- Tumugi.logger.info "run: #{t.id}"
26
+
27
+ if t.completed?
28
+ t.state = :skipped
29
+ logger.info "#{t.state}: #{t.id} is already completed"
30
+ elsif t.requires_failed?
31
+ t.state = :requires_failed
32
+ logger.info "#{t.state}: #{t.id} has failed requires task"
33
+ else
34
+ logger.info "run: #{t.id}"
21
35
  t.state = :running
22
36
 
23
37
  begin
@@ -25,18 +39,18 @@ module Tumugi
25
39
  t.run
26
40
  end
27
41
  rescue => e
28
- Tumugi.logger.info "failed: #{t.id}"
29
- Tumugi.logger.error "#{e.message}"
30
42
  t.state = :failed
43
+ logger.info "#{t.state}: #{t.id}"
44
+ logger.error "#{e.message}"
31
45
  else
32
- Tumugi.logger.info "completed: #{t.id}"
33
46
  t.state = :completed
47
+ logger.info "#{t.state}: #{t.id}"
34
48
  end
35
- else
36
- t.state = :skipped
37
- Tumugi.logger.info "skip: #{t.id} is already completed"
38
49
  end
39
50
  end
51
+
52
+ show_result_report(dag)
53
+ raise ::Thor::Error.new("run failed") if dag.tsort.any? { |t| t.state == :failed }
40
54
  end
41
55
 
42
56
  private
@@ -55,8 +69,29 @@ module Tumugi
55
69
 
56
70
  def on_retry
57
71
  Proc.new do |exception, try, elapsed_time, next_interval|
58
- Tumugi.logger.error "#{exception.class}: '#{exception.message}' - #{try} tries in #{elapsed_time} seconds and #{next_interval} seconds until the next try."
72
+ if next_interval
73
+ Tumugi.logger.error "#{exception.class}: '#{exception.message}' - #{try} tries in #{elapsed_time} seconds and #{next_interval} seconds until the next try."
74
+ else
75
+ Tumugi.logger.error "#{exception.class}: '#{exception.message}' - #{try} tries in #{elapsed_time} seconds. Task failed."
76
+ end
77
+ end
78
+ end
79
+
80
+ def show_result_report(dag)
81
+ headings = ['Task', 'Requires', 'Parameters', 'State']
82
+ table = Terminal::Table.new headings: headings do |t|
83
+ dag.tsort.reverse.map do |task|
84
+ proxy = task.class.merged_parameter_proxy
85
+ requires = list(task.requires).map do |r|
86
+ r.id
87
+ end
88
+ params = proxy.params.map do |name, _|
89
+ "#{name}=#{task.instance_variable_get("@#{name}")}"
90
+ end
91
+ t << [ task.id, requires.join("\n"), params.join("\n"), task.state ]
92
+ end
59
93
  end
94
+ Tumugi.logger.info "Result report:\n#{table.to_s}"
60
95
  end
61
96
  end
62
97
  end
@@ -1,11 +1,12 @@
1
1
  module Tumugi
2
2
  class Config
3
- attr_accessor :workers, :max_retry, :retry_interval
3
+ attr_accessor :workers, :max_retry, :retry_interval, :param_auto_bind_enabled
4
4
 
5
5
  def initialize
6
6
  @workers = 1
7
7
  @max_retry = 3
8
8
  @retry_interval = 300 #seconds
9
+ @param_auto_bind_enabled = true
9
10
  end
10
11
  end
11
12
  end
@@ -0,0 +1,85 @@
1
+ require 'tumugi/parameter/error'
2
+ require 'tumugi/parameter/parameter_proxy'
3
+
4
+ module Tumugi
5
+ module Mixin
6
+ module Parameterizable
7
+ def self.included(mod)
8
+ mod.extend(ClassMethods)
9
+ end
10
+
11
+ def initialize
12
+ super()
13
+ proxy = self.class.merged_parameter_proxy
14
+ params = proxy.params
15
+ proxy.param_defaults.each do |name, value|
16
+ param = params[name]
17
+ param.overwrite_default(value) if param
18
+ end
19
+ params.each do |name, param|
20
+ unless proxy.param_auto_bind_enabled.nil?
21
+ param.task_param_auto_bind_enabled = proxy.param_auto_bind_enabled
22
+ end
23
+ instance_variable_set("@#{name}", param.get)
24
+ end
25
+ validate_params(params)
26
+ configure
27
+ end
28
+
29
+ def validate_params(params)
30
+ params.each do |name, param|
31
+ if param.required? && instance_variable_get("@#{name}").nil?
32
+ raise Tumugi::Parameter::ParameterError.new("Parameter #{name} is required")
33
+ end
34
+ end
35
+ end
36
+
37
+ def configure
38
+ # You can override in a subclass
39
+ end
40
+
41
+ module ClassMethods
42
+ def parameter_proxy_map
43
+ map = {}
44
+ self.define_singleton_method(:parameter_proxy_map) { map }
45
+ map
46
+ end
47
+
48
+ def parameter_proxy(mod_name)
49
+ map = parameter_proxy_map
50
+ unless map[mod_name]
51
+ proxy = Tumugi::Parameter::ParameterProxy.new(mod_name)
52
+ map[mod_name] = proxy
53
+ end
54
+ map[mod_name]
55
+ end
56
+
57
+ def param(name, opts={})
58
+ parameter_proxy(proxy_id(self)).param(name, opts)
59
+ attr_accessor name
60
+ end
61
+
62
+ def param_set(name, value)
63
+ parameter_proxy(proxy_id(self)).param_set(name, value)
64
+ end
65
+
66
+ def param_auto_bind_enabled(v)
67
+ parameter_proxy(proxy_id(self)).param_auto_bind_enabled = v
68
+ end
69
+
70
+ def merged_parameter_proxy
71
+ parameterizable = ancestors.reverse.select{ |a| a.respond_to?(:parameter_proxy) }
72
+ parameterizable.map { |a| a.parameter_proxy(proxy_id(a)) }.reduce(:merge)
73
+ end
74
+
75
+ def dump
76
+ parameter_proxy_map[proxy_id(self)].dump
77
+ end
78
+
79
+ def proxy_id(klass)
80
+ self.name || self.object_id.to_s
81
+ end
82
+ end
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,58 @@
1
+ require 'time'
2
+
3
+ module Tumugi
4
+ module Parameter
5
+ class StringConverter
6
+ def convert(value, opts={})
7
+ value
8
+ end
9
+ end
10
+
11
+ class IntegerConverter
12
+ def convert(value, opts={})
13
+ Integer(value)
14
+ end
15
+ end
16
+
17
+ class FloatConverter
18
+ def convert(value, opts={})
19
+ Float(value)
20
+ end
21
+ end
22
+
23
+ class BoolConverter
24
+ def convert(value, opts={})
25
+ if value =~ /^(true|false)$/
26
+ value == 'true'
27
+ else
28
+ raise ArgumentError.new("Invalid value for Bool: '#{value}'")
29
+ end
30
+ end
31
+ end
32
+
33
+ class TimeConverter
34
+ def convert(value, opts={})
35
+ Time.parse(value)
36
+ end
37
+ end
38
+
39
+ class Converter
40
+ CONVERTERS = {
41
+ string: StringConverter.new,
42
+ integer: IntegerConverter.new,
43
+ float: FloatConverter.new,
44
+ bool: BoolConverter.new,
45
+ time: TimeConverter.new,
46
+ }
47
+
48
+ def self.convert(type, value)
49
+ converter = CONVERTERS[type]
50
+ if converter
51
+ converter.convert(value)
52
+ else
53
+ raise ArgumentError.new("Invalid type: #{type}")
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,6 @@
1
+ module Tumugi
2
+ module Parameter
3
+ class ParameterError < StandardError
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,81 @@
1
+ require 'tumugi/parameter/converter'
2
+ require 'tumugi/parameter/error'
3
+
4
+ module Tumugi
5
+ module Parameter
6
+ class Parameter
7
+ attr_accessor :name, :task_param_auto_bind_enabled, :application_param_auto_bind_enabled
8
+
9
+ def initialize(name, opts={})
10
+ @name = name
11
+ @opts = opts
12
+ @application_param_auto_bind_enabled = Tumugi.config.param_auto_bind_enabled
13
+ @task_param_auto_bind_enabled = @application_param_auto_bind_enabled
14
+ validate
15
+ end
16
+
17
+ def get
18
+ if auto_bind?
19
+ value = search_from_application_parameters
20
+ value = search_from_env if value.nil?
21
+ end
22
+
23
+ return value unless value.nil?
24
+ default_value
25
+ end
26
+
27
+ def auto_bind?
28
+ if @opts[:auto_bind].nil?
29
+ if @task_param_auto_bind_enabled
30
+ true
31
+ else
32
+ false
33
+ end
34
+ else
35
+ @opts[:auto_bind]
36
+ end
37
+ end
38
+
39
+ def required?
40
+ @opts[:required].nil? ? false : @opts[:required]
41
+ end
42
+
43
+ def type
44
+ @opts[:type] || :string
45
+ end
46
+
47
+ def default_value
48
+ @opts[:default] || nil
49
+ end
50
+
51
+ def overwrite_default(value)
52
+ @opts[:required] = false
53
+ @opts[:default] = value
54
+ end
55
+
56
+ private
57
+
58
+ def search_from_application_parameters
59
+ key = @name.to_s
60
+ value = Tumugi.application.params[key]
61
+ value ? Converter.convert(type, value) : nil
62
+ end
63
+
64
+ def search_from_env
65
+ key = @name.to_s
66
+ value = nil
67
+ value = ENV[key] if ENV.has_key?(key)
68
+ value = ENV[key.upcase] if ENV.has_key?(key.upcase)
69
+ value ? Converter.convert(type, value) : nil
70
+ end
71
+
72
+ private
73
+
74
+ def validate
75
+ if required? && default_value != nil
76
+ raise ParameterError.new("When you set required: true, you cannot set default value")
77
+ end
78
+ end
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,34 @@
1
+ require 'tumugi/parameter/parameter'
2
+
3
+ module Tumugi
4
+ module Parameter
5
+ class ParameterProxy
6
+ attr_accessor :name, :params, :param_defaults, :param_auto_bind_enabled
7
+
8
+ def initialize(name)
9
+ @name = name
10
+ @params = {}
11
+ @param_defaults = {}
12
+ end
13
+
14
+ def merge(other)
15
+ merged = self.class.new(other.name)
16
+ merged.params = other.params.merge(self.params)
17
+ merged.param_defaults = other.param_defaults.merge(self.param_defaults)
18
+ merged
19
+ end
20
+
21
+ def param(name, opts={})
22
+ @params[name] = Tumugi::Parameter::Parameter.new(name, opts)
23
+ end
24
+
25
+ def param_set(name, value)
26
+ @param_defaults[name] = value
27
+ end
28
+
29
+ def dump
30
+ Marshal.dump(self)
31
+ end
32
+ end
33
+ end
34
+ end
@@ -1,14 +1,17 @@
1
1
  require 'tumugi/mixin/listable'
2
2
  require 'tumugi/mixin/task_helper'
3
+ require 'tumugi/mixin/parameterizable'
3
4
 
4
5
  module Tumugi
5
6
  class Task
7
+ include Tumugi::Mixin::Parameterizable
6
8
  include Tumugi::Mixin::Listable
7
9
  include Tumugi::Mixin::TaskHelper
8
10
 
9
11
  attr_accessor :state # :pending, :running, :completed, :skipped
10
12
 
11
13
  def initialize
14
+ super()
12
15
  @state = :pending
13
16
  end
14
17
 
@@ -72,6 +75,10 @@ module Tumugi
72
75
  end
73
76
  end
74
77
 
78
+ def requires_failed?
79
+ list(_requires).any? { |t| t.instance.state == :failed || t.instance.state == :requires_failed }
80
+ end
81
+
75
82
  # Following methods are internal use only
76
83
 
77
84
  def _requires
@@ -20,6 +20,8 @@ module Tumugi
20
20
  def initialize(id, opts={})
21
21
  @id = id
22
22
  @opts = { type: Tumugi::Task }.merge(opts)
23
+ @params = {}
24
+ @param_defaults = {}
23
25
 
24
26
  unless @opts[:type].is_a?(Class)
25
27
  @opts[:type] = Tumugi::Plugin.lookup_task(@opts[:type])
@@ -30,6 +32,18 @@ module Tumugi
30
32
  @task ||= create_task
31
33
  end
32
34
 
35
+ def param(name, opts={})
36
+ @params[name] = opts
37
+ end
38
+
39
+ def param_set(name, value)
40
+ @param_defaults[name] = value
41
+ end
42
+
43
+ def param_auto_bind_enabled(v)
44
+ @param_auto_bind_enabled = v
45
+ end
46
+
33
47
  def requires(tasks)
34
48
  @required_tasks = tasks
35
49
  end
@@ -64,10 +78,11 @@ module Tumugi
64
78
  end
65
79
 
66
80
  def define_task
67
- task_class = Class.new(@opts[:type])
81
+ task_class = Class.new(lookup_parent_task_class)
68
82
  define_requires_method(task_class)
69
83
  define_output_method(task_class)
70
84
  define_run_method(task_class)
85
+ setup_params(task_class)
71
86
  task_class
72
87
  end
73
88
 
@@ -106,5 +121,25 @@ module Tumugi
106
121
  end
107
122
  end unless @run.nil?
108
123
  end
124
+
125
+ def setup_params(task_class)
126
+ @params.each do |name, opts|
127
+ task_class.param(name, opts)
128
+ end
129
+ @param_defaults.each do |name, value|
130
+ task_class.param_set(name, value)
131
+ end
132
+ unless @param_auto_bind_enabled.nil?
133
+ task_class.param_auto_bind_enabled(@param_auto_bind_enabled)
134
+ end
135
+ end
136
+
137
+ def lookup_parent_task_class
138
+ if @opts[:type].is_a?(Class)
139
+ @opts[:type]
140
+ else
141
+ Tumugi::Plugin.lookup_task(@opts[:type])
142
+ end
143
+ end
109
144
  end
110
145
  end
@@ -1,3 +1,3 @@
1
1
  module Tumugi
2
- VERSION = "0.2.0"
2
+ VERSION = "0.3.0"
3
3
  end
@@ -23,6 +23,7 @@ Gem::Specification.new do |spec|
23
23
  spec.add_runtime_dependency 'parallel', '~> 1.8.0'
24
24
  spec.add_runtime_dependency 'retriable', '~> 2.1'
25
25
  spec.add_runtime_dependency 'ruby-graphviz', '~> 1.2.2'
26
+ spec.add_runtime_dependency 'terminal-table', '~> 1.5.2'
26
27
  spec.add_runtime_dependency 'thor', '~> 0.19.1'
27
28
 
28
29
  spec.add_development_dependency 'bundler', '~> 1.11'
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.2.0
4
+ version: 0.3.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-05-02 00:00:00.000000000 Z
11
+ date: 2016-05-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: parallel
@@ -52,6 +52,20 @@ dependencies:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
54
  version: 1.2.2
55
+ - !ruby/object:Gem::Dependency
56
+ name: terminal-table
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: 1.5.2
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 1.5.2
55
69
  - !ruby/object:Gem::Dependency
56
70
  name: thor
57
71
  requirement: !ruby/object:Gem::Requirement
@@ -169,9 +183,14 @@ files:
169
183
  - bin/setup
170
184
  - examples/concurrent_task_run.rb
171
185
  - examples/data_pipeline.rb
186
+ - examples/fail_first_task.rb
187
+ - examples/fail_intermediate_task.rb
188
+ - examples/fail_last_task.rb
172
189
  - examples/simple.rb
173
190
  - examples/target.rb
174
191
  - examples/task_inheritance.rb
192
+ - examples/task_parameter.rb
193
+ - examples/tumugi_config.rb
175
194
  - exe/tumugi
176
195
  - lib/tumugi.rb
177
196
  - lib/tumugi/application.rb
@@ -186,7 +205,12 @@ files:
186
205
  - lib/tumugi/file_system_error.rb
187
206
  - lib/tumugi/logger.rb
188
207
  - lib/tumugi/mixin/listable.rb
208
+ - lib/tumugi/mixin/parameterizable.rb
189
209
  - lib/tumugi/mixin/task_helper.rb
210
+ - lib/tumugi/parameter/converter.rb
211
+ - lib/tumugi/parameter/error.rb
212
+ - lib/tumugi/parameter/parameter.rb
213
+ - lib/tumugi/parameter/parameter_proxy.rb
190
214
  - lib/tumugi/plugin.rb
191
215
  - lib/tumugi/plugin/atomic_local_file.rb
192
216
  - lib/tumugi/plugin/file_system_target.rb