ratch 0.1 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|