tap 0.10.1 → 0.11.0
Sign up to get free protection for your applications and to get access to all the features.
- data/History +12 -0
- data/MIT-LICENSE +0 -2
- data/README +23 -32
- data/bin/rap +116 -0
- data/bin/tap +6 -9
- data/cgi/run.rb +67 -0
- data/cmd/console.rb +1 -1
- data/cmd/destroy.rb +4 -4
- data/cmd/generate.rb +4 -4
- data/cmd/manifest.rb +61 -53
- data/cmd/run.rb +8 -75
- data/doc/Class Reference +130 -121
- data/doc/Command Reference +76 -124
- data/doc/Syntax Reference +290 -0
- data/doc/Tutorial +305 -237
- data/lib/tap/app.rb +140 -467
- data/lib/tap/constants.rb +2 -2
- data/lib/tap/declarations.rb +211 -0
- data/lib/tap/env.rb +171 -193
- data/lib/tap/exe.rb +100 -21
- data/lib/tap/file_task.rb +3 -3
- data/lib/tap/generator/base.rb +1 -1
- data/lib/tap/generator/destroy.rb +10 -10
- data/lib/tap/generator/generate.rb +29 -18
- data/lib/tap/generator/generators/command/command_generator.rb +2 -2
- data/lib/tap/generator/generators/command/templates/command.erb +2 -2
- data/lib/tap/generator/generators/config/config_generator.rb +3 -3
- data/lib/tap/generator/generators/config/templates/doc.erb +1 -1
- data/lib/tap/generator/generators/file_task/file_task_generator.rb +1 -1
- data/lib/tap/generator/generators/file_task/templates/task.erb +1 -1
- data/lib/tap/generator/generators/file_task/templates/test.erb +1 -1
- data/lib/tap/generator/generators/generator/generator_generator.rb +27 -0
- data/lib/tap/generator/generators/generator/templates/task.erb +27 -0
- data/lib/tap/generator/generators/root/root_generator.rb +13 -13
- data/lib/tap/generator/generators/root/templates/README +0 -0
- data/lib/tap/generator/generators/root/templates/Rakefile +2 -2
- data/lib/tap/generator/generators/root/templates/gemspec +4 -5
- data/lib/tap/generator/generators/root/templates/tapfile +11 -8
- data/lib/tap/generator/generators/root/templates/test/tap_test_suite.rb +1 -1
- data/lib/tap/generator/generators/task/task_generator.rb +1 -3
- data/lib/tap/generator/generators/task/templates/test.erb +1 -3
- data/lib/tap/patches/optparse/summarize.rb +62 -0
- data/lib/tap/root.rb +41 -29
- data/lib/tap/support/aggregator.rb +16 -3
- data/lib/tap/support/assignments.rb +10 -9
- data/lib/tap/support/audit.rb +58 -64
- data/lib/tap/support/class_configuration.rb +33 -44
- data/lib/tap/support/combinator.rb +125 -0
- data/lib/tap/support/configurable.rb +13 -14
- data/lib/tap/support/configurable_class.rb +21 -43
- data/lib/tap/support/configuration.rb +55 -9
- data/lib/tap/support/constant.rb +87 -13
- data/lib/tap/support/constant_manifest.rb +116 -0
- data/lib/tap/support/dependencies.rb +54 -0
- data/lib/tap/support/dependency.rb +44 -0
- data/lib/tap/support/executable.rb +247 -32
- data/lib/tap/support/executable_queue.rb +1 -1
- data/lib/tap/support/gems/rake.rb +29 -8
- data/lib/tap/support/gems.rb +10 -30
- data/lib/tap/support/instance_configuration.rb +29 -3
- data/lib/tap/support/intern.rb +46 -0
- data/lib/tap/support/join.rb +143 -0
- data/lib/tap/support/joins/fork.rb +19 -0
- data/lib/tap/support/joins/merge.rb +22 -0
- data/lib/tap/support/joins/sequence.rb +21 -0
- data/lib/tap/support/joins/switch.rb +25 -0
- data/lib/tap/support/joins/sync_merge.rb +63 -0
- data/lib/tap/support/joins.rb +15 -0
- data/lib/tap/support/lazy_attributes.rb +17 -2
- data/lib/tap/support/lazydoc/comment.rb +503 -0
- data/lib/tap/support/lazydoc/config.rb +17 -0
- data/lib/tap/support/lazydoc/definition.rb +36 -0
- data/lib/tap/support/lazydoc/document.rb +152 -0
- data/lib/tap/support/lazydoc/method.rb +24 -0
- data/lib/tap/support/lazydoc.rb +269 -343
- data/lib/tap/support/manifest.rb +121 -103
- data/lib/tap/support/minimap.rb +90 -0
- data/lib/tap/support/node.rb +56 -0
- data/lib/tap/support/parser.rb +436 -0
- data/lib/tap/support/schema.rb +359 -0
- data/lib/tap/support/shell_utils.rb +3 -5
- data/lib/tap/support/string_ext.rb +60 -0
- data/lib/tap/support/tdoc.rb +7 -2
- data/lib/tap/support/templater.rb +30 -16
- data/lib/tap/support/validation.rb +77 -8
- data/lib/tap/task.rb +431 -143
- data/lib/tap/tasks/dump.rb +15 -10
- data/lib/tap/tasks/load.rb +112 -0
- data/lib/tap/tasks/rake.rb +4 -41
- data/lib/tap/test/assertions.rb +38 -0
- data/lib/tap/test/env_vars.rb +1 -1
- data/lib/tap/test/extensions.rb +79 -0
- data/lib/tap/test/file_test.rb +420 -0
- data/lib/tap/test/file_test_class.rb +12 -0
- data/lib/tap/test/regexp_escape.rb +87 -0
- data/lib/tap/test/script_test.rb +46 -0
- data/lib/tap/test/script_tester.rb +115 -0
- data/lib/tap/test/subset_test.rb +260 -0
- data/lib/tap/test/subset_test_class.rb +99 -0
- data/lib/tap/test/{tap_methods.rb → tap_test.rb} +45 -43
- data/lib/tap/test/utils.rb +231 -0
- data/lib/tap/test.rb +53 -26
- data/lib/tap.rb +3 -20
- metadata +50 -27
- data/lib/tap/generator/generators/root/templates/test/tapfile_test.rb +0 -15
- data/lib/tap/patches/rake/rake_test_loader.rb +0 -8
- data/lib/tap/patches/rake/testtask.rb +0 -57
- data/lib/tap/patches/ruby19/backtrace_filter.rb +0 -51
- data/lib/tap/patches/ruby19/parsedate.rb +0 -16
- data/lib/tap/support/batchable.rb +0 -47
- data/lib/tap/support/batchable_class.rb +0 -107
- data/lib/tap/support/command_line.rb +0 -98
- data/lib/tap/support/comment.rb +0 -270
- data/lib/tap/support/constant_utils.rb +0 -127
- data/lib/tap/support/declarations.rb +0 -111
- data/lib/tap/support/framework.rb +0 -83
- data/lib/tap/support/framework_class.rb +0 -180
- data/lib/tap/support/run_error.rb +0 -39
- data/lib/tap/support/summary.rb +0 -30
- data/lib/tap/test/file_methods.rb +0 -377
- data/lib/tap/test/script_methods/script_test.rb +0 -98
- data/lib/tap/test/script_methods.rb +0 -107
- data/lib/tap/test/subset_methods.rb +0 -420
- data/lib/tap/workflow.rb +0 -200
data/doc/Tutorial
CHANGED
@@ -1,237 +1,305 @@
|
|
1
|
-
=
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
%
|
26
|
-
Goodnight -- your basic goodnight moon task
|
27
|
-
--------------------------------------------------------------------------------
|
28
|
-
|
29
|
-
--------------------------------------------------------------------------------
|
30
|
-
usage: tap run -- goodnight
|
31
|
-
|
32
|
-
configurations:
|
33
|
-
--message MESSAGE
|
34
|
-
|
35
|
-
options:
|
36
|
-
-h, --help Print this help
|
37
|
-
--name NAME Specify a name
|
38
|
-
--use FILE Loads inputs from file
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
%
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
1
|
+
= Tap (Task Application)
|
2
|
+
|
3
|
+
Tap is a framework for creating configurable, distributable tasks and workflows. Although scalable for complex workflows, at it simplest tap works like a supercharged rake. Using the rap executable, you can declare tasks using a syntax almost identical to rake, but with added support for configurations and documentation.
|
4
|
+
|
5
|
+
== Quickstart
|
6
|
+
|
7
|
+
If you've used rake, tap will be easy to pick up. To get started, make a Tapfile with a simple task declaration:
|
8
|
+
|
9
|
+
[Tapfile]
|
10
|
+
|
11
|
+
# ::desc your basic goodnight moon task
|
12
|
+
# Says goodnight with a configurable message.
|
13
|
+
Tap.task(:goodnight, :obj, :message => 'goodnight') do |task, args|
|
14
|
+
puts "#{task.message} #{args.obj}\n"
|
15
|
+
end
|
16
|
+
|
17
|
+
Now from the command line:
|
18
|
+
|
19
|
+
% rap goodnight moon
|
20
|
+
goodnight moon
|
21
|
+
|
22
|
+
% rap goodnight world --message hello
|
23
|
+
hello world
|
24
|
+
|
25
|
+
% rap goodnight --help
|
26
|
+
Goodnight -- your basic goodnight moon task
|
27
|
+
--------------------------------------------------------------------------------
|
28
|
+
Says goodnight with a configurable message.
|
29
|
+
--------------------------------------------------------------------------------
|
30
|
+
usage: tap run -- goodnight obj
|
31
|
+
|
32
|
+
configurations:
|
33
|
+
--message MESSAGE
|
34
|
+
|
35
|
+
options:
|
36
|
+
-h, --help Print this help
|
37
|
+
--name NAME Specify a name
|
38
|
+
--use FILE Loads inputs from file
|
39
|
+
|
40
|
+
Just like that you have a command-line application with inputs, configuration, and documentation.
|
41
|
+
|
42
|
+
The declaration syntax is obviously similar to rake; configurations are new but the task-block style is the same, as are inputs. Other rake constructs are available. Here is a similar goodnight task using dependencies, rake-style.
|
43
|
+
|
44
|
+
[Tapfile]
|
45
|
+
|
46
|
+
# make the declarations available everywhere
|
47
|
+
# (normally they're accessed via Tap, as above)
|
48
|
+
extend Tap::Declarations
|
49
|
+
|
50
|
+
namespace :example do
|
51
|
+
task(:say, :message) do |task, args|
|
52
|
+
print(args.message || 'goodnight')
|
53
|
+
end
|
54
|
+
|
55
|
+
desc "your basic goodnight moon task"
|
56
|
+
task({:goodnight => :say}, :obj) do |task, args|
|
57
|
+
puts " #{args.obj}\n"
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
And now from the command line:
|
62
|
+
|
63
|
+
% rap goodnight moon
|
64
|
+
goodnight moon
|
65
|
+
|
66
|
+
% rap goodnight world --* say hello
|
67
|
+
hello world
|
68
|
+
|
69
|
+
Unlike rake, rap inputs are written out individually and tasks are delimited by a modified double-dash. Aside from that, you can see rap is basically a supercharged rake. Furthermore, rap runs rake. Directly substitute rap for rake on the command line and your tasks should run as normal (see the {Syntax Reference}[link:files/doc/Syntax%20Reference.html] for more details).
|
70
|
+
|
71
|
+
However, supercharging rake isn't the point of Tap. Declarations bridge the gap between rake and tap, but tap itself is a more general framework. To get at other features like imperative workflows, testing, and distribution, we have to go beyond rap and take a look at what declarations do.
|
72
|
+
|
73
|
+
Spoiler: declarations make subclasses of Tap::Task.
|
74
|
+
|
75
|
+
== Beyond Rap
|
76
|
+
|
77
|
+
Going back to the first example, lets take a look at how a task declaration maps to a class definition:
|
78
|
+
|
79
|
+
[Tapfile]
|
80
|
+
|
81
|
+
# ::desc your basic goodnight moon task
|
82
|
+
# Says goodnight with a configurable message.
|
83
|
+
Tap.task(:goodnight, :obj, :message => 'goodnight') do
|
84
|
+
puts "#{task.message} #{args.obj}\n"
|
85
|
+
end
|
86
|
+
|
87
|
+
Here is a corresponding class:
|
88
|
+
|
89
|
+
# Goodnight::manifest your basic goodnight moon task
|
90
|
+
# Says goodnight with a configurable message.
|
91
|
+
class Goodnight < Tap::Task
|
92
|
+
config :message, 'goodnight'
|
93
|
+
|
94
|
+
def process(obj)
|
95
|
+
"#{message} #{obj}"
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
Simple enough; the name corresponds to the class, configurations (and dependencies, although they aren't show) are written out individually, and the block corresponds to process. There are a few differences, especially relating to process, but for the moment lets gloss over them and see how Goodnight works.
|
100
|
+
|
101
|
+
Goodnight.configurations.to_hash # => {:message => 'goodnight'}
|
102
|
+
|
103
|
+
goodnight = Goodnight.new
|
104
|
+
goodnight.message # => 'goodnight'
|
105
|
+
goodnight.process('moon') # => 'goodnight moon'
|
106
|
+
|
107
|
+
hello = Goodnight.new(:message => 'hello')
|
108
|
+
hello.message # => 'hello'
|
109
|
+
hello.process('world') # => 'hello world'
|
110
|
+
|
111
|
+
Totally straightforward. Goodnight stores the default configurations, each instance has accessors to the configurations, and the defaults may be overridden during initialization, or later. Class definitions allow validation/transformation blocks to be specified for configurations. These blocks process inputs (ex the string inputs from the command line), quite literally defining the writer for a configuration accessor. A set of standard blocks are available through +c+, an alias for the Tap::Support::Validation module.
|
112
|
+
|
113
|
+
[Tapfile]
|
114
|
+
|
115
|
+
# Goodnight::manifest a fancy goodnight moon task
|
116
|
+
# Says goodnight with a configurable message.
|
117
|
+
class Goodnight < Tap::Task
|
118
|
+
config :message, 'goodnight' # a goodnight message
|
119
|
+
config :reverse, false, &c.switch # reverses the message
|
120
|
+
config :n, 1, &c.integer # repeats message n times
|
121
|
+
|
122
|
+
def process(*objects)
|
123
|
+
print "#{reverse == true ? message.reverse : message} " * n
|
124
|
+
puts objects.join(', ')
|
125
|
+
puts
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
A few examples show a validation block in action:
|
130
|
+
|
131
|
+
goodnight = Goodnight.new
|
132
|
+
|
133
|
+
goodnight.n = 10
|
134
|
+
goodnight.n # => 10
|
135
|
+
|
136
|
+
goodnight.n = "100"
|
137
|
+
goodnight.n # => 100
|
138
|
+
|
139
|
+
goodnight.n = "not an integer" # !> ValidationError
|
140
|
+
|
141
|
+
Now from the command line:
|
142
|
+
|
143
|
+
% rap goodnight moon
|
144
|
+
goodnight moon
|
145
|
+
|
146
|
+
% rap goodnight moon mittens "little toy boat"
|
147
|
+
goodnight moon, mittens, little toy boat
|
148
|
+
|
149
|
+
% rap goodnight world --message hello --reverse --n 3
|
150
|
+
olleh olleh olleh world
|
151
|
+
|
152
|
+
% rap goodnight --help
|
153
|
+
Goodnight -- a fancy goodnight moon task
|
154
|
+
--------------------------------------------------------------------------------
|
155
|
+
Says goodnight with a configurable message.
|
156
|
+
--------------------------------------------------------------------------------
|
157
|
+
usage: tap run -- goodnight OBJECTS...
|
158
|
+
|
159
|
+
configurations:
|
160
|
+
--message MESSAGE a goodnight message
|
161
|
+
--[no-]reverse reverses the message
|
162
|
+
--n N repeats message n times
|
163
|
+
|
164
|
+
options:
|
165
|
+
-h, --help Print this help
|
166
|
+
--name NAME Specify a name
|
167
|
+
--use FILE Loads inputs from file
|
168
|
+
|
169
|
+
Take a quick look at the documentation. Class definitions can also map documentation and, in some cases, metadata to the command line; the configurations now have comments and reverse is a switch! Rich mapping allows tasks to act as an script interface, not unlike {OptionParser}[http://www.ruby-doc.org/stdlib/libdoc/optparse/rdoc/classes/OptionParser.html] (surprise, tap uses OptionParser).
|
170
|
+
|
171
|
+
For example this is a stand-alone goodnight script:
|
172
|
+
|
173
|
+
[goodnight]
|
174
|
+
|
175
|
+
#!/usr/bin/env ruby
|
176
|
+
|
177
|
+
require 'rubygems'
|
178
|
+
require 'tap'
|
179
|
+
|
180
|
+
# Goodnight::manifest a goodnight moon script
|
181
|
+
# Says goodnight with a configurable message.
|
182
|
+
class Goodnight < Tap::Task
|
183
|
+
config :message, 'goodnight'
|
184
|
+
|
185
|
+
def process(obj)
|
186
|
+
puts "#{message} #{obj}\n"
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
instance, args = Goodnight.parse!(ARGV)
|
191
|
+
instance.execute(*args)
|
192
|
+
|
193
|
+
Now, from the command line:
|
194
|
+
|
195
|
+
% ./goodnight moon
|
196
|
+
goodnight moon
|
197
|
+
|
198
|
+
% ./goodnight --help
|
199
|
+
...
|
200
|
+
|
201
|
+
As simple as it is to take a task to the command line, it's nice to note that tasks may be subclassed, tested, and distributed as usual. No magic, just convenience.
|
202
|
+
|
203
|
+
== Tap
|
204
|
+
|
205
|
+
Tap comes with two executables, rap and tap. The tap executable is more verbose than rap for running tasks, but it is more configurable, scalable, and logically pure. Tap comes with a number of {commands}[link:files/doc/Command%20Reference.html] but we'll focus on generate to make, test, and package a task library. Begin by creating a tap directory structure and a task:
|
206
|
+
|
207
|
+
% tap generate root sample
|
208
|
+
% cd sample
|
209
|
+
% tap generate task goodnight
|
210
|
+
|
211
|
+
Take a look at the task files an you find something like this:
|
212
|
+
|
213
|
+
[lib/goodnight.rb]
|
214
|
+
|
215
|
+
# Goodnight::manifest <replace with manifest summary>
|
216
|
+
# <replace with command line description>
|
217
|
+
|
218
|
+
# Goodnight Documentation
|
219
|
+
class Goodnight < Tap::Task
|
220
|
+
|
221
|
+
# <config file documentation>
|
222
|
+
config :message, 'goodnight' # a sample config
|
223
|
+
|
224
|
+
def process(name)
|
225
|
+
log message, name
|
226
|
+
"#{message} #{name}"
|
227
|
+
end
|
228
|
+
end
|
229
|
+
|
230
|
+
[test/goodnight_test.rb]
|
231
|
+
|
232
|
+
require File.join(File.dirname(__FILE__), 'tap_test_helper.rb')
|
233
|
+
require 'goodnight'
|
234
|
+
|
235
|
+
class GoodnightTest < Test::Unit::TestCase
|
236
|
+
acts_as_tap_test
|
237
|
+
|
238
|
+
def test_goodnight
|
239
|
+
task = Goodnight.new :message => "goodnight"
|
240
|
+
|
241
|
+
# a simple test
|
242
|
+
assert_equal({:message => 'goodnight'}, task.config)
|
243
|
+
assert_equal "goodnight moon", task.process("moon")
|
244
|
+
|
245
|
+
# a more complex test
|
246
|
+
task.enq("moon")
|
247
|
+
app.run
|
248
|
+
|
249
|
+
assert_equal ["goodnight moon"], app.results(task)
|
250
|
+
assert_audit_equal ExpAudit[[nil, "moon"], [task, "goodnight moon"]], app._results(task)[0]
|
251
|
+
end
|
252
|
+
end
|
253
|
+
|
254
|
+
Run the test:
|
255
|
+
|
256
|
+
% rap test
|
257
|
+
|
258
|
+
Run the task:
|
259
|
+
|
260
|
+
% rap goodnight moon
|
261
|
+
I[23:22:19] goodnight moon
|
262
|
+
|
263
|
+
Ok, lets share it. Print the current gemspec manifest:
|
264
|
+
|
265
|
+
% rap print_manifest
|
266
|
+
true README
|
267
|
+
Rakefile
|
268
|
+
lib/goodnight.rb
|
269
|
+
sample.gemspec
|
270
|
+
true tap.yml
|
271
|
+
test/goodnight_test.rb
|
272
|
+
true test/tap_test_helper.rb
|
273
|
+
true test/tap_test_suite.rb
|
274
|
+
|
275
|
+
As you can see, this needs an update to include the task file. Open up sample.gemspec and fix the manifest.
|
276
|
+
|
277
|
+
[sample.gemspec]
|
278
|
+
|
279
|
+
Gem::Specification.new do |s|
|
280
|
+
s.name = "sample"
|
281
|
+
s.version = "0.0.1"
|
282
|
+
s.platform = Gem::Platform::RUBY
|
283
|
+
s.summary = "sample"
|
284
|
+
s.require_path = "lib"
|
285
|
+
s.add_dependency("tap", ">= 0.11")
|
286
|
+
s.files = %W{
|
287
|
+
lib/goodnight.rb
|
288
|
+
tap.yml
|
289
|
+
}
|
290
|
+
end
|
291
|
+
|
292
|
+
Now package the gem and install it (gem may require sudo):
|
293
|
+
|
294
|
+
% rap gem
|
295
|
+
% gem install pkg/sample-0.0.1.gem
|
296
|
+
|
297
|
+
Now you can say goodnight anywhere, using 'tap run' or rap:
|
298
|
+
|
299
|
+
% cd ~/Desktop
|
300
|
+
% tap run -- goodnight moon
|
301
|
+
goodnight moon
|
302
|
+
% rap goodnight opus
|
303
|
+
goodnight opus
|
304
|
+
|
305
|
+
And that is that.
|