tumugi 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.travis.yml +8 -7
- data/CHANGELOG.md +43 -0
- data/README.md +1 -1
- data/Rakefile +4 -0
- data/examples/concurrent_task_run.rb +9 -10
- data/examples/data_pipeline.rb +7 -9
- data/examples/simple.rb +4 -4
- data/examples/target.rb +17 -32
- data/examples/task_inheritance.rb +11 -7
- data/lib/tumugi.rb +20 -0
- data/lib/tumugi/application.rb +4 -3
- data/lib/tumugi/atomic_file.rb +49 -0
- data/lib/tumugi/cli.rb +3 -4
- data/lib/tumugi/command/show.rb +19 -12
- data/lib/tumugi/dag.rb +2 -2
- data/lib/tumugi/file_system.rb +38 -0
- data/lib/tumugi/file_system_error.rb +13 -0
- data/lib/tumugi/logger.rb +1 -0
- data/lib/tumugi/mixin/listable.rb +17 -0
- data/lib/tumugi/mixin/task_helper.rb +12 -0
- data/lib/tumugi/plugin.rb +43 -0
- data/lib/tumugi/plugin/atomic_local_file.rb +12 -0
- data/lib/tumugi/plugin/file_system_target.rb +30 -0
- data/lib/tumugi/plugin/local_file_system.rb +62 -0
- data/lib/tumugi/plugin/target/local_file.rb +25 -0
- data/lib/tumugi/registry.rb +56 -0
- data/lib/tumugi/target.rb +17 -0
- data/lib/tumugi/task.rb +17 -4
- data/lib/tumugi/task_definition.rb +13 -4
- data/lib/tumugi/version.rb +1 -1
- data/tumugi.gemspec +5 -3
- metadata +42 -33
- data/lib/tumugi/helper.rb +0 -15
- data/lib/tumugi/target/base.rb +0 -9
- data/lib/tumugi/target/file_target.rb +0 -17
- data/lib/tumugi/tumugi_module.rb +0 -23
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: fe91c5dd14b1c75b8562de885608d52d9f8ff927
|
|
4
|
+
data.tar.gz: 7ce1c778ca4614bb5a9a4be2e04ac1d75dc59a5b
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 5005eed43b4ec6261c0870c89afe93609c516719541f67dd9ef683f1b0742b6ed8e8dedb574eb578485612856d3096aab64198ef55c8e8cefead786d3f538663
|
|
7
|
+
data.tar.gz: 3208bf2657f87d7f76dd39a568e9ec356c549ddfca95986e8f879d3ac0b88b2c017ab150159b3cec7b653c37e9fdd86cda56414f1df817f228879bf061c18cee
|
data/.travis.yml
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
language: ruby
|
|
2
2
|
rvm:
|
|
3
3
|
- 2.0.0-p648
|
|
4
|
-
- 2.1.
|
|
5
|
-
- 2.2.
|
|
6
|
-
- 2.3.
|
|
4
|
+
- 2.1.10
|
|
5
|
+
- 2.2.5
|
|
6
|
+
- 2.3.1
|
|
7
7
|
- jruby-9.0.5.0
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
8
|
+
cache: bundler
|
|
9
|
+
addons:
|
|
10
|
+
apt:
|
|
11
|
+
packages:
|
|
12
|
+
- graphviz
|
data/CHANGELOG.md
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# Change Log
|
|
2
|
+
|
|
3
|
+
## [v0.2.0](https://github.com/tumugi/tumugi/tree/v0.2.0) (2016-05-02)
|
|
4
|
+
[Full Changelog](https://github.com/tumugi/tumugi/compare/v0.1.0...v0.2.0)
|
|
5
|
+
|
|
6
|
+
**Implemented enhancements:**
|
|
7
|
+
|
|
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))
|
|
10
|
+
- \[Breaking Change\] Add Task\#logger and Task\#log method [\#12](https://github.com/tumugi/tumugi/pull/12) ([hakobera](https://github.com/hakobera))
|
|
11
|
+
- Update command description / Set file options mandatory [\#11](https://github.com/tumugi/tumugi/pull/11) ([hakobera](https://github.com/hakobera))
|
|
12
|
+
|
|
13
|
+
**Fixed bugs:**
|
|
14
|
+
|
|
15
|
+
- Fix show command cannot handle task which id include underscore [\#13](https://github.com/tumugi/tumugi/pull/13) ([hakobera](https://github.com/hakobera))
|
|
16
|
+
|
|
17
|
+
**Merged pull requests:**
|
|
18
|
+
|
|
19
|
+
- Use bundler cache on travis [\#17](https://github.com/tumugi/tumugi/pull/17) ([hakobera](https://github.com/hakobera))
|
|
20
|
+
- Add gem version badge to README [\#16](https://github.com/tumugi/tumugi/pull/16) ([hakobera](https://github.com/hakobera))
|
|
21
|
+
- Add changelog of v0.1.0 [\#10](https://github.com/tumugi/tumugi/pull/10) ([hakobera](https://github.com/hakobera))
|
|
22
|
+
|
|
23
|
+
## [v0.1.0](https://github.com/tumugi/tumugi/tree/v0.1.0) (2016-04-28)
|
|
24
|
+
**Implemented enhancements:**
|
|
25
|
+
|
|
26
|
+
- Retry when task failed [\#8](https://github.com/tumugi/tumugi/pull/8) ([hakobera](https://github.com/hakobera))
|
|
27
|
+
- Support run tasks concurrently [\#7](https://github.com/tumugi/tumugi/pull/7) ([hakobera](https://github.com/hakobera))
|
|
28
|
+
- Visualize [\#6](https://github.com/tumugi/tumugi/pull/6) ([hakobera](https://github.com/hakobera))
|
|
29
|
+
- Support task inheritance [\#5](https://github.com/tumugi/tumugi/pull/5) ([hakobera](https://github.com/hakobera))
|
|
30
|
+
- First DSL implementation [\#3](https://github.com/tumugi/tumugi/pull/3) ([hakobera](https://github.com/hakobera))
|
|
31
|
+
|
|
32
|
+
**Closed issues:**
|
|
33
|
+
|
|
34
|
+
- Features and Tasks for v0.1 [\#4](https://github.com/tumugi/tumugi/issues/4)
|
|
35
|
+
|
|
36
|
+
**Merged pull requests:**
|
|
37
|
+
|
|
38
|
+
- Create gem [\#2](https://github.com/tumugi/tumugi/pull/2) ([hakobera](https://github.com/hakobera))
|
|
39
|
+
- Add initial spec [\#1](https://github.com/tumugi/tumugi/pull/1) ([hakobera](https://github.com/hakobera))
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
\* *This Change Log was automatically generated by [github_changelog_generator](https://github.com/skywinder/Github-Changelog-Generator)*
|
data/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
[](https://travis-ci.org/tumugi/tumugi) [](https://codeclimate.com/github/tumugi/tumugi) [](https://coveralls.io/github/tumugi/tumugi?branch=master)
|
|
1
|
+
[](https://travis-ci.org/tumugi/tumugi) [](https://codeclimate.com/github/tumugi/tumugi) [](https://coveralls.io/github/tumugi/tumugi?branch=master) [](https://badge.fury.io/rb/tumugi)
|
|
2
2
|
|
|
3
3
|
# Tumugi
|
|
4
4
|
|
data/Rakefile
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
require "bundler/gem_tasks"
|
|
2
2
|
require "rake/testtask"
|
|
3
|
+
require "github_changelog_generator/task"
|
|
3
4
|
|
|
4
5
|
Rake::TestTask.new(:test) do |t|
|
|
5
6
|
t.libs << "test"
|
|
@@ -7,4 +8,7 @@ Rake::TestTask.new(:test) do |t|
|
|
|
7
8
|
t.test_files = FileList['test/**/*_test.rb']
|
|
8
9
|
end
|
|
9
10
|
|
|
11
|
+
GitHubChangelogGenerator::RakeTask.new :changelog do |config|
|
|
12
|
+
end
|
|
13
|
+
|
|
10
14
|
task :default => :test
|
|
@@ -1,27 +1,26 @@
|
|
|
1
|
-
require 'tumugi/target/file_target'
|
|
2
|
-
|
|
3
1
|
class FileTask < Tumugi::Task
|
|
2
|
+
Tumugi::Plugin.register_task(:local_file, self)
|
|
3
|
+
|
|
4
4
|
def output
|
|
5
|
-
|
|
5
|
+
target(:local_file, "/tmp/tumugi_#{self.id}.txt")
|
|
6
6
|
end
|
|
7
7
|
|
|
8
8
|
def run
|
|
9
|
-
|
|
10
|
-
sleep
|
|
11
|
-
|
|
12
|
-
@logger.info "#{self.id}#done"
|
|
9
|
+
log 'sleep 2 seconds'
|
|
10
|
+
sleep 2
|
|
11
|
+
output.open('w') {|f| f.puts('done') }
|
|
13
12
|
end
|
|
14
13
|
end
|
|
15
14
|
|
|
16
|
-
task :task1, type:
|
|
15
|
+
task :task1, type: :local_file do
|
|
17
16
|
requires (1..10).map {|i| :"task2_#{i}"}
|
|
18
17
|
end
|
|
19
18
|
|
|
20
19
|
(1..10).each do |i|
|
|
21
|
-
task :"task2_#{i}", type:
|
|
20
|
+
task :"task2_#{i}", type: :local_file do
|
|
22
21
|
requires [:task3]
|
|
23
22
|
end
|
|
24
23
|
end
|
|
25
24
|
|
|
26
|
-
task :task3, type:
|
|
25
|
+
task :task3, type: :local_file do
|
|
27
26
|
end
|
data/examples/data_pipeline.rb
CHANGED
|
@@ -1,12 +1,10 @@
|
|
|
1
|
-
require 'tumugi/target/file_target'
|
|
2
|
-
|
|
3
1
|
task :generate_data do
|
|
4
2
|
output do
|
|
5
|
-
|
|
3
|
+
target(:local_file, "/tmp/tumugi_data_#{Time.now.strftime('%Y-%m-%d')}.txt")
|
|
6
4
|
end
|
|
7
5
|
|
|
8
|
-
run do
|
|
9
|
-
|
|
6
|
+
run do
|
|
7
|
+
output.open('w') do |f|
|
|
10
8
|
(1..10).each do |i|
|
|
11
9
|
f.puts i
|
|
12
10
|
end
|
|
@@ -18,14 +16,14 @@ task :sum do
|
|
|
18
16
|
requires :generate_data
|
|
19
17
|
|
|
20
18
|
output do
|
|
21
|
-
|
|
19
|
+
target(:local_file, "/tmp/tumugi_output_#{Time.now.strftime('%Y-%m-%d')}.txt")
|
|
22
20
|
end
|
|
23
21
|
|
|
24
|
-
run do
|
|
22
|
+
run do
|
|
25
23
|
sum = 0
|
|
26
|
-
|
|
24
|
+
input.open do |line|
|
|
27
25
|
sum += line.to_i
|
|
28
26
|
end
|
|
29
|
-
|
|
27
|
+
output { |f| f.puts(sum) }
|
|
30
28
|
end
|
|
31
29
|
end
|
data/examples/simple.rb
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
task :task1 do
|
|
2
2
|
requires [:task2, :task3]
|
|
3
|
-
run {
|
|
3
|
+
run { log 'task1#run' }
|
|
4
4
|
end
|
|
5
5
|
|
|
6
6
|
task :task2 do
|
|
7
7
|
requires [:task4]
|
|
8
|
-
run {
|
|
8
|
+
run { log 'task2#run' }
|
|
9
9
|
end
|
|
10
10
|
|
|
11
11
|
task :task3 do
|
|
12
12
|
requires [:task4]
|
|
13
|
-
run {
|
|
13
|
+
run { log 'task3#run' }
|
|
14
14
|
end
|
|
15
15
|
|
|
16
16
|
task :task4 do
|
|
17
17
|
run do
|
|
18
|
-
|
|
18
|
+
log 'task4#run'
|
|
19
19
|
sleep 1
|
|
20
20
|
end
|
|
21
21
|
end
|
data/examples/target.rb
CHANGED
|
@@ -1,51 +1,36 @@
|
|
|
1
|
-
require 'tumugi/target/
|
|
1
|
+
require 'tumugi/plugin/target/local_file'
|
|
2
2
|
|
|
3
3
|
task :task1 do
|
|
4
4
|
requires [:task2, :task3]
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
run do |task|
|
|
11
|
-
puts 'task1#run'
|
|
12
|
-
File.write(task.output.path, 'done')
|
|
5
|
+
output target(:local_file, "/tmp/tumugi_#{id}.txt")
|
|
6
|
+
run do
|
|
7
|
+
log 'task1#run'
|
|
8
|
+
output.open('w') {|f| f.puts('done') }
|
|
13
9
|
end
|
|
14
10
|
end
|
|
15
11
|
|
|
16
12
|
task :task2 do
|
|
17
13
|
requires [:task4]
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
run do |task|
|
|
24
|
-
puts 'task2#run'
|
|
25
|
-
File.write(task.output.path, 'done')
|
|
14
|
+
output [target(:local_file, "/tmp/tumugi_#{id}.txt")]
|
|
15
|
+
run do
|
|
16
|
+
log 'task2#run'
|
|
17
|
+
output[0].open('w') {|f| f.puts('done') }
|
|
26
18
|
end
|
|
27
19
|
end
|
|
28
20
|
|
|
29
21
|
task :task3 do
|
|
30
22
|
requires [:task4]
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
run do |task|
|
|
37
|
-
puts 'task3#run'
|
|
38
|
-
File.write(task.output.path, 'done')
|
|
23
|
+
output { target(:local_file, "/tmp/tumugi_#{id}.txt") }
|
|
24
|
+
run do
|
|
25
|
+
log 'task3#run'
|
|
26
|
+
output.open('w') {|f| f.puts('done') }
|
|
39
27
|
end
|
|
40
28
|
end
|
|
41
29
|
|
|
42
30
|
task :task4 do
|
|
43
|
-
output
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
run do |task|
|
|
48
|
-
puts 'task4#run'
|
|
49
|
-
File.write(task.output.path, 'done')
|
|
31
|
+
output Tumugi::Plugin::LocalFileTarget.new("/tmp/tumugi_#{id}.txt")
|
|
32
|
+
run do
|
|
33
|
+
log 'task4#run'
|
|
34
|
+
output.open('w') {|f| f.puts('done') }
|
|
50
35
|
end
|
|
51
36
|
end
|
|
@@ -1,24 +1,28 @@
|
|
|
1
|
-
require 'tumugi/target/file_target'
|
|
2
|
-
|
|
3
1
|
class FileTask < Tumugi::Task
|
|
2
|
+
Tumugi::Plugin.register_task(:file, self)
|
|
3
|
+
|
|
4
4
|
def output
|
|
5
|
-
|
|
5
|
+
target(:local_file, "/tmp/#{id}.txt")
|
|
6
6
|
end
|
|
7
7
|
|
|
8
8
|
def run
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
log "#{id}#run"
|
|
10
|
+
output.open('w') do |f|
|
|
11
|
+
f.puts('done')
|
|
12
|
+
end
|
|
11
13
|
end
|
|
12
14
|
end
|
|
13
15
|
|
|
14
|
-
|
|
16
|
+
# Task type can specified by task plugin ID
|
|
17
|
+
task :task1, type: :file do
|
|
15
18
|
requires [:task2, :task3]
|
|
16
19
|
end
|
|
17
20
|
|
|
18
|
-
task :task2, type:
|
|
21
|
+
task :task2, type: :file do
|
|
19
22
|
requires [:task4]
|
|
20
23
|
end
|
|
21
24
|
|
|
25
|
+
# You can also specify type by Class object
|
|
22
26
|
task :task3, type: FileTask do
|
|
23
27
|
requires [:task4]
|
|
24
28
|
end
|
data/lib/tumugi.rb
CHANGED
|
@@ -1,4 +1,24 @@
|
|
|
1
|
+
require 'tumugi/application'
|
|
2
|
+
require 'tumugi/config'
|
|
3
|
+
require 'tumugi/logger'
|
|
1
4
|
require 'tumugi/version'
|
|
2
5
|
|
|
3
6
|
module Tumugi
|
|
7
|
+
class << self
|
|
8
|
+
def application
|
|
9
|
+
@application ||= Tumugi::Application.new
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def logger
|
|
13
|
+
@logger ||= Tumugi::Logger.new
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def config
|
|
17
|
+
@config ||= Tumugi::Config.new
|
|
18
|
+
if block_given?
|
|
19
|
+
yield @config
|
|
20
|
+
end
|
|
21
|
+
@config
|
|
22
|
+
end
|
|
23
|
+
end
|
|
4
24
|
end
|
data/lib/tumugi/application.rb
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
require "active_support/all"
|
|
2
|
-
|
|
3
1
|
require 'tumugi/dag'
|
|
4
2
|
require 'tumugi/dsl'
|
|
3
|
+
require 'tumugi/plugin'
|
|
4
|
+
require 'tumugi/target'
|
|
5
5
|
require 'tumugi/command/run'
|
|
6
6
|
require 'tumugi/command/show'
|
|
7
7
|
|
|
@@ -14,7 +14,8 @@ module Tumugi
|
|
|
14
14
|
def execute(command, root_task_id, options)
|
|
15
15
|
load(options[:file], true)
|
|
16
16
|
dag = create_dag(root_task_id)
|
|
17
|
-
|
|
17
|
+
command_module = Kernel.const_get("Tumugi").const_get("Command")
|
|
18
|
+
cmd = command_module.const_get("#{command.to_s.capitalize}").new
|
|
18
19
|
cmd.execute(dag, options)
|
|
19
20
|
end
|
|
20
21
|
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
require 'tempfile'
|
|
2
|
+
require 'forwardable'
|
|
3
|
+
|
|
4
|
+
module Tumugi
|
|
5
|
+
class AtomicFile
|
|
6
|
+
extend Forwardable
|
|
7
|
+
def_delegators :@temp_file,
|
|
8
|
+
:bin_mode?, :print, :printf, :putc, :puts, :write,
|
|
9
|
+
:seek, :set_encoding, :sync, :sync=, :sysseek,
|
|
10
|
+
:syswrite, :write, :write_nonblock
|
|
11
|
+
|
|
12
|
+
def initialize(path)
|
|
13
|
+
@path = path
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
attr_reader :path
|
|
17
|
+
|
|
18
|
+
def open(&block)
|
|
19
|
+
if block_given?
|
|
20
|
+
Tempfile.open(basename) do |fp|
|
|
21
|
+
@temp_file = fp
|
|
22
|
+
block.call(self)
|
|
23
|
+
close
|
|
24
|
+
end
|
|
25
|
+
else
|
|
26
|
+
@temp_file = Tempfile.open(basename)
|
|
27
|
+
end
|
|
28
|
+
self
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def close
|
|
32
|
+
if @temp_file
|
|
33
|
+
move_to_final_destination(@temp_file)
|
|
34
|
+
@temp_file.close
|
|
35
|
+
@temp_file = nil
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def move_to_final_destination(temp_file)
|
|
40
|
+
raise NotImplementedError, "You must implement #{self.class}##{__method__}"
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
private
|
|
44
|
+
|
|
45
|
+
def basename
|
|
46
|
+
@basename ||= File.basename(@path)
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
data/lib/tumugi/cli.rb
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
require 'thor'
|
|
2
2
|
require 'tumugi'
|
|
3
|
-
require 'tumugi/tumugi_module'
|
|
4
3
|
|
|
5
4
|
module Tumugi
|
|
6
5
|
class CLI < Thor
|
|
@@ -8,7 +7,7 @@ module Tumugi
|
|
|
8
7
|
|
|
9
8
|
class << self
|
|
10
9
|
def common_options
|
|
11
|
-
option :file, aliases: '-f', desc: 'Task definition file name'
|
|
10
|
+
option :file, aliases: '-f', desc: 'Task definition file name', required: true
|
|
12
11
|
option :config, aliases: '-c', desc: 'Configuration file name', default: 'tumugi.rb'
|
|
13
12
|
end
|
|
14
13
|
end
|
|
@@ -18,7 +17,7 @@ module Tumugi
|
|
|
18
17
|
puts "tumugi v#{Tumugi::VERSION}"
|
|
19
18
|
end
|
|
20
19
|
|
|
21
|
-
desc "run", "Run workflow"
|
|
20
|
+
desc "run TASK", "Run TASK in a workflow"
|
|
22
21
|
map "run" => "run_" # run is thor's reserved word, so this trick is needed
|
|
23
22
|
option :workers, aliases: '-w', type: :numeric, desc: 'Number of workers to run task concurrently'
|
|
24
23
|
option :quiet, type: :boolean, desc: 'Suppress log', default: false
|
|
@@ -29,7 +28,7 @@ module Tumugi
|
|
|
29
28
|
Tumugi.application.execute(:run, task, options)
|
|
30
29
|
end
|
|
31
30
|
|
|
32
|
-
desc "show", "Show DAG of workflow"
|
|
31
|
+
desc "show TASK", "Show DAG of TASK in a workflow"
|
|
33
32
|
common_options
|
|
34
33
|
option :out, aliases: '-o', desc: 'Output file name. If not specified, output result to STDOUT'
|
|
35
34
|
option :format, aliases: '-t', desc: 'Output file format. Only affected --out option is specified.', enum: ['dot', 'png', 'svg']
|
data/lib/tumugi/command/show.rb
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
|
-
require '
|
|
1
|
+
require 'graphviz'
|
|
2
2
|
require 'tmpdir'
|
|
3
3
|
require 'fileutils'
|
|
4
|
+
require 'tumugi/mixin/listable'
|
|
4
5
|
|
|
5
6
|
module Tumugi
|
|
6
7
|
module Command
|
|
7
8
|
class Show
|
|
9
|
+
include Tumugi::Mixin::Listable
|
|
10
|
+
|
|
8
11
|
@@supported_formats = ['dot', 'png', 'jpg', 'svg', 'pdf']
|
|
9
12
|
|
|
10
13
|
def execute(dag, options={})
|
|
@@ -17,22 +20,26 @@ module Tumugi
|
|
|
17
20
|
format = options[:format]
|
|
18
21
|
end
|
|
19
22
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
23
|
+
g = GraphViz.new(:G, type: :digraph, rankdir: "RL")
|
|
24
|
+
tasks = dag.tsort
|
|
25
|
+
tasks.each do |task|
|
|
26
|
+
g.add_nodes(task.id.to_s)
|
|
27
|
+
end
|
|
28
|
+
tasks.each do |task|
|
|
29
|
+
list(task._requires).each do |req|
|
|
30
|
+
g.add_edge(g.get_node(req.id.to_s), g.get_node(task.id.to_s))
|
|
24
31
|
end
|
|
25
32
|
end
|
|
26
33
|
|
|
27
|
-
if out
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
34
|
+
if out
|
|
35
|
+
FileUtils.mkdir_p(File.dirname(out))
|
|
36
|
+
if format == 'dot'
|
|
37
|
+
File.write(out, g.to_s)
|
|
38
|
+
else
|
|
39
|
+
g.output(format => out)
|
|
33
40
|
end
|
|
34
41
|
else
|
|
35
|
-
print
|
|
42
|
+
print g
|
|
36
43
|
end
|
|
37
44
|
end
|
|
38
45
|
end
|
data/lib/tumugi/dag.rb
CHANGED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
require 'tumugi'
|
|
2
|
+
require 'tumugi/file_system_error'
|
|
3
|
+
|
|
4
|
+
module Tumugi
|
|
5
|
+
# This class defines interfaces of file system
|
|
6
|
+
# such as local file, Amazon S3, Google Cloud Storage
|
|
7
|
+
class FileSystem
|
|
8
|
+
def exist?(path)
|
|
9
|
+
raise NotImplementedError, "You must implement #{self.class}##{__method__}"
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def remove(path, recursive: true)
|
|
13
|
+
raise NotImplementedError, "You must implement #{self.class}##{__method__}"
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def mkdir(path, parents: true, raise_if_exist: false)
|
|
17
|
+
raise NotImplementedError, "You must implement #{self.class}##{__method__}"
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def directory?(path)
|
|
21
|
+
raise NotImplementedError, "You must implement #{self.class}##{__method__}"
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def entries(path)
|
|
25
|
+
raise NotImplementedError, "You must implement #{self.class}##{__method__}"
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def move(src, dest, raise_if_exist: false)
|
|
29
|
+
raise NotImplementedError, "You must implement #{self.class}##{__method__}"
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def rename(path, dest)
|
|
33
|
+
Tumugi.logger.warn "File system #{self.class.name} client doesn't support atomic move."
|
|
34
|
+
raise FileAlreadyExistError if exist?(dest)
|
|
35
|
+
move(path, dest)
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
data/lib/tumugi/logger.rb
CHANGED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
require 'tumugi'
|
|
2
|
+
require 'tumugi/registry'
|
|
3
|
+
|
|
4
|
+
module Tumugi
|
|
5
|
+
module Plugin
|
|
6
|
+
TARGET_REGISTRY = Registry.new(:target, 'tumugi/plugin/target/')
|
|
7
|
+
TASK_REGISTRY = Registry.new(:task, 'tumugi/plugin/task/')
|
|
8
|
+
|
|
9
|
+
def self.register_target(type, klass)
|
|
10
|
+
register_impl('target', TARGET_REGISTRY, type, klass)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def self.register_task(type, klass)
|
|
14
|
+
register_impl('task', TASK_REGISTRY, type, klass)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def self.register_impl(kind, registry, type, value)
|
|
18
|
+
if !value.is_a?(Class)
|
|
19
|
+
raise "Invalid implementation as #{kind} plugin: '#{type}'. It must be a Class."
|
|
20
|
+
end
|
|
21
|
+
registry.register(type, value)
|
|
22
|
+
Tumugi.logger.debug "registered #{kind} plugin '#{type}'"
|
|
23
|
+
nil
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def self.lookup_target(type)
|
|
27
|
+
lookup_impl('target', TARGET_REGISTRY, type)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def self.lookup_task(type)
|
|
31
|
+
lookup_impl('task', TASK_REGISTRY, type)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def self.lookup_impl(kind, registry, type)
|
|
35
|
+
obj = registry.lookup(type)
|
|
36
|
+
if obj.is_a?(Class)
|
|
37
|
+
obj
|
|
38
|
+
else
|
|
39
|
+
raise "#{kind} plugin '#{type}' is not a Class"
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
require 'tumugi/target'
|
|
2
|
+
require 'tumugi/file_system'
|
|
3
|
+
require 'tumugi/file_system_error'
|
|
4
|
+
|
|
5
|
+
module Tumugi
|
|
6
|
+
module Plugin
|
|
7
|
+
class FileSystemTarget < Target
|
|
8
|
+
attr_reader :path
|
|
9
|
+
|
|
10
|
+
def initialize(path)
|
|
11
|
+
@path = path
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def fs
|
|
15
|
+
raise NotImplementedError, "You must implement #{self.class}##{__method__}"
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def open(mode="r")
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def exist?
|
|
22
|
+
fs.exist?(@path)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def remove
|
|
26
|
+
fs.remove(@path)
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
require 'fileutils'
|
|
2
|
+
require 'tumugi/file_system'
|
|
3
|
+
require 'tumugi/file_system_error'
|
|
4
|
+
|
|
5
|
+
module Tumugi
|
|
6
|
+
module Plugin
|
|
7
|
+
class LocalFileSystem
|
|
8
|
+
def exist?(path)
|
|
9
|
+
File.exist?(path)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def remove(path, recursive: true)
|
|
13
|
+
if recursive && directory?(path)
|
|
14
|
+
FileUtils.rm_r(path)
|
|
15
|
+
else
|
|
16
|
+
FileUtils.remove_file(path)
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def mkdir(path, parents: true, raise_if_exist: false)
|
|
21
|
+
if File.exist?(path)
|
|
22
|
+
if raise_if_exist
|
|
23
|
+
raise FileAlreadyExistError
|
|
24
|
+
elsif !directory?(path)
|
|
25
|
+
raise NotADirectoryError
|
|
26
|
+
else
|
|
27
|
+
return
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
if parents
|
|
32
|
+
FileUtils.mkdir_p(path)
|
|
33
|
+
else
|
|
34
|
+
if File.exist?(File.expand_path("..", path))
|
|
35
|
+
FileUtils.mkdir(path)
|
|
36
|
+
else
|
|
37
|
+
raise MissingParentDirectoryError
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def directory?(path)
|
|
43
|
+
File.directory?(path)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def entries(path)
|
|
47
|
+
if directory?(path)
|
|
48
|
+
Dir.glob(File.join(path, '*'))
|
|
49
|
+
else
|
|
50
|
+
raise NotADirectoryError
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def move(src, dest, raise_if_exist: false)
|
|
55
|
+
if File.exist?(dest) && raise_if_exist
|
|
56
|
+
raise FileAlreadyExistError
|
|
57
|
+
end
|
|
58
|
+
FileUtils.mv(src, dest, force: true)
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
require 'tumugi/plugin/atomic_local_file'
|
|
2
|
+
require 'tumugi/plugin/file_system_target'
|
|
3
|
+
require 'tumugi/plugin/local_file_system'
|
|
4
|
+
|
|
5
|
+
module Tumugi
|
|
6
|
+
module Plugin
|
|
7
|
+
class LocalFileTarget < FileSystemTarget
|
|
8
|
+
Plugin.register_target(:local_file, self)
|
|
9
|
+
|
|
10
|
+
def fs
|
|
11
|
+
@fs ||= LocalFileSystem.new
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def open(mode="r", &block)
|
|
15
|
+
if mode.include? 'r'
|
|
16
|
+
File.open(path, mode, &block)
|
|
17
|
+
elsif mode.include? 'w'
|
|
18
|
+
AtomicLocalFile.new(path).open(&block)
|
|
19
|
+
else
|
|
20
|
+
raise 'Invalid mode: #{mode}'
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
module Tumugi
|
|
2
|
+
class Registry
|
|
3
|
+
DEFAULT_PLUGIN_PATH = File.expand_path('plugin', __FILE__)
|
|
4
|
+
|
|
5
|
+
def initialize(kind, search_prefix)
|
|
6
|
+
@kind = kind
|
|
7
|
+
@search_prefix = search_prefix
|
|
8
|
+
@map = {}
|
|
9
|
+
@paths = [DEFAULT_PLUGIN_PATH]
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
attr_reader :kind, :paths
|
|
13
|
+
|
|
14
|
+
def register(type, value)
|
|
15
|
+
type = type.to_sym
|
|
16
|
+
@map[type] = value
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def lookup(type)
|
|
20
|
+
t = type.to_sym
|
|
21
|
+
return @map[t] if @map.has_key?(t)
|
|
22
|
+
search(type)
|
|
23
|
+
return @map[t] if @map.has_key?(t)
|
|
24
|
+
raise "Unknown #{@kind} plugin '#{type}'"
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def search(type)
|
|
28
|
+
path = "#{@search_prefix}#{type}"
|
|
29
|
+
|
|
30
|
+
# prefer LOAD_PATH than gems
|
|
31
|
+
[@paths, $LOAD_PATH].each do |paths|
|
|
32
|
+
files = paths.map { |lp|
|
|
33
|
+
lpath = File.expand_path(File.join(lp, "#{path}.rb"))
|
|
34
|
+
File.exist?(lpath) ? lpath : nil
|
|
35
|
+
}.compact
|
|
36
|
+
unless files.empty?
|
|
37
|
+
require files.sort.last
|
|
38
|
+
return
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
specs = Gem::Specification.find_all { |spec|
|
|
43
|
+
spec.contains_requirable_file? path
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
# prefer newer version
|
|
47
|
+
specs = specs.sort_by { |spec| spec.version }
|
|
48
|
+
if spec = specs.last
|
|
49
|
+
spec.require_paths.each do |lib|
|
|
50
|
+
file = "#{spec.full_gem_path}/#{lib}/#{path}"
|
|
51
|
+
return file
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
require 'tumugi'
|
|
2
|
+
|
|
3
|
+
module Tumugi
|
|
4
|
+
class Target
|
|
5
|
+
def exist?
|
|
6
|
+
raise NotImplementedError, "You must implement #{self.class}##{__method__}"
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def logger
|
|
10
|
+
@logger ||= Tumugi.logger
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def log(msg)
|
|
14
|
+
logger.info(msg)
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
data/lib/tumugi/task.rb
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
|
-
require 'tumugi/
|
|
1
|
+
require 'tumugi/mixin/listable'
|
|
2
|
+
require 'tumugi/mixin/task_helper'
|
|
2
3
|
|
|
3
4
|
module Tumugi
|
|
4
5
|
class Task
|
|
5
|
-
include Tumugi::
|
|
6
|
+
include Tumugi::Mixin::Listable
|
|
7
|
+
include Tumugi::Mixin::TaskHelper
|
|
6
8
|
|
|
7
9
|
attr_accessor :state # :pending, :running, :completed, :skipped
|
|
8
10
|
|
|
9
11
|
def initialize
|
|
10
|
-
@logger = Tumugi.logger
|
|
11
12
|
@state = :pending
|
|
12
13
|
end
|
|
13
14
|
|
|
@@ -31,6 +32,14 @@ module Tumugi
|
|
|
31
32
|
self
|
|
32
33
|
end
|
|
33
34
|
|
|
35
|
+
def logger
|
|
36
|
+
@logger ||= Tumugi.logger
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def log(msg)
|
|
40
|
+
logger.info(msg)
|
|
41
|
+
end
|
|
42
|
+
|
|
34
43
|
# If you need to define task dependencies, override in subclass
|
|
35
44
|
def requires
|
|
36
45
|
[]
|
|
@@ -56,7 +65,11 @@ module Tumugi
|
|
|
56
65
|
|
|
57
66
|
def completed?
|
|
58
67
|
outputs = list(output)
|
|
59
|
-
|
|
68
|
+
if outputs.empty?
|
|
69
|
+
@state == :completed || @state == :skipped
|
|
70
|
+
else
|
|
71
|
+
outputs.all?(&:exist?)
|
|
72
|
+
end
|
|
60
73
|
end
|
|
61
74
|
|
|
62
75
|
# Following methods are internal use only
|
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
require 'tumugi/task'
|
|
2
|
+
require 'tumugi/plugin'
|
|
3
|
+
require 'tumugi/mixin/listable'
|
|
4
|
+
require 'tumugi/mixin/task_helper'
|
|
2
5
|
|
|
3
6
|
module Tumugi
|
|
4
7
|
class TaskDefinition
|
|
5
|
-
include Tumugi::
|
|
8
|
+
include Tumugi::Mixin::Listable
|
|
9
|
+
include Tumugi::Mixin::TaskHelper
|
|
6
10
|
|
|
7
11
|
def self.define(id, opts={}, &block)
|
|
8
12
|
td = Tumugi::TaskDefinition.new(id, opts)
|
|
9
|
-
td.instance_eval(&block)
|
|
13
|
+
td.instance_eval(&block) if block_given?
|
|
10
14
|
Tumugi.application.add_task(id, td)
|
|
11
15
|
td
|
|
12
16
|
end
|
|
@@ -16,6 +20,10 @@ module Tumugi
|
|
|
16
20
|
def initialize(id, opts={})
|
|
17
21
|
@id = id
|
|
18
22
|
@opts = { type: Tumugi::Task }.merge(opts)
|
|
23
|
+
|
|
24
|
+
unless @opts[:type].is_a?(Class)
|
|
25
|
+
@opts[:type] = Tumugi::Plugin.lookup_task(@opts[:type])
|
|
26
|
+
end
|
|
19
27
|
end
|
|
20
28
|
|
|
21
29
|
def instance
|
|
@@ -35,7 +43,7 @@ module Tumugi
|
|
|
35
43
|
end
|
|
36
44
|
|
|
37
45
|
def output_eval(task)
|
|
38
|
-
@out ||= @outputs.is_a?(Proc) ?
|
|
46
|
+
@out ||= @outputs.is_a?(Proc) ? task.instance_eval(&@outputs) : @outputs
|
|
39
47
|
end
|
|
40
48
|
|
|
41
49
|
def required_tasks
|
|
@@ -43,13 +51,14 @@ module Tumugi
|
|
|
43
51
|
end
|
|
44
52
|
|
|
45
53
|
def run_block(task)
|
|
46
|
-
|
|
54
|
+
task.instance_eval(&@run)
|
|
47
55
|
end
|
|
48
56
|
|
|
49
57
|
private
|
|
50
58
|
|
|
51
59
|
def create_task
|
|
52
60
|
task = define_task.new
|
|
61
|
+
raise "Invalid type: '#{@opts[:type]}'" unless task.is_a?(Tumugi::Task)
|
|
53
62
|
task.id = @id
|
|
54
63
|
task
|
|
55
64
|
end
|
data/lib/tumugi/version.rb
CHANGED
data/tumugi.gemspec
CHANGED
|
@@ -18,15 +18,17 @@ Gem::Specification.new do |spec|
|
|
|
18
18
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
|
19
19
|
spec.require_paths = ['lib']
|
|
20
20
|
|
|
21
|
-
spec.
|
|
22
|
-
|
|
23
|
-
spec.add_runtime_dependency 'thor', '~> 0.19.1'
|
|
21
|
+
spec.required_ruby_version = '>= 2.0'
|
|
22
|
+
|
|
24
23
|
spec.add_runtime_dependency 'parallel', '~> 1.8.0'
|
|
25
24
|
spec.add_runtime_dependency 'retriable', '~> 2.1'
|
|
25
|
+
spec.add_runtime_dependency 'ruby-graphviz', '~> 1.2.2'
|
|
26
|
+
spec.add_runtime_dependency 'thor', '~> 0.19.1'
|
|
26
27
|
|
|
27
28
|
spec.add_development_dependency 'bundler', '~> 1.11'
|
|
28
29
|
spec.add_development_dependency 'rake', '~> 10.0'
|
|
29
30
|
spec.add_development_dependency 'test-unit', '~> 3.1'
|
|
30
31
|
spec.add_development_dependency 'test-unit-rr'
|
|
31
32
|
spec.add_development_dependency 'coveralls'
|
|
33
|
+
spec.add_development_dependency 'github_changelog_generator'
|
|
32
34
|
end
|
metadata
CHANGED
|
@@ -1,85 +1,71 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: tumugi
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.2.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-05-02 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
|
-
name:
|
|
14
|
+
name: parallel
|
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
|
16
16
|
requirements:
|
|
17
17
|
- - "~>"
|
|
18
18
|
- !ruby/object:Gem::Version
|
|
19
|
-
version:
|
|
19
|
+
version: 1.8.0
|
|
20
20
|
type: :runtime
|
|
21
21
|
prerelease: false
|
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
|
23
23
|
requirements:
|
|
24
24
|
- - "~>"
|
|
25
25
|
- !ruby/object:Gem::Version
|
|
26
|
-
version:
|
|
26
|
+
version: 1.8.0
|
|
27
27
|
- !ruby/object:Gem::Dependency
|
|
28
|
-
name:
|
|
28
|
+
name: retriable
|
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
|
30
30
|
requirements:
|
|
31
31
|
- - "~>"
|
|
32
32
|
- !ruby/object:Gem::Version
|
|
33
|
-
version:
|
|
33
|
+
version: '2.1'
|
|
34
34
|
type: :runtime
|
|
35
35
|
prerelease: false
|
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
|
37
37
|
requirements:
|
|
38
38
|
- - "~>"
|
|
39
39
|
- !ruby/object:Gem::Version
|
|
40
|
-
version:
|
|
40
|
+
version: '2.1'
|
|
41
41
|
- !ruby/object:Gem::Dependency
|
|
42
|
-
name:
|
|
42
|
+
name: ruby-graphviz
|
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
|
44
44
|
requirements:
|
|
45
45
|
- - "~>"
|
|
46
46
|
- !ruby/object:Gem::Version
|
|
47
|
-
version:
|
|
47
|
+
version: 1.2.2
|
|
48
48
|
type: :runtime
|
|
49
49
|
prerelease: false
|
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
|
51
51
|
requirements:
|
|
52
52
|
- - "~>"
|
|
53
53
|
- !ruby/object:Gem::Version
|
|
54
|
-
version:
|
|
54
|
+
version: 1.2.2
|
|
55
55
|
- !ruby/object:Gem::Dependency
|
|
56
|
-
name:
|
|
57
|
-
requirement: !ruby/object:Gem::Requirement
|
|
58
|
-
requirements:
|
|
59
|
-
- - "~>"
|
|
60
|
-
- !ruby/object:Gem::Version
|
|
61
|
-
version: 1.8.0
|
|
62
|
-
type: :runtime
|
|
63
|
-
prerelease: false
|
|
64
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
65
|
-
requirements:
|
|
66
|
-
- - "~>"
|
|
67
|
-
- !ruby/object:Gem::Version
|
|
68
|
-
version: 1.8.0
|
|
69
|
-
- !ruby/object:Gem::Dependency
|
|
70
|
-
name: retriable
|
|
56
|
+
name: thor
|
|
71
57
|
requirement: !ruby/object:Gem::Requirement
|
|
72
58
|
requirements:
|
|
73
59
|
- - "~>"
|
|
74
60
|
- !ruby/object:Gem::Version
|
|
75
|
-
version:
|
|
61
|
+
version: 0.19.1
|
|
76
62
|
type: :runtime
|
|
77
63
|
prerelease: false
|
|
78
64
|
version_requirements: !ruby/object:Gem::Requirement
|
|
79
65
|
requirements:
|
|
80
66
|
- - "~>"
|
|
81
67
|
- !ruby/object:Gem::Version
|
|
82
|
-
version:
|
|
68
|
+
version: 0.19.1
|
|
83
69
|
- !ruby/object:Gem::Dependency
|
|
84
70
|
name: bundler
|
|
85
71
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -150,6 +136,20 @@ dependencies:
|
|
|
150
136
|
- - ">="
|
|
151
137
|
- !ruby/object:Gem::Version
|
|
152
138
|
version: '0'
|
|
139
|
+
- !ruby/object:Gem::Dependency
|
|
140
|
+
name: github_changelog_generator
|
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
|
142
|
+
requirements:
|
|
143
|
+
- - ">="
|
|
144
|
+
- !ruby/object:Gem::Version
|
|
145
|
+
version: '0'
|
|
146
|
+
type: :development
|
|
147
|
+
prerelease: false
|
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
149
|
+
requirements:
|
|
150
|
+
- - ">="
|
|
151
|
+
- !ruby/object:Gem::Version
|
|
152
|
+
version: '0'
|
|
153
153
|
description:
|
|
154
154
|
email:
|
|
155
155
|
- hakobera@gmail.com
|
|
@@ -160,6 +160,7 @@ extra_rdoc_files: []
|
|
|
160
160
|
files:
|
|
161
161
|
- ".gitignore"
|
|
162
162
|
- ".travis.yml"
|
|
163
|
+
- CHANGELOG.md
|
|
163
164
|
- Gemfile
|
|
164
165
|
- LICENSE
|
|
165
166
|
- README.md
|
|
@@ -174,19 +175,27 @@ files:
|
|
|
174
175
|
- exe/tumugi
|
|
175
176
|
- lib/tumugi.rb
|
|
176
177
|
- lib/tumugi/application.rb
|
|
178
|
+
- lib/tumugi/atomic_file.rb
|
|
177
179
|
- lib/tumugi/cli.rb
|
|
178
180
|
- lib/tumugi/command/run.rb
|
|
179
181
|
- lib/tumugi/command/show.rb
|
|
180
182
|
- lib/tumugi/config.rb
|
|
181
183
|
- lib/tumugi/dag.rb
|
|
182
184
|
- lib/tumugi/dsl.rb
|
|
183
|
-
- lib/tumugi/
|
|
185
|
+
- lib/tumugi/file_system.rb
|
|
186
|
+
- lib/tumugi/file_system_error.rb
|
|
184
187
|
- lib/tumugi/logger.rb
|
|
185
|
-
- lib/tumugi/
|
|
186
|
-
- lib/tumugi/
|
|
188
|
+
- lib/tumugi/mixin/listable.rb
|
|
189
|
+
- lib/tumugi/mixin/task_helper.rb
|
|
190
|
+
- lib/tumugi/plugin.rb
|
|
191
|
+
- lib/tumugi/plugin/atomic_local_file.rb
|
|
192
|
+
- lib/tumugi/plugin/file_system_target.rb
|
|
193
|
+
- lib/tumugi/plugin/local_file_system.rb
|
|
194
|
+
- lib/tumugi/plugin/target/local_file.rb
|
|
195
|
+
- lib/tumugi/registry.rb
|
|
196
|
+
- lib/tumugi/target.rb
|
|
187
197
|
- lib/tumugi/task.rb
|
|
188
198
|
- lib/tumugi/task_definition.rb
|
|
189
|
-
- lib/tumugi/tumugi_module.rb
|
|
190
199
|
- lib/tumugi/version.rb
|
|
191
200
|
- tumugi.gemspec
|
|
192
201
|
homepage: https://github.com/tumugi/tumugi
|
|
@@ -201,7 +210,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
201
210
|
requirements:
|
|
202
211
|
- - ">="
|
|
203
212
|
- !ruby/object:Gem::Version
|
|
204
|
-
version: '0'
|
|
213
|
+
version: '2.0'
|
|
205
214
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
206
215
|
requirements:
|
|
207
216
|
- - ">="
|
data/lib/tumugi/helper.rb
DELETED
data/lib/tumugi/target/base.rb
DELETED
data/lib/tumugi/tumugi_module.rb
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
require 'tumugi/application'
|
|
2
|
-
require 'tumugi/config'
|
|
3
|
-
require 'tumugi/logger'
|
|
4
|
-
|
|
5
|
-
module Tumugi
|
|
6
|
-
class << self
|
|
7
|
-
def application
|
|
8
|
-
@application ||= Tumugi::Application.new
|
|
9
|
-
end
|
|
10
|
-
|
|
11
|
-
def logger
|
|
12
|
-
@logger ||= Tumugi::Logger.new
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
def config
|
|
16
|
-
@config ||= Tumugi::Config.new
|
|
17
|
-
if block_given?
|
|
18
|
-
yield @config
|
|
19
|
-
end
|
|
20
|
-
@config
|
|
21
|
-
end
|
|
22
|
-
end
|
|
23
|
-
end
|