rap 0.13.1 → 0.14.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/History +8 -1
- data/README +1 -1
- data/bin/rap +2 -1
- data/lib/rap.rb +7 -0
- data/lib/rap/declarations.rb +1 -4
- data/lib/rap/task.rb +133 -33
- data/lib/rap/utils.rb +50 -1
- metadata +4 -4
data/History
CHANGED
data/README
CHANGED
@@ -43,7 +43,7 @@ Now from the command line:
|
|
43
43
|
--------------------------------------------------------------------------------
|
44
44
|
Says goodnight with a configurable message.
|
45
45
|
--------------------------------------------------------------------------------
|
46
|
-
usage:
|
46
|
+
usage: tap run -- goodnight OBJ
|
47
47
|
|
48
48
|
configurations:
|
49
49
|
--message MESSAGE
|
data/bin/rap
CHANGED
@@ -24,6 +24,7 @@ end
|
|
24
24
|
|
25
25
|
Dir.glob('[TtRr]apfile{,.rb}').each do |rapfile|
|
26
26
|
next unless File.file?(rapfile)
|
27
|
+
env.scan(rapfile, "task|join|middleware")
|
27
28
|
load rapfile
|
28
29
|
end
|
29
30
|
|
@@ -52,7 +53,7 @@ when '--help', nil, '-T'
|
|
52
53
|
end
|
53
54
|
|
54
55
|
puts
|
55
|
-
puts "version #{
|
56
|
+
puts "version #{Rap::VERSION} -- #{Rap::WEBSITE}"
|
56
57
|
else
|
57
58
|
begin
|
58
59
|
schema = Tap::Schema.parse(ARGV)
|
data/lib/rap.rb
CHANGED
data/lib/rap/declarations.rb
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
require 'rap/task'
|
2
|
-
require 'rap/utils'
|
3
2
|
|
4
3
|
module Rap
|
5
4
|
|
@@ -51,8 +50,6 @@ module Rap
|
|
51
50
|
# See the {Syntax Reference}[link:files/doc/Syntax%20Reference.html] for more
|
52
51
|
# information.
|
53
52
|
module Declarations
|
54
|
-
include Utils
|
55
|
-
|
56
53
|
# The environment in which declared task classes are registered.
|
57
54
|
# By default a Tap::Env for Dir.pwd.
|
58
55
|
def Declarations.env() @@env ||= Tap::Env.new; end
|
@@ -238,7 +235,7 @@ module Rap
|
|
238
235
|
alias desc original_desc
|
239
236
|
|
240
237
|
# hide remaining Declarations methods (including Utils methods)
|
241
|
-
private :namespace
|
238
|
+
private :namespace
|
242
239
|
# :startdoc:
|
243
240
|
|
244
241
|
private
|
data/lib/rap/task.rb
CHANGED
@@ -35,6 +35,24 @@ module Rap
|
|
35
35
|
class Task < Tap::Task
|
36
36
|
class << self
|
37
37
|
|
38
|
+
# Returns class dependencies
|
39
|
+
attr_reader :dependencies
|
40
|
+
|
41
|
+
# Returns or initializes the instance of self cached with app.
|
42
|
+
def instance(app=Tap::App.instance, auto_initialize=true)
|
43
|
+
app.cache[self] ||= (auto_initialize ? new({}, app) : nil)
|
44
|
+
end
|
45
|
+
|
46
|
+
def inherited(child) # :nodoc:
|
47
|
+
unless child.instance_variable_defined?(:@source_file)
|
48
|
+
caller[0] =~ Lazydoc::CALLER_REGEXP
|
49
|
+
child.instance_variable_set(:@source_file, File.expand_path($1))
|
50
|
+
end
|
51
|
+
|
52
|
+
child.instance_variable_set(:@dependencies, dependencies.dup)
|
53
|
+
super
|
54
|
+
end
|
55
|
+
|
38
56
|
# Sets actions.
|
39
57
|
attr_writer :actions
|
40
58
|
|
@@ -73,7 +91,12 @@ module Rap
|
|
73
91
|
#
|
74
92
|
def parse!(argv=ARGV, app=Tap::App.instance)
|
75
93
|
instance = super
|
76
|
-
|
94
|
+
|
95
|
+
# store args on instance and clear so that instance
|
96
|
+
# will not be enqued with any inputs
|
97
|
+
instance.args = argv.dup
|
98
|
+
argv.clear
|
99
|
+
|
77
100
|
instance
|
78
101
|
end
|
79
102
|
|
@@ -135,62 +158,115 @@ module Rap
|
|
135
158
|
|
136
159
|
subclass
|
137
160
|
end
|
161
|
+
|
162
|
+
# Sets a class-level dependency; when task class B depends_on another
|
163
|
+
# task class A, instances of B are initialized to depend on a shared
|
164
|
+
# instance of A. The shared instance is specific to an app and can
|
165
|
+
# be accessed through instance(app).
|
166
|
+
#
|
167
|
+
# If a non-nil name is specified, depends_on will create a reader of
|
168
|
+
# the dependency instance.
|
169
|
+
#
|
170
|
+
# class A < Rap::Task
|
171
|
+
# end
|
172
|
+
#
|
173
|
+
# class B < Rap::Task
|
174
|
+
# depends_on :a, A
|
175
|
+
# end
|
176
|
+
#
|
177
|
+
# app = Tap::App.new
|
178
|
+
# b = B.new({}, app)
|
179
|
+
# b.dependencies # => [A.instance(app)]
|
180
|
+
# b.a # => A.instance(app)
|
181
|
+
#
|
182
|
+
# Returns self.
|
183
|
+
def depends_on(name, dependency_class)
|
184
|
+
unless dependency_class.ancestors.include?(Rap::Task)
|
185
|
+
raise "not a Rap::Task: #{dependency_class}"
|
186
|
+
end
|
187
|
+
|
188
|
+
unless dependencies.include?(dependency_class)
|
189
|
+
dependencies << dependency_class
|
190
|
+
end
|
191
|
+
|
192
|
+
if name
|
193
|
+
# returns the resolved result of the dependency
|
194
|
+
define_method(name) do
|
195
|
+
dependency_class.instance(app)
|
196
|
+
end
|
197
|
+
|
198
|
+
public(name)
|
199
|
+
end
|
200
|
+
|
201
|
+
self
|
202
|
+
end
|
138
203
|
end
|
139
204
|
|
140
|
-
|
141
|
-
attr_reader :result
|
205
|
+
instance_variable_set(:@dependencies, [])
|
142
206
|
|
143
|
-
#
|
207
|
+
# An array of node dependencies
|
208
|
+
attr_reader :dependencies
|
209
|
+
|
210
|
+
# The arguments assigned to self.
|
144
211
|
attr_accessor :args
|
145
212
|
|
146
213
|
def initialize(config={}, app=Tap::App.instance)
|
147
214
|
super
|
215
|
+
@dependencies = []
|
148
216
|
@resolved = false
|
149
|
-
@result = nil
|
150
217
|
@args = nil
|
218
|
+
|
219
|
+
# setup class dependencies
|
220
|
+
self.class.dependencies.each do |dependency_class|
|
221
|
+
depends_on dependency_class.instance(app)
|
222
|
+
end
|
151
223
|
end
|
152
224
|
|
153
|
-
# Conditional call to the super call; only calls once
|
154
|
-
|
225
|
+
# Conditional call to the super call; only calls once and with args (if
|
226
|
+
# set). Call recursively resolves dependencies and raises an error for
|
227
|
+
# circular dependencies.
|
228
|
+
#
|
229
|
+
def call
|
230
|
+
if resolved?
|
231
|
+
return
|
232
|
+
end
|
155
233
|
|
156
|
-
|
157
|
-
|
158
|
-
# Such arguments will be set as args, and be used to enque the
|
159
|
-
# task.
|
160
|
-
#
|
161
|
-
# If the task executes from the queue first, args will be
|
162
|
-
# provided to call and they should equal self.args. If the task
|
163
|
-
# executes as a dependency first, call will not receive args and
|
164
|
-
# in that case self.args will be used.
|
165
|
-
#
|
166
|
-
# This warns for cases that odd workflows can produce where the
|
167
|
-
# args have been set and DIFFERENT args are used to enque the task.
|
168
|
-
# In these cases always go with the pre-set args but warn the issue.
|
169
|
-
self.args ||= args
|
170
|
-
unless self.args == args
|
171
|
-
if @resolved
|
172
|
-
warn "warn: ignorning dependency task inputs #{args.inspect} (#{self})"
|
173
|
-
else
|
174
|
-
warn "warn: invoking dependency task with preset args #{self.args.inspect} and not inputs #{args.inspect} (#{self})"
|
175
|
-
end
|
234
|
+
if resolving?
|
235
|
+
raise DependencyError.new(self)
|
176
236
|
end
|
177
237
|
|
178
|
-
|
179
|
-
|
180
|
-
|
238
|
+
@resolved = nil
|
239
|
+
begin
|
240
|
+
dependencies.each do |dependency|
|
241
|
+
dependency.call
|
242
|
+
end
|
243
|
+
rescue(DependencyError)
|
244
|
+
$!.trace.unshift(self)
|
245
|
+
raise $!
|
181
246
|
end
|
182
|
-
|
247
|
+
|
248
|
+
@resolved = true
|
249
|
+
args ? super(*args) : super()
|
183
250
|
end
|
184
251
|
|
252
|
+
# Alias for call.
|
253
|
+
def resolve!
|
254
|
+
call
|
255
|
+
end
|
256
|
+
|
185
257
|
# Returns true if already resolved by call.
|
186
258
|
def resolved?
|
187
|
-
@resolved
|
259
|
+
@resolved == true
|
260
|
+
end
|
261
|
+
|
262
|
+
def resolving?
|
263
|
+
@resolved == nil
|
188
264
|
end
|
189
265
|
|
190
266
|
# Resets self so call will call again. Also sets result to nil.
|
191
267
|
def reset
|
268
|
+
raise "cannot reset when resolving" if resolving?
|
192
269
|
@resolved = false
|
193
|
-
@result = nil
|
194
270
|
end
|
195
271
|
|
196
272
|
# Collects the inputs into an OpenStruct according to the class arg_names,
|
@@ -216,5 +292,29 @@ module Rap
|
|
216
292
|
|
217
293
|
nil
|
218
294
|
end
|
295
|
+
|
296
|
+
# Adds the dependency to self.
|
297
|
+
def depends_on(dependency)
|
298
|
+
raise "cannot depend on self" if dependency == self
|
299
|
+
unless dependencies.include?(dependency)
|
300
|
+
dependencies << dependency
|
301
|
+
end
|
302
|
+
self
|
303
|
+
end
|
304
|
+
|
305
|
+
end
|
306
|
+
|
307
|
+
# Raised for circular dependencies during Rap::Task.resolve!
|
308
|
+
class DependencyError < StandardError
|
309
|
+
attr_reader :trace
|
310
|
+
|
311
|
+
def initialize(task)
|
312
|
+
@trace = [task]
|
313
|
+
super()
|
314
|
+
end
|
315
|
+
|
316
|
+
def message
|
317
|
+
"circular dependency: [#{trace.collect {|task| task.class.to_s }.join(', ')}]"
|
318
|
+
end
|
219
319
|
end
|
220
320
|
end
|
data/lib/rap/utils.rb
CHANGED
@@ -1,18 +1,67 @@
|
|
1
|
+
require 'tempfile'
|
2
|
+
|
1
3
|
module Rap
|
4
|
+
# Provides several shell utility methods for calling programs.
|
5
|
+
#
|
6
|
+
# == Windows
|
7
|
+
# MSDOS has command line length limits specific to the version of Windows being
|
8
|
+
# run (from http://www.ss64.com/nt/cmd.html):
|
9
|
+
#
|
10
|
+
# Windows NT:: 256 characters
|
11
|
+
# Windows 2000:: 2046 characters
|
12
|
+
# Windows XP:: 8190 characters
|
13
|
+
#
|
14
|
+
# Commands longer than these limits fail, usually with something like: 'the input
|
15
|
+
# line is too long'
|
2
16
|
module Utils
|
17
|
+
|
18
|
+
# :startdoc:::-
|
3
19
|
# Run the system command +cmd+, passing the result to the block, if given.
|
4
20
|
# Raises an error if the command fails. Uses the same semantics as
|
5
21
|
# Kernel::exec and Kernel::system.
|
6
22
|
#
|
7
23
|
# Based on FileUtils#sh from Rake.
|
24
|
+
# :startdoc:::+
|
8
25
|
def sh(*cmd) # :yields: ok, status
|
9
26
|
ok = system(*cmd)
|
10
27
|
|
11
28
|
if block_given?
|
12
29
|
yield(ok, $?)
|
13
30
|
else
|
14
|
-
ok or raise "Command failed with status (#{$?.exitstatus}): [#{cmd.join(' ')}]"
|
31
|
+
ok or raise "Command failed with status (#{$?.exitstatus}): [#{ cmd.join(' ')}]"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
# Runs the system command +cmd+ using sh, redirecting the output to the
|
36
|
+
# specified file path. Uses the redirection command:
|
37
|
+
#
|
38
|
+
# "> \"#{path}\" 2>&1 #{cmd}"
|
39
|
+
#
|
40
|
+
# This redirection has been tested on Windows, OS X, and Fedora. See
|
41
|
+
# http://en.wikipedia.org/wiki/Redirection_(Unix) for pointers on
|
42
|
+
# redirection. This style of redirection SHOULD NOT be used with
|
43
|
+
# commands that contain other redirections.
|
44
|
+
def redirect_sh(cmd, path, &block) # :yields: ok, status
|
45
|
+
sh( "> \"#{path}\" 2>&1 #{cmd}", &block)
|
46
|
+
end
|
47
|
+
|
48
|
+
# Runs the system command +cmd+ and returns the output as a string.
|
49
|
+
def capture_sh(cmd, quiet=false, &block) # :yields: ok, status, tempfile_path
|
50
|
+
tempfile = Tempfile.new('shell_utils')
|
51
|
+
tempfile.close
|
52
|
+
redirect_sh(cmd, tempfile.path) do |ok, status|
|
53
|
+
if block_given?
|
54
|
+
yield(ok, $?, tempfile.path)
|
55
|
+
else
|
56
|
+
ok or raise %Q{Command failed with status (#{$?.exitstatus}): [#{cmd}]
|
57
|
+
-------------- command output -------------------
|
58
|
+
#{File.read(tempfile.path)}
|
59
|
+
-------------------------------------------------
|
60
|
+
}
|
61
|
+
end
|
15
62
|
end
|
63
|
+
|
64
|
+
quiet == true ? "" : File.read(tempfile.path)
|
16
65
|
end
|
17
66
|
end
|
18
67
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rap
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.14.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Simon Chiang
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-06-
|
12
|
+
date: 2009-06-17 00:00:00 -06:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -20,7 +20,7 @@ dependencies:
|
|
20
20
|
requirements:
|
21
21
|
- - ">="
|
22
22
|
- !ruby/object:Gem::Version
|
23
|
-
version: 0.
|
23
|
+
version: 0.18.0
|
24
24
|
version:
|
25
25
|
description:
|
26
26
|
email: simon.a.chiang@gmail.com
|
@@ -38,8 +38,8 @@ files:
|
|
38
38
|
- lib/rap/declarations.rb
|
39
39
|
- lib/rap/description.rb
|
40
40
|
- lib/rap/rake.rb
|
41
|
-
- lib/rap/utils.rb
|
42
41
|
- lib/rap.rb
|
42
|
+
- lib/rap/utils.rb
|
43
43
|
- tap.yml
|
44
44
|
- README
|
45
45
|
- MIT-LICENSE
|