rap 0.12.3 → 0.13.0
Sign up to get free protection for your applications and to get access to all the features.
- data/History +7 -0
- data/README +36 -18
- data/bin/rap +44 -84
- data/doc/Syntax Reference +35 -27
- data/lib/rap.rb +6 -0
- data/lib/rap/declaration_task.rb +124 -22
- data/lib/rap/declarations.rb +83 -42
- data/lib/rap/description.rb +4 -4
- data/lib/rap/rake.rb +19 -10
- data/lib/rap/utils.rb +18 -0
- metadata +5 -6
- data/doc/Command Reference +0 -22
- data/lib/rap/rake_app.rb +0 -107
data/History
CHANGED
data/README
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
= {Rap (Rakish App)}[http://tap.rubyforge.org/rap]
|
2
2
|
|
3
3
|
rap v. a quick, sharp knock or blow
|
4
|
-
|
4
|
+
rak.ish adj. having a dashing, jaunty, or slightly disreputable quality or appearance
|
5
5
|
|
6
6
|
A rakish extension to {Tap}[http://tap.rubyforge.org/rdoc].
|
7
7
|
|
@@ -20,16 +20,13 @@ Check out these links for documentation, development, and bug tracking.
|
|
20
20
|
|
21
21
|
== Usage
|
22
22
|
|
23
|
-
Usage is much like {
|
23
|
+
Usage is much like {Rake}[http://rake.rubyforge.org/]:
|
24
24
|
|
25
25
|
[Rapfile]
|
26
|
-
require 'rap/declarations'
|
27
|
-
include Rap::Declarations
|
28
|
-
|
29
|
-
desc "your basic goodnight moon task"
|
30
26
|
|
27
|
+
# ::desc your basic goodnight moon task
|
31
28
|
# Says goodnight with a configurable message.
|
32
|
-
task(:goodnight, :obj, :message => 'goodnight') do |task, args|
|
29
|
+
Rap.task(:goodnight, :obj, :message => 'goodnight') do |task, args|
|
33
30
|
puts "#{task.message} #{args.obj}\n"
|
34
31
|
end
|
35
32
|
|
@@ -52,13 +49,14 @@ Now from the command line:
|
|
52
49
|
--message MESSAGE
|
53
50
|
|
54
51
|
options:
|
55
|
-
|
56
|
-
--name NAME
|
57
|
-
--
|
52
|
+
--help Print this help
|
53
|
+
--name NAME Specifies the task name
|
54
|
+
--config FILE Specifies a config file
|
58
55
|
|
59
56
|
For testing, load the Rapfile and access the task as a constant.
|
60
57
|
|
61
58
|
[test.rb]
|
59
|
+
require 'rap'
|
62
60
|
load 'Rapfile'
|
63
61
|
require 'test/unit'
|
64
62
|
require 'stringio'
|
@@ -86,19 +84,39 @@ The test passes:
|
|
86
84
|
1 tests, 2 assertions, 0 failures, 0 errors
|
87
85
|
|
88
86
|
Generally speaking, the rap executable is a shorthand for 'tap run --' so you
|
89
|
-
can use rap to
|
90
|
-
|
91
|
-
|
87
|
+
can use rap to launch workflows as well.
|
88
|
+
|
89
|
+
== Limitations
|
90
|
+
|
91
|
+
Rap is not a pure replacement of Rake, nor do the Rap tasks behave exactly
|
92
|
+
like standard Tap tasks.
|
93
|
+
|
94
|
+
==== Regarding Rake:
|
95
|
+
|
96
|
+
* Rap does not support builds by default
|
97
|
+
* Classes like FileList are not available
|
98
|
+
* Namespace lookup is slightly different (see the {Syntax Reference}[link:files/doc/Syntax%20Reference.html])
|
99
|
+
|
100
|
+
That said, many rakefiles can be renamed as rapfiles and they'll work with
|
101
|
+
minor and sometimes no changes.
|
102
|
+
|
103
|
+
==== Regarding Tap
|
104
|
+
|
105
|
+
Rap tasks (ie subclasses of Rap::DeclarationTask) are designed to behave like
|
106
|
+
Rake tasks. As such Rap tasks:
|
92
107
|
|
93
|
-
|
108
|
+
* return nil and pass nil in workflows
|
109
|
+
* only execute once
|
110
|
+
* are effectively singletons
|
94
111
|
|
95
|
-
|
96
|
-
|
97
|
-
|
112
|
+
This makes rap tasks useful in dependency-based workflows but fairly useless
|
113
|
+
in imperative workflows. However, other tasks behave as normal and any
|
114
|
+
workflow you can run with 'tap run' can be run without alteration by rap.
|
98
115
|
|
99
116
|
== Installation
|
100
117
|
|
101
|
-
Rap is available as a gem on RubyForge[http://rubyforge.org/projects/tap].
|
118
|
+
Rap is available as a gem on RubyForge[http://rubyforge.org/projects/tap].
|
119
|
+
Use:
|
102
120
|
|
103
121
|
% gem install rap
|
104
122
|
|
data/bin/rap
CHANGED
@@ -2,20 +2,14 @@
|
|
2
2
|
# usage: rap taskname {options} [args] [-d-]
|
3
3
|
|
4
4
|
$:.unshift "#{File.dirname(__FILE__)}/../lib"
|
5
|
-
require 'rap
|
5
|
+
require 'rap'
|
6
6
|
|
7
7
|
# setup the environment
|
8
8
|
begin
|
9
9
|
|
10
|
-
env = Tap::Exe.setup
|
11
|
-
|
12
|
-
|
13
|
-
Dir.glob('[TtRr]apfile{,.rb}').each do |task_file|
|
14
|
-
task_file = File.expand_path(task_file)
|
15
|
-
next unless File.file?(task_file)
|
16
|
-
|
17
|
-
env.loads.unshift(task_file)
|
18
|
-
end
|
10
|
+
env = Tap::Exe.setup
|
11
|
+
Rap::Declarations.env = env
|
12
|
+
env.activate
|
19
13
|
|
20
14
|
rescue(Tap::Env::ConfigError)
|
21
15
|
# catch errors and exit gracefully
|
@@ -24,92 +18,58 @@ rescue(Tap::Env::ConfigError)
|
|
24
18
|
exit(1)
|
25
19
|
end
|
26
20
|
|
27
|
-
#
|
28
|
-
# setup after script
|
29
|
-
#
|
30
|
-
|
31
|
-
at_exit do
|
32
|
-
begin
|
33
|
-
eval(env.after) if env.after != nil
|
34
|
-
rescue(Exception)
|
35
|
-
puts "Error in after script."
|
36
|
-
env.handle_error($!)
|
37
|
-
exit(1)
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
#
|
42
|
-
# run before script
|
43
|
-
#
|
44
|
-
|
45
|
-
begin
|
46
|
-
eval(env.before) if env.before != nil
|
47
|
-
rescue(Exception)
|
48
|
-
puts "Error in before script."
|
49
|
-
env.handle_error($!)
|
50
|
-
exit(1)
|
51
|
-
end
|
52
|
-
|
53
21
|
#
|
54
22
|
# run rap
|
55
23
|
#
|
56
24
|
|
57
|
-
|
58
|
-
|
25
|
+
Dir.glob('[TtRr]apfile{,.rb}').each do |rapfile|
|
26
|
+
next unless File.file?(rapfile)
|
27
|
+
load rapfile
|
59
28
|
end
|
60
29
|
|
61
|
-
|
62
|
-
|
30
|
+
case ARGV[0]
|
31
|
+
when '--help', nil, '-T'
|
63
32
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
<%=
|
33
|
+
# same as normal summarize, but pass over tasks that have no comment
|
34
|
+
summary_template = %Q{<% entries.delete_if {|key, const| const.comment.kind_of?(Rap::Description) && const.comment.resolve.desc == nil } %>
|
35
|
+
<% if !entries.empty? && count > 1 %>
|
36
|
+
<%= env_key %>:
|
68
37
|
<% end %>
|
69
|
-
<% entries.each do |
|
70
|
-
|
71
|
-
<%
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
puts Lazydoc.usage(__FILE__)
|
81
|
-
puts
|
82
|
-
puts "=== tap tasks ==="
|
83
|
-
puts env.summarize(:tasks, rap_template)
|
38
|
+
<% entries.each do |key, const| %>
|
39
|
+
<%= key.ljust(width) %> # <%= const.comment %>
|
40
|
+
<% end %>
|
41
|
+
}
|
42
|
+
|
43
|
+
puts Lazydoc.usage(__FILE__)
|
44
|
+
puts
|
45
|
+
puts "=== tap tasks ==="
|
46
|
+
puts env.manifest(:task).summarize(summary_template)
|
47
|
+
|
48
|
+
if Rap::Rake.has_rakefile?
|
84
49
|
puts
|
85
50
|
puts "=== rake tasks ==="
|
86
|
-
Rap::Rake.new.
|
87
|
-
Tap::App.instance.run
|
88
|
-
|
89
|
-
# this is not currently reached as rake exits on -T
|
90
|
-
puts
|
91
|
-
puts "version #{Tap::VERSION} -- #{Tap::WEBSITE}"
|
92
|
-
exit
|
93
|
-
else
|
94
|
-
app = Tap::App.instance
|
95
|
-
schema = Tap::Support::Schema.parse(ARGV)
|
96
|
-
ARGV.clear
|
97
|
-
env.build(schema, app) do |args|
|
98
|
-
warn "warning: implict rake for [#{args.join(' ')}]"
|
99
|
-
Rap::Rake
|
100
|
-
end
|
101
|
-
|
102
|
-
if app.queue.empty?
|
103
|
-
puts "no task specified"
|
104
|
-
exit
|
105
|
-
end
|
106
|
-
|
107
|
-
env.set_signals
|
108
|
-
app.run
|
51
|
+
Rap::Rake.new.execute('-T')
|
109
52
|
end
|
110
53
|
|
111
|
-
|
112
|
-
|
54
|
+
puts
|
55
|
+
puts "version #{Tap::VERSION} -- #{Tap::WEBSITE}"
|
56
|
+
else
|
57
|
+
begin
|
58
|
+
schema = Tap::Schema.parse(ARGV)
|
59
|
+
env.run(schema) do |type, key, metadata|
|
60
|
+
if type == :task && Rap::Rake.has_rakefile?
|
61
|
+
warn "warning: implict rake for '#{metadata.join(' ')}'"
|
62
|
+
metadata.unshift(key)
|
63
|
+
Rap::Rake
|
64
|
+
else
|
65
|
+
nil
|
66
|
+
end
|
67
|
+
end
|
68
|
+
rescue
|
69
|
+
raise if $DEBUG
|
70
|
+
puts $!.message
|
71
|
+
exit(1)
|
72
|
+
end
|
113
73
|
end
|
114
74
|
|
115
75
|
exit(0)
|
data/doc/Syntax Reference
CHANGED
@@ -4,13 +4,7 @@
|
|
4
4
|
|
5
5
|
A task declaration:
|
6
6
|
|
7
|
-
|
8
|
-
# key of a {key => dependencies} hash
|
9
|
-
# dependencies:: an array of task names (optional)
|
10
|
-
# arg_names:: an array of argument names (optional)
|
11
|
-
# configurations:: a hash of {key => default} pairs (optional)
|
12
|
-
|
13
|
-
task({<name> => [<dependencies...>]}, <arg_names...>, {<configs>}) do |task, args|
|
7
|
+
task(<name>, <arg_names...>, {<configs>}) do |task, args|
|
14
8
|
# arguments are available through args:
|
15
9
|
args.arg_name
|
16
10
|
|
@@ -18,6 +12,10 @@ A task declaration:
|
|
18
12
|
task.key
|
19
13
|
end
|
20
14
|
|
15
|
+
A task declaration with dependencies:
|
16
|
+
|
17
|
+
task({<name> => [<dependencies...>]}, <arg_names...>, {<configs>}) { task ... }
|
18
|
+
|
21
19
|
A namespace declaration:
|
22
20
|
|
23
21
|
namespace(<name>) { task ... }
|
@@ -39,19 +37,19 @@ Extended documentation:
|
|
39
37
|
# Lines are justified and wrapped on the command line.
|
40
38
|
task ...
|
41
39
|
|
42
|
-
Pains were taken to make task declarations for
|
43
|
-
tasks.
|
44
|
-
|
40
|
+
Pains were taken to make task declarations for Rap work the similar to Rake
|
41
|
+
tasks. For both Rake and Rap (noting that in general task classes are not
|
42
|
+
limited in these ways):
|
45
43
|
|
46
44
|
* tasks are singleton instances that may be extended across multiple
|
47
45
|
declarations
|
48
46
|
* tasks do not pass inputs from one task to the next
|
49
47
|
* tasks only execute once
|
50
48
|
|
51
|
-
A few syntactical differences between
|
52
|
-
can cause errors
|
49
|
+
A few syntactical differences between Rake and Rap must to be noted, as they
|
50
|
+
can cause errors during migration.
|
53
51
|
|
54
|
-
====
|
52
|
+
==== No :needs
|
55
53
|
|
56
54
|
Rap does not support :needs as a way to specify dependencies. For instance,
|
57
55
|
this will declare a ':needs' configuration with the default value ':another',
|
@@ -59,24 +57,34 @@ not a task which depends on another:
|
|
59
57
|
|
60
58
|
Rap.task :name, :needs => :another
|
61
59
|
|
62
|
-
====
|
60
|
+
==== Namespace Lookup
|
63
61
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
62
|
+
Rap immediately resolves dependencies relative to the top level namespace,
|
63
|
+
which is very different from Rake. Rake waits to resolve dependencies and will
|
64
|
+
use a match within a namespace if it becomes available. For these tasks rap
|
65
|
+
and rake produce different results:
|
68
66
|
|
69
|
-
|
67
|
+
[Rapfile/Rakfile]
|
68
|
+
|
69
|
+
task(:outer) { print 'non-nested' }
|
70
70
|
namespace :nest do
|
71
|
-
task
|
72
|
-
task :outer {
|
71
|
+
task(:inner1 => :outer) { puts ' was executed' }
|
72
|
+
task(:inner2 => 'nest:outer') { puts ' was executed' }
|
73
|
+
task(:outer) { print 'nested' }
|
73
74
|
end
|
74
75
|
|
75
|
-
|
76
|
-
within a namespace in preference to a literal match. For these tasks rap and
|
77
|
-
rake produce different results:
|
76
|
+
Rap resolves the dependencies literally:
|
78
77
|
|
79
|
-
% rap nest/
|
78
|
+
% rap nest/inner1
|
80
79
|
non-nested was executed
|
81
|
-
|
82
|
-
|
80
|
+
|
81
|
+
% rap nest/inner2
|
82
|
+
nested was executed
|
83
|
+
|
84
|
+
Rake resolves the dependencies relative to the namespace:
|
85
|
+
|
86
|
+
% rake nest:inner1
|
87
|
+
nested was executed
|
88
|
+
|
89
|
+
% rake nest:inner2
|
90
|
+
nested was executed
|
data/lib/rap.rb
ADDED
data/lib/rap/declaration_task.rb
CHANGED
@@ -1,14 +1,41 @@
|
|
1
|
-
require 'tap'
|
1
|
+
require 'tap/task'
|
2
|
+
require 'tap/env'
|
2
3
|
require 'ostruct'
|
3
4
|
require 'rap/description'
|
4
5
|
|
5
6
|
module Rap
|
6
7
|
|
7
|
-
# DeclarationTasks are a
|
8
|
-
#
|
9
|
-
#
|
8
|
+
# DeclarationTasks are a special breed of Tap::Task designed to behave much
|
9
|
+
# like Rake tasks. As such, declaration tasks:
|
10
|
+
#
|
11
|
+
# * return nil and pass nil in workflows
|
12
|
+
# * only execute once
|
13
|
+
# * are effectively singletons (one instance per app)
|
14
|
+
# * allow for multiple actions
|
15
|
+
#
|
16
|
+
# The DeclarationTask class partially includes Declarations so subclasses
|
17
|
+
# may directly declare tasks. A few alias acrobatics makes it so that ONLY
|
18
|
+
# Declarations#task is made available (desc cannot be used because Task
|
19
|
+
# classes already use that method for documentation, and namespace
|
20
|
+
# would be silly).
|
21
|
+
#
|
22
|
+
# Weird? Yes, but it leads to this syntax:
|
23
|
+
#
|
24
|
+
# # [Rapfile]
|
25
|
+
# # class Subclass < Rap::DeclarationTask
|
26
|
+
# # def helper(); "help"; end
|
27
|
+
# # end
|
28
|
+
# #
|
29
|
+
# # # ::desc a help task
|
30
|
+
# # Subclass.task(:help) {|task, args| puts "got #{task.helper}"}
|
31
|
+
#
|
32
|
+
# % rap help
|
33
|
+
# got help
|
34
|
+
#
|
10
35
|
class DeclarationTask < Tap::Task
|
11
36
|
class << self
|
37
|
+
|
38
|
+
# Sets actions.
|
12
39
|
attr_writer :actions
|
13
40
|
|
14
41
|
# An array of actions (blocks) associated with this class. Each of the
|
@@ -18,6 +45,7 @@ module Rap
|
|
18
45
|
@actions ||= []
|
19
46
|
end
|
20
47
|
|
48
|
+
# Sets argument names
|
21
49
|
attr_writer :arg_names
|
22
50
|
|
23
51
|
# The argument names pulled from a task declaration.
|
@@ -32,24 +60,43 @@ module Rap
|
|
32
60
|
args
|
33
61
|
end
|
34
62
|
|
35
|
-
#
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
63
|
+
# Instantiates the instance of self for app and reconfigures it using
|
64
|
+
# argh. Configurations are set, the task name is set, and the
|
65
|
+
# arguments are stored on the instance. The arguments are returned
|
66
|
+
# as normal in the [instance, args] result.
|
67
|
+
#
|
68
|
+
# These atypical behaviors handle various situations on the command
|
69
|
+
# line. Setting the args this way, for example, allows arguments to
|
70
|
+
# be specified on dependency tasks:
|
71
|
+
#
|
72
|
+
# # [Rapfile]
|
73
|
+
# # Rap.task(:a, :obj) {|t, a| puts "A #{a.obj}"}
|
74
|
+
# # Rap.task({:b => :a}, :obj) {|t, a| puts "B #{a.obj}"}
|
75
|
+
#
|
76
|
+
# % rap b world -- a hello
|
77
|
+
# A hello
|
78
|
+
# B world
|
79
|
+
#
|
80
|
+
def instantiate(argh={}, app=Tap::App.instance)
|
81
|
+
config = argh[:config]
|
82
|
+
config_file = argh[:config_file]
|
83
|
+
|
84
|
+
instance = self.instance(app)
|
85
|
+
instance.reconfigure(load_config(config_file)) if config_file
|
86
|
+
instance.reconfigure(config) if config
|
87
|
+
instance.args = argh[:args]
|
88
|
+
|
89
|
+
[instance, instance.args]
|
40
90
|
end
|
41
91
|
|
42
|
-
# Looks up or creates the DeclarationTask subclass specified by
|
43
|
-
#
|
44
|
-
# Declare also registers the subclass in the declaration_env tasks
|
45
|
-
# manifest.
|
46
|
-
#
|
47
|
-
# Configurations are always validated using the yaml transformation block
|
48
|
-
# (see {Configurable::Validation.yaml}[http://tap.rubyforge.org/configurable/classes/Configurable/Validation.html]).
|
92
|
+
# Looks up or creates the DeclarationTask subclass specified by const_name
|
93
|
+
# and adds the configs and dependencies.
|
49
94
|
#
|
95
|
+
# Configurations are always validated using the yaml transformation block
|
96
|
+
# (see {Configurable::Validation}[http://tap.rubyforge.org/configurable/classes/Configurable/Validation.html]).
|
50
97
|
def subclass(const_name, configs={}, dependencies=[])
|
51
98
|
# lookup or generate the subclass
|
52
|
-
subclass = Tap::
|
99
|
+
subclass = Tap::Env::Constant.constantize(const_name.to_s) do |base, constants|
|
53
100
|
subclass_const = constants.pop
|
54
101
|
constants.inject(base) do |namespace, const|
|
55
102
|
# nesting Task classes into other Task classes is required
|
@@ -72,19 +119,74 @@ module Rap
|
|
72
119
|
|
73
120
|
# add dependencies
|
74
121
|
dependencies.each do |dependency|
|
75
|
-
dependency_name = File.basename(dependency.
|
122
|
+
dependency_name = File.basename(dependency.to_s.underscore)
|
123
|
+
|
124
|
+
# this suppresses 'method redefined' warnings
|
125
|
+
if subclass.method_defined?(dependency_name)
|
126
|
+
subclass.send(:undef_method, dependency_name)
|
127
|
+
end
|
128
|
+
|
76
129
|
subclass.send(:depends_on, dependency_name, dependency)
|
77
130
|
end
|
78
131
|
|
79
132
|
subclass
|
80
133
|
end
|
134
|
+
end
|
135
|
+
|
136
|
+
# The result of self, set by call.
|
137
|
+
attr_reader :result
|
138
|
+
|
139
|
+
# The arguments assigned to self during call.
|
140
|
+
attr_accessor :args
|
141
|
+
|
142
|
+
def initialize(config={}, app=Tap::App.instance)
|
143
|
+
super
|
144
|
+
@resolved = false
|
145
|
+
@result = nil
|
146
|
+
@args = nil
|
147
|
+
end
|
148
|
+
|
149
|
+
# Conditional call to the super call; only calls once. Returns result.
|
150
|
+
def call(*args)
|
81
151
|
|
82
|
-
|
152
|
+
# Declaration tasks function as dependencies, but unlike normal
|
153
|
+
# dependencies, they CAN take arguments from the command line.
|
154
|
+
# Such arguments will be set as args, and be used to enque the
|
155
|
+
# task.
|
156
|
+
#
|
157
|
+
# If the task executes from the queue first, args will be
|
158
|
+
# provided to call and they should equal self.args. If the task
|
159
|
+
# executes as a dependency first, call will not receive args and
|
160
|
+
# in that case self.args will be used.
|
161
|
+
#
|
162
|
+
# This warns for cases that odd workflows can produce where the
|
163
|
+
# args have been set and DIFFERENT args are used to enque the task.
|
164
|
+
# In these cases always go with the pre-set args but warn the issue.
|
165
|
+
self.args ||= args
|
166
|
+
unless self.args == args
|
167
|
+
if @resolved
|
168
|
+
warn "warn: ignorning dependency task inputs #{args.inspect} (#{self})"
|
169
|
+
else
|
170
|
+
warn "warn: invoking dependency task with preset args #{self.args.inspect} and not inputs #{args.inspect} (#{self})"
|
171
|
+
end
|
172
|
+
end
|
83
173
|
|
84
|
-
|
85
|
-
|
86
|
-
self
|
174
|
+
unless @resolved
|
175
|
+
@resolved = true
|
176
|
+
@result = super(*self.args)
|
87
177
|
end
|
178
|
+
result
|
179
|
+
end
|
180
|
+
|
181
|
+
# Returns true if already resolved by call.
|
182
|
+
def resolved?
|
183
|
+
@resolved
|
184
|
+
end
|
185
|
+
|
186
|
+
# Resets self so call will call again. Also sets result to nil.
|
187
|
+
def reset
|
188
|
+
@resolved = false
|
189
|
+
@result = nil
|
88
190
|
end
|
89
191
|
|
90
192
|
# Collects the inputs into an OpenStruct according to the class arg_names,
|
data/lib/rap/declarations.rb
CHANGED
@@ -1,27 +1,28 @@
|
|
1
1
|
require 'rap/declaration_task'
|
2
|
-
require '
|
2
|
+
require 'rap/utils'
|
3
3
|
|
4
4
|
module Rap
|
5
5
|
|
6
|
-
# Defines the
|
7
|
-
# top level (like Rake) or
|
8
|
-
# through Rap.
|
6
|
+
# Defines the Rap task declaration methods. They may be included at the
|
7
|
+
# top level (like Rake) or used through Rap.
|
9
8
|
#
|
10
|
-
#
|
9
|
+
# === Usage
|
10
|
+
#
|
11
|
+
# Unlike in rake, task will define actual task classes according to the task
|
11
12
|
# names. Task classes may be nested within modules using namespace. It's
|
12
13
|
# VERY important to realize this is the case both to aid in thing like
|
13
14
|
# testing and to prevent namespace conflicts. For example:
|
14
15
|
#
|
15
|
-
# Rap.task(:sample)
|
16
|
+
# t = Rap.task(:sample)
|
17
|
+
# t.class # => Sample
|
18
|
+
#
|
16
19
|
# Rap.namespace(:nested) do
|
17
|
-
# Rap.task(:sample)
|
20
|
+
# t = Rap.task(:sample)
|
21
|
+
# t.class # => Nested::Sample
|
18
22
|
# end
|
19
23
|
#
|
20
|
-
# Normally all declared tasks are subclasses of DeclarationTask
|
21
|
-
#
|
22
|
-
# to call declare on the subclass. This feature is only available to
|
23
|
-
# subclasses of DeclarationTask, but can be used within namespaces, and in
|
24
|
-
# conjunction with desc.
|
24
|
+
# Normally all declared tasks are subclasses of DeclarationTask, but
|
25
|
+
# subclasses of DeclarationTask can declare tasks as well.
|
25
26
|
#
|
26
27
|
# class Alt < DeclarationTask
|
27
28
|
# end
|
@@ -30,31 +31,41 @@ module Rap
|
|
30
31
|
#
|
31
32
|
# desc "task one, a subclass of DeclarationTask"
|
32
33
|
# o = Rap.task(:one)
|
33
|
-
# o.class
|
34
|
-
# o.class.superclass
|
35
|
-
# o.class.
|
34
|
+
# o.class # => One
|
35
|
+
# o.class.superclass # => DeclarationTask
|
36
|
+
# o.class.desc.to_s # => "task one, a subclass of DeclarationTask"
|
36
37
|
#
|
37
38
|
# namespace(:nest) do
|
38
|
-
#
|
39
39
|
# desc "task two, a nested subclass of Alt"
|
40
|
-
# t = Alt.
|
40
|
+
# t = Alt.task(:two)
|
41
41
|
# t.class # => Nest::Two
|
42
42
|
# t.class.superclass # => Alt
|
43
|
-
# t.class.
|
44
|
-
#
|
43
|
+
# t.class.desc.to_s # => "task two, a nested subclass of Alt"
|
45
44
|
# end
|
46
45
|
#
|
47
|
-
#
|
46
|
+
# This feature is only available to subclasses of DeclarationTask and can
|
47
|
+
# be very useful for creating inheritance hierarchies. Note that other
|
48
|
+
# declaration methods like 'desc' and 'namespace' are not available on
|
49
|
+
# DeclarationTask or subclasses, just 'task'.
|
50
|
+
#
|
51
|
+
# See the {Syntax Reference}[link:files/doc/Syntax%20Reference.html] for more
|
52
|
+
# information.
|
48
53
|
module Declarations
|
49
|
-
include
|
54
|
+
include Utils
|
50
55
|
|
51
56
|
# The environment in which declared task classes are registered.
|
52
|
-
# By default
|
53
|
-
def Declarations.env() @@env ||= Tap::Env.
|
57
|
+
# By default a Tap::Env for Dir.pwd.
|
58
|
+
def Declarations.env() @@env ||= Tap::Env.new; end
|
54
59
|
|
55
60
|
# Sets the declaration environment.
|
56
61
|
def Declarations.env=(env) @@env=env; end
|
57
62
|
|
63
|
+
# The declaration App (default Tap::App.instance)
|
64
|
+
def Declarations.app() @@app ||= Tap::App.instance; end
|
65
|
+
|
66
|
+
# Sets the declaration App.
|
67
|
+
def Declarations.app=(app) @@app=app; end
|
68
|
+
|
58
69
|
# The base constant for all task declarations, prepended to the task name.
|
59
70
|
def Declarations.current_namespace() @@current_namespace; end
|
60
71
|
@@current_namespace = ''
|
@@ -64,6 +75,11 @@ module Rap
|
|
64
75
|
def Declarations.current_desc() @@current_desc; end
|
65
76
|
@@current_desc = nil
|
66
77
|
|
78
|
+
# Returns the instance of the task class in app.
|
79
|
+
def Declarations.instance(tasc)
|
80
|
+
tasc.instance(Declarations.app)
|
81
|
+
end
|
82
|
+
|
67
83
|
# Declares a task with a rake-like syntax. Task generates a subclass of
|
68
84
|
# DeclarationTask, nested within the current namespace.
|
69
85
|
def task(*args, &action)
|
@@ -74,22 +90,27 @@ module Rap
|
|
74
90
|
|
75
91
|
# generate the task class
|
76
92
|
const_name = File.join(@@current_namespace, name.to_s).camelize
|
77
|
-
|
93
|
+
tasc = declaration_class.subclass(const_name, configs, dependencies)
|
78
94
|
|
79
95
|
# register documentation
|
80
|
-
|
81
|
-
|
96
|
+
desc = Lazydoc.register_caller(Description)
|
97
|
+
desc.desc = @@current_desc
|
82
98
|
@@current_desc = nil
|
83
99
|
|
84
|
-
|
85
|
-
|
86
|
-
|
100
|
+
tasc.arg_names = arg_names
|
101
|
+
tasc.desc = desc
|
102
|
+
tasc.source_file = desc.document.source_file
|
87
103
|
|
88
104
|
# add the action
|
89
|
-
|
105
|
+
tasc.actions << action if action
|
106
|
+
|
107
|
+
# register
|
108
|
+
register tasc
|
90
109
|
|
91
110
|
# return the instance
|
92
|
-
|
111
|
+
instance = Declarations.instance(tasc)
|
112
|
+
instance.config.bind(instance, true)
|
113
|
+
instance
|
93
114
|
end
|
94
115
|
|
95
116
|
# Nests tasks within the named module for the duration of the block.
|
@@ -152,7 +173,7 @@ module Rap
|
|
152
173
|
unless need.kind_of?(Class)
|
153
174
|
# lookup or declare non-class dependencies
|
154
175
|
name = normalize_name(need).camelize
|
155
|
-
need = Tap::
|
176
|
+
need = Tap::Env::Constant.constantize(name) do |base, constants|
|
156
177
|
const = block_given? ? yield(name) : nil
|
157
178
|
const or raise ArgumentError, "unknown task class: #{name}"
|
158
179
|
end
|
@@ -186,26 +207,46 @@ module Rap
|
|
186
207
|
|
187
208
|
# Registers a task class with the Declarations.env, if necessary.
|
188
209
|
# Returns task_class.
|
189
|
-
def register(
|
190
|
-
tasks = Declarations.env.
|
191
|
-
|
192
|
-
|
193
|
-
|
210
|
+
def register(tasc)
|
211
|
+
tasks = Declarations.env.manifest(:task)
|
212
|
+
|
213
|
+
const_name = tasc.to_s
|
214
|
+
constant = tasks.find do |const|
|
215
|
+
const.const_name == const_name
|
216
|
+
end
|
217
|
+
|
218
|
+
unless constant
|
219
|
+
constant = Tap::Env::Constant.new(const_name)
|
220
|
+
tasks.entries << constant
|
194
221
|
end
|
195
222
|
|
196
|
-
|
223
|
+
constant.comment = tasc.desc(false)
|
224
|
+
tasc
|
197
225
|
end
|
198
226
|
end
|
199
227
|
|
200
228
|
class DeclarationTask
|
201
229
|
class << self
|
230
|
+
# :stopdoc:
|
231
|
+
alias original_desc desc
|
232
|
+
# :startdoc:
|
233
|
+
|
202
234
|
include Declarations
|
203
235
|
|
204
|
-
#
|
205
|
-
|
236
|
+
# :stopdoc:
|
237
|
+
undef_method :desc
|
238
|
+
alias desc original_desc
|
239
|
+
|
240
|
+
# hide remaining Declarations methods (including Utils methods)
|
241
|
+
private :namespace, :sh
|
242
|
+
# :startdoc:
|
206
243
|
|
207
|
-
|
208
|
-
|
244
|
+
private
|
245
|
+
|
246
|
+
# overridden to provide self as the declaration_class
|
247
|
+
def declaration_class # :nodoc:
|
248
|
+
self
|
249
|
+
end
|
209
250
|
end
|
210
251
|
end
|
211
252
|
|
data/lib/rap/description.rb
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
module Rap
|
2
2
|
|
3
|
-
# :::-
|
3
|
+
# :startdoc:::-
|
4
4
|
# A special type of Lazydoc::Comment designed to handle the comment syntax
|
5
5
|
# for task declarations.
|
6
6
|
#
|
7
7
|
# Description instances can be assigned a description, or they may parse
|
8
8
|
# one directly from the comment. Comment lines with the constant attribute
|
9
9
|
# '::desc' will have the value set as desc.
|
10
|
-
# :::+
|
10
|
+
# :startdoc:::+
|
11
11
|
class Description < Lazydoc::Comment
|
12
12
|
|
13
13
|
# The description for self.
|
@@ -15,8 +15,8 @@ module Rap
|
|
15
15
|
|
16
16
|
# Parses in-comment descriptions from prepended lines, if present.
|
17
17
|
def prepend(line)
|
18
|
-
if line =~ /::desc
|
19
|
-
self.desc = $1
|
18
|
+
if line =~ /::desc(?:\s+(.*?))?\s*$/
|
19
|
+
self.desc = $1.to_s
|
20
20
|
false
|
21
21
|
else
|
22
22
|
super
|
data/lib/rap/rake.rb
CHANGED
@@ -1,14 +1,15 @@
|
|
1
|
-
require '
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
2
3
|
|
3
4
|
module Rap
|
4
5
|
|
5
|
-
# :startdoc::
|
6
|
+
# :startdoc::task run rake tasks
|
6
7
|
#
|
7
8
|
# Simply enques the specified rake task(s) for execution. Useful when a
|
8
9
|
# rake task needs to be executed within a workflow. For example these
|
9
10
|
# are equivalent:
|
10
11
|
#
|
11
|
-
# %
|
12
|
+
# % rap rake test
|
12
13
|
# % rake test
|
13
14
|
#
|
14
15
|
# The only exeception is in the use of the --help option. Use --rake-help
|
@@ -16,7 +17,7 @@ module Rap
|
|
16
17
|
#
|
17
18
|
class Rake < Tap::Task
|
18
19
|
class << self
|
19
|
-
|
20
|
+
|
20
21
|
# Overrides Tap::Support::FrameworkClass#parse! to do
|
21
22
|
# nothing so that all args get passed forward to rake.
|
22
23
|
def parse!(argv, app=Tap::App.instance) # => instance, argv
|
@@ -24,13 +25,21 @@ module Rap
|
|
24
25
|
puts help
|
25
26
|
exit
|
26
27
|
end
|
27
|
-
|
28
|
+
argv = argv.collect {|arg| arg == '--rake-help' ? '--help' : arg}
|
29
|
+
[new({}, app), argv]
|
30
|
+
end
|
31
|
+
|
32
|
+
# Returns true if Rake detects a rakefile.
|
33
|
+
def has_rakefile?
|
34
|
+
::Rake.application.have_rakefile != nil
|
28
35
|
end
|
29
36
|
end
|
30
|
-
|
37
|
+
|
38
|
+
# Executes Rake using the input arguments as if they came from the
|
39
|
+
# command line.
|
31
40
|
def process(*argv)
|
32
41
|
rake = ::Rake.application
|
33
|
-
|
42
|
+
|
34
43
|
# run as if from command line using argv
|
35
44
|
current_argv = ARGV.dup
|
36
45
|
begin
|
@@ -45,9 +54,9 @@ module Rap
|
|
45
54
|
ARGV.clear
|
46
55
|
ARGV.concat(current_argv)
|
47
56
|
end
|
48
|
-
|
49
|
-
rake.
|
50
|
-
|
57
|
+
|
58
|
+
rake.top_level
|
59
|
+
|
51
60
|
nil
|
52
61
|
end
|
53
62
|
end
|
data/lib/rap/utils.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
module Rap
|
2
|
+
module Utils
|
3
|
+
# Run the system command +cmd+, passing the result to the block, if given.
|
4
|
+
# Raises an error if the command fails. Uses the same semantics as
|
5
|
+
# Kernel::exec and Kernel::system.
|
6
|
+
#
|
7
|
+
# Based on FileUtils#sh from Rake.
|
8
|
+
def sh(*cmd) # :yields: ok, status
|
9
|
+
ok = system(*cmd)
|
10
|
+
|
11
|
+
if block_given?
|
12
|
+
yield(ok, $?)
|
13
|
+
else
|
14
|
+
ok or raise "Command failed with status (#{$?.exitstatus}): [#{cmd.join(' ')}]"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
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.13.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-
|
12
|
+
date: 2009-05-25 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.17.0
|
24
24
|
version:
|
25
25
|
description:
|
26
26
|
email: simon.a.chiang@gmail.com
|
@@ -32,19 +32,18 @@ extra_rdoc_files:
|
|
32
32
|
- README
|
33
33
|
- MIT-LICENSE
|
34
34
|
- History
|
35
|
-
- doc/Command Reference
|
36
35
|
- doc/Syntax Reference
|
37
36
|
files:
|
38
37
|
- lib/rap/declaration_task.rb
|
39
38
|
- lib/rap/declarations.rb
|
40
39
|
- lib/rap/description.rb
|
41
|
-
- lib/rap/rake_app.rb
|
42
40
|
- lib/rap/rake.rb
|
41
|
+
- lib/rap/utils.rb
|
42
|
+
- lib/rap.rb
|
43
43
|
- tap.yml
|
44
44
|
- README
|
45
45
|
- MIT-LICENSE
|
46
46
|
- History
|
47
|
-
- doc/Command Reference
|
48
47
|
- doc/Syntax Reference
|
49
48
|
has_rdoc: true
|
50
49
|
homepage: http://tap.rubyforge.org
|
data/doc/Command Reference
DELETED
@@ -1,22 +0,0 @@
|
|
1
|
-
= Command Reference
|
2
|
-
|
3
|
-
Rap comes the rap executable. For help on the command line, type:
|
4
|
-
|
5
|
-
% rap --help
|
6
|
-
|
7
|
-
The rap executable is basically a shorthand for 'tap run --'. Specifying tasks
|
8
|
-
for rap is no different than 'tap run' (see the Tap {Command Reference}[http://tap.rubyforge.org/rdoc/files/doc/Command%20Reference.html]).
|
9
|
-
The only exception occurs when the task can't be found; unknown tasks are run
|
10
|
-
as if by rake. For instance all of these are the same:
|
11
|
-
|
12
|
-
Run a rake task with inputs and an ENV config:
|
13
|
-
|
14
|
-
% rake task_name[1,2,3] key=value
|
15
|
-
|
16
|
-
Explicitly run a Rap::Rake task using the same inputs:
|
17
|
-
|
18
|
-
% rap rake task_name[1,2,3] key=value
|
19
|
-
|
20
|
-
Implicitly run the Rap::Rake task:
|
21
|
-
|
22
|
-
% rap task_name[1,2,3] key=value
|
data/lib/rap/rake_app.rb
DELETED
@@ -1,107 +0,0 @@
|
|
1
|
-
require 'rubygems'
|
2
|
-
require 'rake'
|
3
|
-
require 'tap'
|
4
|
-
|
5
|
-
module Rap
|
6
|
-
class RakeManifest < Tap::Support::Manifest
|
7
|
-
def initialize(env)
|
8
|
-
@env = env
|
9
|
-
rake = ::Rake.application
|
10
|
-
super(rake.have_rakefile(env.root.root) ? [rake.instance_variable_get(:@rakefile)] : [])
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
|
-
module RakeApp
|
15
|
-
def self.extended(base)
|
16
|
-
Tap::Env.instantiate(Dir.pwd).activate unless Tap::Env.instance
|
17
|
-
base.env = Tap::Env.instance
|
18
|
-
end
|
19
|
-
|
20
|
-
attr_accessor :env
|
21
|
-
|
22
|
-
def enq_top_level(app)
|
23
|
-
# takes the place of rake.top_level
|
24
|
-
if options.show_tasks
|
25
|
-
display_tasks_and_comments
|
26
|
-
exit
|
27
|
-
elsif options.show_prereqs
|
28
|
-
display_prerequisites
|
29
|
-
exit
|
30
|
-
else
|
31
|
-
top_level_tasks.each do |task_string|
|
32
|
-
name, args = parse_task_string(task_string)
|
33
|
-
task = self[name]
|
34
|
-
app.mq(task, :invoke, *args)
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
def collect_tasks(*args)
|
40
|
-
# a little song and dance for compliance with
|
41
|
-
# rake pre- and post-0.8.2
|
42
|
-
argv = args.empty? ? ARGV : args[0]
|
43
|
-
argv.collect! do |arg|
|
44
|
-
next(arg) unless arg =~ /^:([a-z_\d]+):(.*)$/
|
45
|
-
env_pattern = $1
|
46
|
-
rake_task = $2
|
47
|
-
|
48
|
-
next(arg) unless entry = env.find(:envs, env_pattern, false)
|
49
|
-
|
50
|
-
mini_path, env = entry
|
51
|
-
root_path = env.root.root
|
52
|
-
|
53
|
-
if have_rakefile(root_path)
|
54
|
-
# load sequence echos that in raw_load_rakefile
|
55
|
-
puts "(in #{root_path})" unless options.silent
|
56
|
-
current_global_rakefile = $rakefile
|
57
|
-
$rakefile = @rakefile
|
58
|
-
|
59
|
-
namespaces = Tap::Root.split(mini_path, false).delete_if do |segment|
|
60
|
-
segment.empty?
|
61
|
-
end
|
62
|
-
|
63
|
-
#if @rakefile != ''
|
64
|
-
eval nest_namespace(%Q{load "#{File.join(root_path, @rakefile)}"}, namespaces.dup)
|
65
|
-
#end
|
66
|
-
|
67
|
-
$rakefile = current_global_rakefile
|
68
|
-
@rakefile = nil
|
69
|
-
|
70
|
-
namespaces << rake_task
|
71
|
-
namespaces.join(":")
|
72
|
-
else
|
73
|
-
fail "No Rakefile found for '#{env_pattern}' (looking for: #{@rakefiles.join(', ')})"
|
74
|
-
end
|
75
|
-
end
|
76
|
-
|
77
|
-
super
|
78
|
-
end
|
79
|
-
|
80
|
-
def have_rakefile(dir=nil)
|
81
|
-
return super() if dir == nil
|
82
|
-
Tap::Root.chdir(dir) { super() }
|
83
|
-
end
|
84
|
-
|
85
|
-
protected
|
86
|
-
|
87
|
-
NAMESPACE_STR = %Q{
|
88
|
-
namespace(:'%s') do
|
89
|
-
%s
|
90
|
-
end
|
91
|
-
}.strip
|
92
|
-
|
93
|
-
def nest_namespace(nest_str, namespaces)
|
94
|
-
return nest_str if namespaces.empty?
|
95
|
-
|
96
|
-
NAMESPACE_STR % [
|
97
|
-
namespaces.shift,
|
98
|
-
namespaces.empty? ? nest_str : nest_namespace(nest_str, namespaces)
|
99
|
-
]
|
100
|
-
end
|
101
|
-
end
|
102
|
-
end
|
103
|
-
|
104
|
-
Rake.application.extend Rap::RakeApp
|
105
|
-
Tap::Env.manifest(:rakefiles) do |env|
|
106
|
-
Rap::RakeManifest.new(env)
|
107
|
-
end
|