ratch 1.1.0 → 1.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.
- data/.ruby +99 -0
- data/COPYING +203 -21
- data/History.rdoc +35 -0
- data/License.txt +204 -0
- data/README.rdoc +113 -0
- data/Version +1 -0
- data/bin/ludo +16 -0
- data/bin/ratch +1 -8
- data/lib/ratch.rb +28 -0
- data/lib/ratch.yml +99 -0
- data/lib/ratch/batch.rb +500 -0
- data/lib/ratch/console.rb +199 -0
- data/lib/ratch/core_ext.rb +1 -4
- data/lib/ratch/core_ext/facets.rb +15 -1
- data/lib/ratch/core_ext/filetest.rb +29 -0
- data/lib/ratch/core_ext/{string.rb → to_actual_filename.rb} +0 -23
- data/lib/ratch/core_ext/to_console.rb +30 -12
- data/lib/ratch/core_ext/{object.rb → to_yamlfrag.rb} +1 -0
- data/lib/ratch/core_ext/unfold_paragraphs.rb +27 -0
- data/lib/ratch/file_list.rb +411 -0
- data/lib/ratch/script.rb +99 -5
- data/lib/ratch/script/help.rb +84 -0
- data/lib/ratch/shell.rb +783 -0
- data/lib/ratch/system.rb +15 -0
- data/lib/ratch/utils/cli.rb +49 -0
- data/lib/ratch/utils/config.rb +52 -0
- data/lib/ratch/{emailer.rb → utils/email.rb} +43 -6
- data/lib/ratch/utils/ftp.rb +134 -0
- data/lib/ratch/utils/pom.rb +22 -0
- data/lib/ratch/utils/rdoc.rb +48 -0
- data/lib/ratch/utils/tar.rb +88 -0
- data/lib/ratch/utils/xdg.rb +39 -0
- data/lib/ratch/utils/zlib.rb +54 -0
- data/spec/01_shell.rdoc +198 -0
- data/spec/02_script.rdoc +34 -0
- data/spec/03_batch.rdoc +71 -0
- data/spec/04_system.rdoc +3 -0
- data/spec/applique/array.rb +8 -0
- data/spec/applique/setup.rb +20 -0
- data/test/case_batch.rb +63 -0
- data/test/case_shell.rb +46 -0
- data/test/core_ext/case_pathname.rb +361 -0
- data/test/helper.rb +4 -0
- data/test/utils/case_cli.rb +6 -0
- data/test/utils/case_config.rb +12 -0
- data/test/utils/case_email.rb +10 -0
- data/test/utils/case_ftp.rb +6 -0
- data/test/utils/case_pom.rb +17 -0
- data/test/utils/case_rdoc.rb +23 -0
- data/test/utils/case_tar.rb +6 -0
- data/test/utils/case_zlib.rb +11 -0
- data/test/utils/fixtures/pom_sample/Profile +4 -0
- data/test/utils/fixtures/rdoc_sample/README.rdoc +4 -0
- data/test/utils/fixtures/rdoc_sample/lib/rdoc_sample/rdoc_sample.rb +9 -0
- metadata +139 -82
- data/HISTORY +0 -6
- data/MANIFEST +0 -53
- data/NEWS +0 -12
- data/README +0 -87
- data/VERSION +0 -1
- data/demo/tryme-task.ratch +0 -12
- data/demo/tryme1.ratch +0 -6
- data/doc/log/basic_stats/index.html +0 -39
- data/doc/log/notes.xml +0 -18
- data/doc/log/stats.log +0 -14
- data/doc/log/syntax.log +0 -0
- data/doc/log/testunit.log +0 -156
- data/lib/ratch/commandline.rb +0 -16
- data/lib/ratch/core_ext/pathname.rb +0 -38
- data/lib/ratch/dsl.rb +0 -420
- data/lib/ratch/index.rb +0 -4
- data/lib/ratch/io.rb +0 -116
- data/lib/ratch/plugin.rb +0 -65
- data/lib/ratch/service.rb +0 -33
- data/lib/ratch/task.rb +0 -249
- data/lib/ratch/task2.rb +0 -298
- data/meta/abstract +0 -4
- data/meta/author +0 -1
- data/meta/contact +0 -1
- data/meta/homepage +0 -1
- data/meta/name +0 -1
- data/meta/requires +0 -4
- data/meta/summary +0 -1
- data/test/README +0 -1
- data/test/test_helper.rb +0 -4
- data/test/test_task.rb +0 -46
data/lib/ratch/index.rb
DELETED
data/lib/ratch/io.rb
DELETED
@@ -1,116 +0,0 @@
|
|
1
|
-
require 'clio/consoleutils'
|
2
|
-
require 'clio/ansicode'
|
3
|
-
|
4
|
-
module Ratch
|
5
|
-
|
6
|
-
# = Ratch IO
|
7
|
-
#
|
8
|
-
# The IO class is used to cleanly separate out the
|
9
|
-
# basic input/output "dialog" between user and script.
|
10
|
-
#
|
11
|
-
class IO
|
12
|
-
|
13
|
-
#
|
14
|
-
attr :commandline
|
15
|
-
|
16
|
-
#
|
17
|
-
def initialize(commandline)
|
18
|
-
@commandline = commandline
|
19
|
-
end
|
20
|
-
|
21
|
-
def force? ; commandline.force? ; end
|
22
|
-
def quiet? ; commandline.quiet? ; end
|
23
|
-
def trace? ; commandline.trace? ; end
|
24
|
-
def debug? ; commandline.debug? ; end
|
25
|
-
def pretend? ; commandline.pretend? ; end
|
26
|
-
|
27
|
-
# Internal status report.
|
28
|
-
#
|
29
|
-
# Only output if dryrun or trace mode.
|
30
|
-
#
|
31
|
-
def status(message)
|
32
|
-
if pretend? or trace?
|
33
|
-
puts message
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
# Convenient method to get simple console reply.
|
38
|
-
#
|
39
|
-
def ask(question, answers=nil)
|
40
|
-
print "#{question}"
|
41
|
-
print " [#{answers}] " if answers
|
42
|
-
until inp = $stdin.gets ; sleep 1 ; end
|
43
|
-
inp.strip
|
44
|
-
end
|
45
|
-
|
46
|
-
# Ask for a password. (FIXME: only for unix so far)
|
47
|
-
#
|
48
|
-
def password(prompt=nil)
|
49
|
-
msg ||= "Enter Password: "
|
50
|
-
inp = ''
|
51
|
-
print "#{prompt} "
|
52
|
-
begin
|
53
|
-
#system "stty -echo"
|
54
|
-
#inp = gets.chomp
|
55
|
-
until inp = $stdin.gets
|
56
|
-
sleep 1
|
57
|
-
end
|
58
|
-
ensure
|
59
|
-
#system "stty echo"
|
60
|
-
end
|
61
|
-
return inp.chomp
|
62
|
-
end
|
63
|
-
|
64
|
-
def print(str)
|
65
|
-
super(str) unless quiet?
|
66
|
-
end
|
67
|
-
|
68
|
-
def puts(str)
|
69
|
-
super(str) unless quiet?
|
70
|
-
end
|
71
|
-
|
72
|
-
#
|
73
|
-
#
|
74
|
-
def printline(left, right='', options={})
|
75
|
-
return if quiet?
|
76
|
-
|
77
|
-
separator = options[:seperator] || options[:sep] || ' '
|
78
|
-
padding = options[:padding] || options[:pad] || 0
|
79
|
-
|
80
|
-
left, right = left.to_s, right.to_s
|
81
|
-
|
82
|
-
left_size = left.size
|
83
|
-
right_size = right.size
|
84
|
-
|
85
|
-
left = colorize(left)
|
86
|
-
right = colorize(right)
|
87
|
-
|
88
|
-
l = padding
|
89
|
-
r = -(right_size + padding + 1)
|
90
|
-
|
91
|
-
line = separator * screen_width
|
92
|
-
line[l, left_size] = left if left_size != 0
|
93
|
-
line[r, right_size] = right if right_size != 0
|
94
|
-
|
95
|
-
puts line
|
96
|
-
end
|
97
|
-
|
98
|
-
#
|
99
|
-
def colorize(text)
|
100
|
-
return text unless text.color
|
101
|
-
if PLATFORM =~ /win/
|
102
|
-
text.to_s
|
103
|
-
else
|
104
|
-
Clio::ANSICode.send(text.color){ text.to_s }
|
105
|
-
end
|
106
|
-
end
|
107
|
-
|
108
|
-
#
|
109
|
-
def screen_width
|
110
|
-
Clio::ConsoleUtils.screen_width
|
111
|
-
end
|
112
|
-
|
113
|
-
end
|
114
|
-
|
115
|
-
end
|
116
|
-
|
data/lib/ratch/plugin.rb
DELETED
@@ -1,65 +0,0 @@
|
|
1
|
-
module Ratch
|
2
|
-
|
3
|
-
# = Plugin
|
4
|
-
#
|
5
|
-
# A Plugin is essentially a delegated Service class..
|
6
|
-
#
|
7
|
-
# The plugin acts a base class for ecapsulating batch routines.
|
8
|
-
# This helps to keep the main batch context free of the clutter
|
9
|
-
# of private supporting methods.
|
10
|
-
#
|
11
|
-
# Plugins are tightly coupled to the batch context,
|
12
|
-
# which allows them to call on the context easily.
|
13
|
-
# However this means plugins cannot be used independent
|
14
|
-
# of a batch context, and changes in the batch context
|
15
|
-
# can cause effects in plugin behvior that can be harder
|
16
|
-
# to track down and fix if a bug arises.
|
17
|
-
#
|
18
|
-
# Unless the tight coupling of a plugin is required, use the
|
19
|
-
# loose coupling of a Service class instead.
|
20
|
-
#
|
21
|
-
# The context must be a subclass of Ratch::DSL.
|
22
|
-
#
|
23
|
-
class Plugin
|
24
|
-
|
25
|
-
# The batch context.
|
26
|
-
attr :context
|
27
|
-
|
28
|
-
private
|
29
|
-
|
30
|
-
# Sets the context and assigns options to setter attributes
|
31
|
-
# if they exist and values are not nil. That last point is
|
32
|
-
# important. You must use 'false' to purposely negate an option.
|
33
|
-
# +nil+ will instead allow any default setting to be used.
|
34
|
-
def initialize(context, options=nil)
|
35
|
-
@context = context
|
36
|
-
|
37
|
-
raise TypeError, "context must be a subclass of Ratch::DSL" unless context.is_a?(Ratch::DSL)
|
38
|
-
|
39
|
-
initialize_defaults
|
40
|
-
|
41
|
-
options ||= {}
|
42
|
-
options.each do |k, v|
|
43
|
-
send("#{k}=", v) if respond_to?("#{k}=") && !v.nil?
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
# When subclassing, put default instance variable settngs here.
|
48
|
-
# Eg.
|
49
|
-
#
|
50
|
-
# def initialize_defaults
|
51
|
-
# @gravy = true
|
52
|
-
# end
|
53
|
-
#
|
54
|
-
def initialize_defaults
|
55
|
-
end
|
56
|
-
|
57
|
-
# TODO: Allow this to be optional? How?
|
58
|
-
def method_missing(s, *a, &b)
|
59
|
-
@context.send(s, *a, &b)
|
60
|
-
end
|
61
|
-
|
62
|
-
end
|
63
|
-
|
64
|
-
end
|
65
|
-
|
data/lib/ratch/service.rb
DELETED
@@ -1,33 +0,0 @@
|
|
1
|
-
require 'ratch/dsl'
|
2
|
-
|
3
|
-
module Ratch
|
4
|
-
|
5
|
-
# = Service
|
6
|
-
#
|
7
|
-
# In particular this means creating module for RunModes and FileUtils
|
8
|
-
# which uses it, as these are the primary couplings between the batch
|
9
|
-
# context and the services that are shared by all.
|
10
|
-
|
11
|
-
class Service < DSL
|
12
|
-
|
13
|
-
private
|
14
|
-
|
15
|
-
#
|
16
|
-
def initialize(options=nil)
|
17
|
-
options ||= {}
|
18
|
-
|
19
|
-
initialize_defaults
|
20
|
-
|
21
|
-
options.each do |k, v|
|
22
|
-
send("#{k}=", v) if respond_to?("#{k}=")
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
#
|
27
|
-
def initialize_defaults
|
28
|
-
end
|
29
|
-
|
30
|
-
end
|
31
|
-
|
32
|
-
end
|
33
|
-
|
data/lib/ratch/task.rb
DELETED
@@ -1,249 +0,0 @@
|
|
1
|
-
|
2
|
-
module Taskable
|
3
|
-
|
4
|
-
def self.included(base)
|
5
|
-
base.extend(Dsl)
|
6
|
-
end
|
7
|
-
|
8
|
-
# Run a task. Better name?
|
9
|
-
def run(target)
|
10
|
-
#t = self.class.tasks(target)
|
11
|
-
#t.run(self)
|
12
|
-
send("#{target}:target")
|
13
|
-
end
|
14
|
-
|
15
|
-
module Dsl
|
16
|
-
# Without an argument, returns list of tasks defined for this class.
|
17
|
-
#
|
18
|
-
# If a task's target name is given, will return the first
|
19
|
-
# task mathing the name found in the class' inheritance chain.
|
20
|
-
# This is important ot ensure task are inherited in the same manner
|
21
|
-
# that methods are.
|
22
|
-
def tasks(target=nil)
|
23
|
-
if target
|
24
|
-
target = target.to_sym
|
25
|
-
anc = ancestors.select{|a| a < Taskable}
|
26
|
-
t = nil; anc.find{|a| t = a.tasks[target]}
|
27
|
-
return t
|
28
|
-
else
|
29
|
-
@tasks ||= {}
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
# Set a description to be used by then next defined task in this class.
|
34
|
-
def desc(description)
|
35
|
-
@desc = description
|
36
|
-
end
|
37
|
-
|
38
|
-
# Define a task.
|
39
|
-
def task(target_and_requisite, &function)
|
40
|
-
target, requisite, function = *Task.parse_arguments(target_and_requisite, &function)
|
41
|
-
task = tasks[target.to_sym] ||= (
|
42
|
-
tdesc = @desc
|
43
|
-
@desc = nil
|
44
|
-
Task.new(self, target, tdesc) #, reqs, actions)
|
45
|
-
)
|
46
|
-
task.update(requisite, &function)
|
47
|
-
define_method("#{target}:target"){ task.run(self) } # or use #run?
|
48
|
-
define_method("#{target}:task", &function) # TODO: in 1.9 use instance_exec instead.
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
# = Task Class
|
53
|
-
#
|
54
|
-
class Task
|
55
|
-
attr :base
|
56
|
-
attr :target
|
57
|
-
attr :requisite
|
58
|
-
attr :function
|
59
|
-
attr :description
|
60
|
-
|
61
|
-
def initialize(base, target, description=nil, requisite=nil, &function)
|
62
|
-
@base = base
|
63
|
-
@target = target.to_sym
|
64
|
-
@description = description
|
65
|
-
@requisite = requisite || []
|
66
|
-
@function = function
|
67
|
-
end
|
68
|
-
|
69
|
-
#
|
70
|
-
def update(requisite, &function)
|
71
|
-
@requisite.concat(requisite).uniq!
|
72
|
-
@function = function if function
|
73
|
-
end
|
74
|
-
|
75
|
-
#
|
76
|
-
def prerequisite
|
77
|
-
base.ancestors.select{|a| a < Taskable}.collect{ |a|
|
78
|
-
a.tasks[target].requisite
|
79
|
-
}.flatten.uniq
|
80
|
-
end
|
81
|
-
|
82
|
-
# invoke target
|
83
|
-
def run(object)
|
84
|
-
rd = rule_dag
|
85
|
-
rd.each do |t|
|
86
|
-
object.send("#{t}:task")
|
87
|
-
end
|
88
|
-
end
|
89
|
-
|
90
|
-
#
|
91
|
-
#def call(object)
|
92
|
-
# object.instance_eval(&function)
|
93
|
-
#end
|
94
|
-
|
95
|
-
# Collect task dependencies for running.
|
96
|
-
def rule_dag(cache=[])
|
97
|
-
prerequisite.each do |r|
|
98
|
-
next if cache.include?(r)
|
99
|
-
t = base.tasks[r]
|
100
|
-
t.rule_dag(cache)
|
101
|
-
#cache << dep
|
102
|
-
end
|
103
|
-
cache << target.to_s
|
104
|
-
cache
|
105
|
-
end
|
106
|
-
|
107
|
-
#
|
108
|
-
def self.parse_arguments(name_and_reqs, &action)
|
109
|
-
if Hash===name_and_reqs
|
110
|
-
target = name_and_reqs.keys.first.to_s
|
111
|
-
reqs = [name_and_reqs.values.first].flatten
|
112
|
-
else
|
113
|
-
target = name_and_reqs.to_s
|
114
|
-
reqs = []
|
115
|
-
end
|
116
|
-
return target, reqs, action
|
117
|
-
end
|
118
|
-
end
|
119
|
-
|
120
|
-
# = File Task Class
|
121
|
-
#
|
122
|
-
class FileTask < Task
|
123
|
-
|
124
|
-
def needed?
|
125
|
-
if prerequisite.empty?
|
126
|
-
dated = true
|
127
|
-
elsif File.exist?(target)
|
128
|
-
mtime = File.mtime(target)
|
129
|
-
dated = prerequisite.find do |file|
|
130
|
-
!File.exist?(file) || File.mtime(file) > mtime
|
131
|
-
end
|
132
|
-
else
|
133
|
-
dated = true
|
134
|
-
end
|
135
|
-
return dated
|
136
|
-
end
|
137
|
-
|
138
|
-
#
|
139
|
-
def call(object)
|
140
|
-
object.instance_eval(&function) if needed?
|
141
|
-
end
|
142
|
-
end
|
143
|
-
|
144
|
-
end
|
145
|
-
|
146
|
-
|
147
|
-
=begin
|
148
|
-
# turn yaml file into tasks
|
149
|
-
def parse(file)
|
150
|
-
script = YAML.load(File.new(file.to_s))
|
151
|
-
|
152
|
-
imports = script.delete('import') || []
|
153
|
-
#plugins = script.delete('plugin') || []
|
154
|
-
srvs = script.delete('services') || {}
|
155
|
-
tgts = script.delete('targets') || {}
|
156
|
-
|
157
|
-
imports.each do |import|
|
158
|
-
path = Reap::Domain::LIB_DIRECTORY + 'systems' + (import + '.reap').to_s
|
159
|
-
parse(path)
|
160
|
-
end
|
161
|
-
|
162
|
-
srvs.each do |label, options|
|
163
|
-
type = options.delete('type')
|
164
|
-
@services[label] = domain.send("#{type}_service") # FIXME
|
165
|
-
end
|
166
|
-
|
167
|
-
tgts.each do |target, options|
|
168
|
-
@targets[target] = Task.new(self, target, options)
|
169
|
-
end
|
170
|
-
end
|
171
|
-
=end
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
=begin
|
179
|
-
# Collect task dependencies for running.
|
180
|
-
def self.rule_dag(target, cache=[])
|
181
|
-
t = tasks[target.to_sym]
|
182
|
-
d = t.prerequisite
|
183
|
-
d.each do |r|
|
184
|
-
next if cache.include?(r)
|
185
|
-
rule_dag(r, cache)
|
186
|
-
#cache << dep
|
187
|
-
end
|
188
|
-
|
189
|
-
# file requirements
|
190
|
-
#q = self.class.ann(name, :reqs) || []
|
191
|
-
#q.each do |req|
|
192
|
-
# path = Pathname.new(req)
|
193
|
-
# next if r.include?(path)
|
194
|
-
# mat = annotations.select{ |n, a| File.fnmatch?(a[:file].first, req) if a[:file] }.compact
|
195
|
-
# mat.each do |n, a|
|
196
|
-
# rule_dag(n, r)
|
197
|
-
# end
|
198
|
-
# r << path
|
199
|
-
#end
|
200
|
-
|
201
|
-
cache << target.to_s
|
202
|
-
return cache
|
203
|
-
end
|
204
|
-
|
205
|
-
# invoke target
|
206
|
-
def run(target)
|
207
|
-
target = target.to_sym
|
208
|
-
rd = self.class.rule_dag(target)
|
209
|
-
rd.each do |t|
|
210
|
-
send("#{t}:task")
|
211
|
-
end
|
212
|
-
end
|
213
|
-
=end
|
214
|
-
|
215
|
-
=begin
|
216
|
-
if target == name.to_s
|
217
|
-
tasks[target].call
|
218
|
-
else
|
219
|
-
case action
|
220
|
-
when Pathname
|
221
|
-
raise unless action.exist?
|
222
|
-
else
|
223
|
-
run_rec(action)
|
224
|
-
end
|
225
|
-
end
|
226
|
-
end
|
227
|
-
end
|
228
|
-
|
229
|
-
def run_rec(action)
|
230
|
-
# creates a file?
|
231
|
-
dated = true
|
232
|
-
if creates = self.class.ann(action, :file)
|
233
|
-
if self.class.ann(name, :reqs).empty?
|
234
|
-
dated = true
|
235
|
-
elsif File.exist?(creates)
|
236
|
-
mtime = File.mtime(creates)
|
237
|
-
dated = self.class.ann(name, :reqs).find do |file|
|
238
|
-
!File.exist?(file) || File.mtime(file) > mtime
|
239
|
-
end
|
240
|
-
else
|
241
|
-
dated = true
|
242
|
-
end
|
243
|
-
end
|
244
|
-
return unless dated
|
245
|
-
send(action)
|
246
|
-
end
|
247
|
-
=end
|
248
|
-
|
249
|
-
|