ratch 0.1 → 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- data/{LICENSE.txt → LICENSE} +0 -0
- data/README +37 -0
- data/bin/lt +54 -2
- data/bin/ludo +12 -2
- data/bin/ratch +48 -2
- data/data/{mint/ratch → ratch/rubyproject}/announce +0 -0
- data/data/ratch/rubyproject/extest +129 -0
- data/data/{mint/ratch → ratch/rubyproject}/install +0 -0
- data/data/ratch/rubyproject/install2 +63 -0
- data/data/ratch/rubyproject/install3 +74 -0
- data/data/ratch/rubyproject/load +39 -0
- data/data/{mint/ratch → ratch/rubyproject}/notes +0 -0
- data/data/ratch/rubyproject/publish +58 -0
- data/data/{mint/ratch → ratch/rubyproject}/rdoc +0 -0
- data/data/{mint/ratch → ratch/rubyproject}/setup +0 -0
- data/data/{mint/ratch → ratch/rubyproject}/stats +0 -0
- data/dev/install +89 -0
- data/dev/ludo +25 -0
- data/dev/oldtaskable.rb +573 -0
- data/dev/taskable.rb +75 -528
- data/lib/ratch/argvutils.rb +56 -0
- data/lib/ratch/batch.rb +7 -1
- data/lib/ratch/{runnable.rb → batchable.rb} +49 -27
- data/lib/ratch/buildable.rb +107 -0
- data/lib/ratch/options.rb +1 -1
- data/lib/ratch/taskable.rb +70 -60
- data/lib/ratch/taskutils.rb +2 -5
- data/meta/{manifest.txt → MANIFEST} +23 -20
- data/meta/{project.yaml → RATCH-0.2.1.roll} +4 -2
- metadata +26 -23
- data/README.txt +0 -10
- data/data/mint/ratch/publish +0 -44
- data/lib/ratch/cli/lt.rb +0 -56
- data/lib/ratch/cli/ludo.rb +0 -14
- data/lib/ratch/cli/ratch.rb +0 -47
- data/misc/original.rb +0 -308
@@ -0,0 +1,56 @@
|
|
1
|
+
|
2
|
+
module Ratch
|
3
|
+
|
4
|
+
# No fuss access to ARGV. This shows up as #argv in the ratch api.
|
5
|
+
#
|
6
|
+
# Ratch uses '=' for parameterized flags b/c this make parsing stupid simple
|
7
|
+
# and that's a good thing!!!
|
8
|
+
|
9
|
+
module ArgvUtils
|
10
|
+
|
11
|
+
def argv
|
12
|
+
@argv ||= (ARGV.dup).extend(Ext)
|
13
|
+
end
|
14
|
+
|
15
|
+
module Ext
|
16
|
+
|
17
|
+
def flags
|
18
|
+
@flags ||= collect{ |e| e =~ /^-/ && e !~ /=/ }
|
19
|
+
end
|
20
|
+
|
21
|
+
def arguments
|
22
|
+
@arguments ||= collect{ |e| e !~ /=/ }
|
23
|
+
end
|
24
|
+
|
25
|
+
def parameters
|
26
|
+
@parameters ||= (
|
27
|
+
pms = {}
|
28
|
+
collect{ |e| e =~ /=/ }.each do |e|
|
29
|
+
pms.store(*split('='))
|
30
|
+
end
|
31
|
+
pms
|
32
|
+
)
|
33
|
+
end
|
34
|
+
|
35
|
+
# Does ARGV include a specifc flag?
|
36
|
+
def flag?(flag)
|
37
|
+
include?(flag)
|
38
|
+
end
|
39
|
+
|
40
|
+
# You can use this if you want to use parameterized
|
41
|
+
# flags w/o the '=', however be aware that the
|
42
|
+
# parameter value will also be listed amoung the
|
43
|
+
# bare arguments list. For example:
|
44
|
+
#
|
45
|
+
# $ foo tom --say hello
|
46
|
+
#
|
47
|
+
# argv.value('--say') #=> "hello"
|
48
|
+
# argv.arguments #=> ["tom", "hello"]
|
49
|
+
#
|
50
|
+
def value(flag)
|
51
|
+
fetch(index(flag)+1)
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
data/lib/ratch/batch.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
#require 'shellwords'
|
2
2
|
require 'rbconfig' # replace with facets/rbsystem in future ?
|
3
3
|
require 'ratch/taskutils'
|
4
|
+
require 'ratch/batchable'
|
4
5
|
|
5
6
|
module Ratch
|
6
7
|
|
@@ -11,6 +12,9 @@ module Ratch
|
|
11
12
|
|
12
13
|
include TaskUtils
|
13
14
|
|
15
|
+
include Batchable
|
16
|
+
include OpenBatchable
|
17
|
+
|
14
18
|
# Quick start, equivalent to calling new.run(file).
|
15
19
|
|
16
20
|
#def self.start(file)
|
@@ -29,7 +33,9 @@ module Ratch
|
|
29
33
|
def call(arguments=nil)
|
30
34
|
script = File.read($0 = @file)
|
31
35
|
eval(script, binding, $0) #instance_eval(script)
|
32
|
-
|
36
|
+
#@main.call if @main
|
37
|
+
task_manager.call_main
|
38
|
+
#run(:main) if task_manager.main
|
33
39
|
end
|
34
40
|
|
35
41
|
end
|
@@ -1,43 +1,66 @@
|
|
1
1
|
module Ratch
|
2
2
|
|
3
|
-
|
3
|
+
class BatchManager
|
4
4
|
|
5
|
-
|
5
|
+
# Task cache, which prevents batch runs from re-executing.
|
6
|
+
attr :cache
|
6
7
|
|
7
|
-
#
|
8
|
+
# New BatchManager.
|
9
|
+
def initialize
|
10
|
+
@cache = {}
|
11
|
+
end
|
8
12
|
|
13
|
+
#
|
14
|
+
def batch(batchfile, arguments=nil)
|
15
|
+
@cache[batchfile] ||= run(batchfile, arguments)
|
16
|
+
end
|
17
|
+
|
18
|
+
# TODO How to handle arguments?
|
9
19
|
def run(batchfile, arguments=nil)
|
10
20
|
BatchFile.new(batchfile).call
|
11
|
-
# # TODO probably should raise error instead
|
12
|
-
# abort "missing batch file -- #{batchfile}" unless File.file?(batchfile)
|
13
|
-
# script = File.read($0 = batchfile)
|
14
|
-
# #instance_eval(script)
|
15
|
-
# eval(script, binding, $0)
|
21
|
+
# # TODO probably should raise error instead
|
22
|
+
# abort "missing batch file -- #{batchfile}" unless File.file?(batchfile)
|
23
|
+
# script = File.read($0 = batchfile)
|
24
|
+
# #instance_eval(script)
|
25
|
+
# eval(script, binding, $0)
|
26
|
+
end
|
27
|
+
|
28
|
+
#
|
29
|
+
def done?(batchfile)
|
30
|
+
batchfile == $0 or @cache.key?(batchfile)
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
#
|
36
|
+
|
37
|
+
module Batchable
|
38
|
+
|
39
|
+
# Reference batch manager.
|
40
|
+
def batch_manager
|
41
|
+
@batch_manager ||= BatchManager.new
|
16
42
|
end
|
17
43
|
|
18
44
|
# Batch run, ie. run and cache.
|
19
45
|
# Usually this can be take care of by method_missing.
|
20
46
|
# But, in some cases, built in method names block task
|
21
47
|
# calls, so you have to use #batch to invoke those.
|
22
|
-
|
23
48
|
def batch(batchfile, arguments=nil)
|
24
|
-
|
49
|
+
batch_manager.batch(batchfile, arguments=nil) # why did I have task instead of batchfile before?
|
25
50
|
end
|
26
51
|
|
27
|
-
#
|
28
|
-
|
29
|
-
|
30
|
-
@@task_cache ||= {}
|
52
|
+
# Lauch a batch file (non-cached)
|
53
|
+
def launch(batchfile, arguments=nil)
|
54
|
+
batch_manager.run(batchfile, arguments=nil)
|
31
55
|
end
|
32
56
|
|
33
|
-
# Is a
|
34
|
-
|
35
|
-
|
36
|
-
task == $0 or task_cache.key?(task)
|
57
|
+
# Is a batch run complete or in the process of being completed?
|
58
|
+
def done?(batchfile)
|
59
|
+
batch_manager.done?(batchfile)
|
37
60
|
end
|
38
61
|
|
39
62
|
# Shell runner.
|
40
|
-
|
63
|
+
# TODO Does this belong here?
|
41
64
|
def sh(cmd)
|
42
65
|
if noharm?
|
43
66
|
puts cmd
|
@@ -49,16 +72,15 @@ module Ratch
|
|
49
72
|
end
|
50
73
|
|
51
74
|
# Abort running.
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
end
|
75
|
+
#def abort(msg=nil)
|
76
|
+
# puts msg if msg
|
77
|
+
# exit 0
|
78
|
+
#end
|
57
79
|
|
58
80
|
end
|
59
81
|
|
60
82
|
#
|
61
|
-
module
|
83
|
+
module OpenBatchable
|
62
84
|
|
63
85
|
# If method is missing try to run an external task
|
64
86
|
# or binary by that name. If it is a binary, arguments
|
@@ -106,8 +128,8 @@ module Ratch
|
|
106
128
|
puts "--> #{cache ? '' : 'not-'}cached execution: #{cmd}" if trace?
|
107
129
|
res = run(task, args)
|
108
130
|
if cache
|
109
|
-
#@
|
110
|
-
|
131
|
+
#@batch_catch[task] ||= (system(cmd); true)
|
132
|
+
batch_catch[task] ||= res
|
111
133
|
end
|
112
134
|
end
|
113
135
|
|
@@ -0,0 +1,107 @@
|
|
1
|
+
module Ratch
|
2
|
+
|
3
|
+
# = Buildable mixin
|
4
|
+
#
|
5
|
+
module Buildable
|
6
|
+
|
7
|
+
# Reference task manager.
|
8
|
+
def build_manager
|
9
|
+
@build_manager ||= BuildManager.new
|
10
|
+
end
|
11
|
+
|
12
|
+
# Define a build target.
|
13
|
+
def file(name, &block)
|
14
|
+
name, deps, block = *parse_build_dependencies(name, &block)
|
15
|
+
@build_manager.define_file(name, *deps, &block)
|
16
|
+
end
|
17
|
+
|
18
|
+
# Build a file.
|
19
|
+
def build(file)
|
20
|
+
@build_manager.call(file)
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
#
|
26
|
+
def parse_build_dependencies
|
27
|
+
if Hash===name_deps
|
28
|
+
name = name_deps.keys[0]
|
29
|
+
deps = name_deps.values[0]
|
30
|
+
else
|
31
|
+
name = name_deps
|
32
|
+
deps = []
|
33
|
+
end
|
34
|
+
[name, *deps, &block]
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
# = BuildManager class
|
39
|
+
#
|
40
|
+
class BuildManager
|
41
|
+
attr :builds
|
42
|
+
|
43
|
+
def initialize
|
44
|
+
@builds = {}
|
45
|
+
end
|
46
|
+
|
47
|
+
def define_file(name, *depend, &block)
|
48
|
+
build = Build.new(name, *depend, &block)
|
49
|
+
builds[build.name] = task
|
50
|
+
end
|
51
|
+
|
52
|
+
#
|
53
|
+
def call(file)
|
54
|
+
plan.each{ |name| @@tasks[name].action_call }
|
55
|
+
#action_call
|
56
|
+
end
|
57
|
+
|
58
|
+
# TODO Check for circular dependencies.
|
59
|
+
def plan(list=[])
|
60
|
+
if list.include?(name)
|
61
|
+
raise "Circular dependency #{name}."
|
62
|
+
end
|
63
|
+
@preqs.each do |need|
|
64
|
+
need = need.to_s
|
65
|
+
next if list.include?(need)
|
66
|
+
@@tasks[need].plan(list)
|
67
|
+
end
|
68
|
+
list << name
|
69
|
+
return list
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
73
|
+
|
74
|
+
# = Build class
|
75
|
+
#
|
76
|
+
class Build
|
77
|
+
|
78
|
+
attr :name
|
79
|
+
attr :preqs
|
80
|
+
attr :action
|
81
|
+
|
82
|
+
#
|
83
|
+
def initialize(name, *preqs, &action)
|
84
|
+
@name = name.to_s
|
85
|
+
@preqs = preqs
|
86
|
+
@action = action
|
87
|
+
end
|
88
|
+
|
89
|
+
#
|
90
|
+
def call
|
91
|
+
files = Dir.glob(@name)
|
92
|
+
files.each do |name|
|
93
|
+
if File.exist?(name)
|
94
|
+
mtime = File.mtime(name)
|
95
|
+
needs = @preqs.find do |file|
|
96
|
+
!File.exist?(file) || File.mtime(file) > mtime
|
97
|
+
end
|
98
|
+
else
|
99
|
+
needs = true
|
100
|
+
end
|
101
|
+
@action.call(@name) if needs
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
data/lib/ratch/options.rb
CHANGED
data/lib/ratch/taskable.rb
CHANGED
@@ -1,105 +1,115 @@
|
|
1
1
|
module Ratch
|
2
2
|
|
3
|
+
# = Taskable Mixin
|
4
|
+
#
|
3
5
|
module Taskable
|
4
6
|
|
5
|
-
#
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
def tasks
|
10
|
-
@tasks ||= {}
|
7
|
+
# Reference task manager.
|
8
|
+
def task_manager
|
9
|
+
@task_manager ||= TaskManager.new
|
11
10
|
end
|
12
11
|
|
13
12
|
# Define a main task.
|
14
|
-
|
15
13
|
def main(name, &block)
|
16
|
-
|
17
|
-
|
14
|
+
name, deps, block = *parse_task_dependencies(name, &block)
|
15
|
+
task_manager.define_main(name, *deps, &block)
|
18
16
|
end
|
19
17
|
|
20
18
|
# Define a task.
|
21
|
-
|
22
19
|
def task(name, &block)
|
23
|
-
|
24
|
-
|
20
|
+
name, deps, block = *parse_task_dependencies(name, &block)
|
21
|
+
task_manager.define_task(name, *deps, &block)
|
25
22
|
end
|
26
23
|
|
27
|
-
#
|
28
|
-
|
29
|
-
|
30
|
-
tasks[name.to_s] = FileTask.register(name, &block)
|
24
|
+
# Run a task.
|
25
|
+
def run(name)
|
26
|
+
task_manager.call(name)
|
31
27
|
end
|
32
28
|
|
29
|
+
private
|
30
|
+
|
31
|
+
#
|
32
|
+
def parse_task_dependencies(name_deps, &block)
|
33
|
+
if Hash===name_deps
|
34
|
+
name = name_deps.keys[0]
|
35
|
+
deps = name_deps.values[0]
|
36
|
+
else
|
37
|
+
name = name_deps
|
38
|
+
deps = []
|
39
|
+
end
|
40
|
+
[name, deps, block]
|
41
|
+
end
|
33
42
|
end
|
34
43
|
|
44
|
+
# = TaskManager Class
|
35
45
|
#
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
class Task
|
46
|
+
class TaskManager
|
47
|
+
attr :main
|
48
|
+
attr :tasks
|
40
49
|
|
41
|
-
def
|
42
|
-
|
50
|
+
def initialize
|
51
|
+
@main = nil
|
52
|
+
@tasks = {}
|
43
53
|
end
|
44
54
|
|
45
|
-
def
|
46
|
-
|
47
|
-
|
48
|
-
deps = name_deps.values[0]
|
49
|
-
else
|
50
|
-
name = name_deps
|
51
|
-
deps = []
|
52
|
-
end
|
53
|
-
tasks[name.to_s] = new(name, *deps, &block)
|
55
|
+
def define_main(name=nil, *depend, &block)
|
56
|
+
@main = Task.new(name, *depend, &block)
|
57
|
+
tasks[@main.name] = @main
|
54
58
|
end
|
55
59
|
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
#
|
61
|
-
|
62
|
-
def initialize(name, *preqs, &action)
|
63
|
-
@name = name.to_s
|
64
|
-
@preqs = preqs
|
65
|
-
@action = action
|
60
|
+
def define_task(name, *depend, &block)
|
61
|
+
task = Task.new(name, *depend, &block)
|
62
|
+
tasks[task.name] = task
|
66
63
|
end
|
67
64
|
|
68
|
-
def
|
69
|
-
|
70
|
-
|
71
|
-
#action_call
|
65
|
+
def call_main
|
66
|
+
return unless @main
|
67
|
+
call(@main.name)
|
72
68
|
end
|
73
69
|
|
74
|
-
#
|
75
|
-
|
76
|
-
|
77
|
-
|
70
|
+
# Call task.
|
71
|
+
def call(name)
|
72
|
+
plan(name).each{ |name| @tasks[name].call }
|
73
|
+
#action_call
|
78
74
|
end
|
79
75
|
|
80
|
-
#
|
81
|
-
|
82
|
-
def plan(list=[])
|
76
|
+
# Prepare plan, checking for circular dependencies.
|
77
|
+
def plan(name, list=[])
|
83
78
|
if list.include?(name)
|
84
79
|
raise "Circular dependency #{name}."
|
85
80
|
end
|
86
|
-
|
87
|
-
|
81
|
+
task = @tasks[name]
|
82
|
+
task.preqs.each do |need|
|
88
83
|
need = need.to_s
|
89
84
|
next if list.include?(need)
|
90
|
-
|
85
|
+
@tasks[need].plan(need, list)
|
91
86
|
end
|
92
|
-
list << name
|
87
|
+
list << task.name
|
93
88
|
return list
|
94
89
|
end
|
95
90
|
|
96
91
|
end
|
97
92
|
|
93
|
+
# = Task class
|
98
94
|
#
|
99
|
-
|
100
|
-
|
95
|
+
class Task
|
96
|
+
|
97
|
+
attr :name
|
98
|
+
attr :preqs
|
99
|
+
attr :action
|
100
|
+
|
101
|
+
#
|
102
|
+
def initialize(name, *preqs, &action)
|
103
|
+
@name = name.to_s
|
104
|
+
@preqs = preqs
|
105
|
+
@action = action
|
106
|
+
end
|
107
|
+
|
108
|
+
#
|
109
|
+
def call
|
110
|
+
@action.call if @action
|
111
|
+
end
|
101
112
|
|
102
|
-
class FileTask < Task
|
103
113
|
end
|
104
114
|
|
105
|
-
end
|
115
|
+
end #module Ratch
|