tap-gen 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/History +4 -0
- data/MIT-LICENSE +22 -0
- data/README +57 -0
- data/cmd/destroy.rb +21 -0
- data/cmd/generate.rb +21 -0
- data/lib/tap/generator/arguments.rb +13 -0
- data/lib/tap/generator/base.rb +180 -0
- data/lib/tap/generator/destroy.rb +60 -0
- data/lib/tap/generator/exe.rb +27 -0
- data/lib/tap/generator/generate.rb +93 -0
- data/lib/tap/generator/generators/command.rb +19 -0
- data/lib/tap/generator/generators/config.rb +118 -0
- data/lib/tap/generator/generators/generator.rb +28 -0
- data/lib/tap/generator/generators/root.rb +96 -0
- data/lib/tap/generator/generators/task.rb +27 -0
- data/lib/tap/generator/manifest.rb +20 -0
- data/lib/tap/generator/preview.rb +69 -0
- data/tap.yml +0 -0
- data/templates/tap/generator/generators/command/command.erb +31 -0
- data/templates/tap/generator/generators/generator/task.erb +29 -0
- data/templates/tap/generator/generators/generator/test.erb +26 -0
- data/templates/tap/generator/generators/root/MIT-LICENSE +22 -0
- data/templates/tap/generator/generators/root/README +14 -0
- data/templates/tap/generator/generators/root/Rakefile +85 -0
- data/templates/tap/generator/generators/root/Rapfile +11 -0
- data/templates/tap/generator/generators/root/gemspec +28 -0
- data/templates/tap/generator/generators/root/test/tap_test_helper.rb +1 -0
- data/templates/tap/generator/generators/task/task.erb +16 -0
- data/templates/tap/generator/generators/task/test.erb +14 -0
- metadata +97 -0
data/History
ADDED
data/MIT-LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2009, Regents of the University of Colorado.
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person
|
4
|
+
obtaining a copy of this software and associated documentation
|
5
|
+
files (the "Software"), to deal in the Software without
|
6
|
+
restriction, including without limitation the rights to use,
|
7
|
+
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
8
|
+
copies of the Software, and to permit persons to whom the
|
9
|
+
Software is furnished to do so, subject to the following
|
10
|
+
conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be
|
13
|
+
included in all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
16
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
17
|
+
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
18
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
19
|
+
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
20
|
+
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
21
|
+
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
22
|
+
OTHER DEALINGS IN THE SOFTWARE.
|
data/README
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
= {Tap Generator}[http://tap.rubyforge.org/tap-gen]
|
2
|
+
|
3
|
+
gen.er.a.tor n. a thing that generates something
|
4
|
+
|
5
|
+
Generators for Tap.
|
6
|
+
|
7
|
+
== Description
|
8
|
+
|
9
|
+
Provides generators for Tap. Generators are subclasses of Task are therefore
|
10
|
+
easy to configure, subclass, and distribute.
|
11
|
+
{Tap-Generator}[http://tap.rubyforge.org/tap-gen] is a part of the
|
12
|
+
{Tap-Suite}[http://tap.rubyforge.org/tap-suite]. Check out these links for
|
13
|
+
documentation, development, and bug tracking.
|
14
|
+
|
15
|
+
* Website[http://tap.rubyforge.org]
|
16
|
+
* Lighthouse[http://bahuvrihi.lighthouseapp.com/projects/9908-tap-task-application/tickets]
|
17
|
+
* Github[http://github.com/bahuvrihi/tap/tree/master]
|
18
|
+
* {Google Group}[http://groups.google.com/group/ruby-on-tap]
|
19
|
+
|
20
|
+
== Usage
|
21
|
+
|
22
|
+
Get started:
|
23
|
+
|
24
|
+
% tap generate root sample
|
25
|
+
% cd sample
|
26
|
+
% tap generate task goodnight
|
27
|
+
% tap run -- goodnight moon
|
28
|
+
|
29
|
+
Get some help:
|
30
|
+
|
31
|
+
% tap generate --help
|
32
|
+
% tap generate task --help
|
33
|
+
|
34
|
+
Roll your own:
|
35
|
+
|
36
|
+
% tap generate generator thing
|
37
|
+
|
38
|
+
Roll it back:
|
39
|
+
|
40
|
+
% tap destroy generator thing
|
41
|
+
% tap destroy task goodnight
|
42
|
+
% cd ..
|
43
|
+
% tap destroy root sample
|
44
|
+
|
45
|
+
== Installation
|
46
|
+
|
47
|
+
Tap-Generator is available as a gem on
|
48
|
+
RubyForge[http://rubyforge.org/projects/tap]. Use:
|
49
|
+
|
50
|
+
% gem install tap-gen
|
51
|
+
|
52
|
+
== Info
|
53
|
+
|
54
|
+
Copyright (c) 2009, Regents of the University of Colorado.
|
55
|
+
Developer:: {Simon Chiang}[http://bahuvrihi.wordpress.com], {Biomolecular Structure Program}[http://biomol.uchsc.edu/], {Hansen Lab}[http://hsc-proteomics.uchsc.edu/hansenlab/]
|
56
|
+
Support:: CU Denver School of Medicine Deans Academic Enrichment Fund
|
57
|
+
License:: {MIT-Style}[link:files/MIT-LICENSE.html]
|
data/cmd/destroy.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
# usage: tap destroy GENERATOR ...
|
2
|
+
#
|
3
|
+
# Runs a generator in reverse. Each generator works a little differently; the
|
4
|
+
# best way to figure out what a generator does is to use --help. For example:
|
5
|
+
#
|
6
|
+
# % tap generate root --help
|
7
|
+
#
|
8
|
+
|
9
|
+
require 'tap/generator/exe'
|
10
|
+
require 'tap/generator/destroy'
|
11
|
+
|
12
|
+
env = Tap::Env.instance
|
13
|
+
env.extend Tap::Generator::Exe
|
14
|
+
|
15
|
+
env.run(Tap::Generator::Destroy, ARGV) do
|
16
|
+
puts Lazydoc.usage(__FILE__)
|
17
|
+
puts
|
18
|
+
puts "generators:"
|
19
|
+
puts env.manifest('generator').summarize
|
20
|
+
exit(1)
|
21
|
+
end
|
data/cmd/generate.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
# usage: tap generate GENERATOR ...
|
2
|
+
#
|
3
|
+
# Runs a generator. Each generator works a little differently; the best way to
|
4
|
+
# figure out what a generator does is to use --help. For example:
|
5
|
+
#
|
6
|
+
# % tap generate root --help
|
7
|
+
#
|
8
|
+
|
9
|
+
require 'tap/generator/exe'
|
10
|
+
require 'tap/generator/generate'
|
11
|
+
|
12
|
+
env = Tap::Env.instance
|
13
|
+
env.extend Tap::Generator::Exe
|
14
|
+
|
15
|
+
env.run(Tap::Generator::Generate, ARGV) do
|
16
|
+
puts Lazydoc.usage(__FILE__)
|
17
|
+
puts
|
18
|
+
puts "generators:"
|
19
|
+
puts env.manifest('generator').summarize
|
20
|
+
exit(1)
|
21
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module Tap
|
2
|
+
module Generator
|
3
|
+
|
4
|
+
# A special type of Lazydoc::Arguments that shifts off the standard 'm'
|
5
|
+
# argument on generator manifest methods, to properly reflect how may
|
6
|
+
# arguments the generator should receive.
|
7
|
+
class Arguments < Lazydoc::Arguments
|
8
|
+
def arguments(shift_manifest_arg=true)
|
9
|
+
shift_manifest_arg ? @arguments[1..-1] : @arguments
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,180 @@
|
|
1
|
+
require 'tap'
|
2
|
+
require 'tap/generator/manifest'
|
3
|
+
require 'tap/generator/arguments'
|
4
|
+
|
5
|
+
module Tap
|
6
|
+
module Generator
|
7
|
+
|
8
|
+
# :startdoc:::-
|
9
|
+
# Base provides the basic structure of a generator and custom generators
|
10
|
+
# inherit from it. Base is patterned after the {Ruby on Rails}[http://rubyonrails.org/]
|
11
|
+
# generators, but obviously takes on all the advantages of Tasks.
|
12
|
+
#
|
13
|
+
# === Usage
|
14
|
+
#
|
15
|
+
# Tap generators define a manifest method that defines what files and
|
16
|
+
# directories are created by the generator. Then, at execution time,
|
17
|
+
# a mixin with the appropriate funtion (ie Generate or Destroy) is
|
18
|
+
# overlaid to figure out how to roll those actions forward or backwards.
|
19
|
+
#
|
20
|
+
# Generators are identified using the ::generator flag rather than ::task,
|
21
|
+
# so that generators are available to the generate/destroy commands and
|
22
|
+
# not run.
|
23
|
+
#
|
24
|
+
# Typically, generators live in a directory structure like this:
|
25
|
+
#
|
26
|
+
# root
|
27
|
+
# |- lib
|
28
|
+
# | `- sample.rb
|
29
|
+
# |
|
30
|
+
# `- templates
|
31
|
+
# `- sample
|
32
|
+
# `- template_file.erb
|
33
|
+
#
|
34
|
+
# Tap generators keep templates out of lib and under templates, in a
|
35
|
+
# directory is named after the generator class. Generators themselves
|
36
|
+
# take the form:
|
37
|
+
#
|
38
|
+
# [sample.rb]
|
39
|
+
# require 'tap/generator/base'
|
40
|
+
#
|
41
|
+
# # ::generator generates a directory, and two files
|
42
|
+
# #
|
43
|
+
# # An extended description of the
|
44
|
+
# # generator goes here...
|
45
|
+
# #
|
46
|
+
# class Sample < Tap::Generator::Base
|
47
|
+
#
|
48
|
+
# config :key, 'value' # a sample config
|
49
|
+
#
|
50
|
+
# def manifest(m, *args)
|
51
|
+
# # make a directory
|
52
|
+
# m.directory('path/to/dir')
|
53
|
+
#
|
54
|
+
# # make a file
|
55
|
+
# m.file('path/to/file.txt') do |file|
|
56
|
+
# file << "some content"
|
57
|
+
# end
|
58
|
+
#
|
59
|
+
# # template a file
|
60
|
+
# m.template('path/to/result.txt', 'template_file.erb', config.to_hash)
|
61
|
+
# end
|
62
|
+
# end
|
63
|
+
#
|
64
|
+
# The arguments that a generator receives are specified by manifest (minus
|
65
|
+
# the 'm' argument which is standard) rather than process. Creating
|
66
|
+
# directories and files is straightforward, as above. Template renders the
|
67
|
+
# erb source file using attributes specified in the last argument; in the
|
68
|
+
# example template uses the generator configurations.
|
69
|
+
#
|
70
|
+
# :startdoc:::+
|
71
|
+
class Base < Tap::Task
|
72
|
+
lazy_attr :manifest, 'generator'
|
73
|
+
lazy_attr :args, :manifest
|
74
|
+
lazy_register :manifest, Arguments
|
75
|
+
|
76
|
+
config :destination_root, Dir.pwd # The destination root directory
|
77
|
+
config :pretend, false, &c.flag # Run but rollback any changes.
|
78
|
+
config :force, false, &c.flag # Overwrite files that already exist.
|
79
|
+
config :skip, false, &c.flag # Skip files that already exist.
|
80
|
+
|
81
|
+
# The generator-specific templates directory. By default:
|
82
|
+
# 'templates/path/to/name' for 'lib/path/to/name.rb'
|
83
|
+
attr_accessor :template_dir
|
84
|
+
|
85
|
+
# The IO used to pull prompt inputs (default: $stdin)
|
86
|
+
attr_accessor :prompt_in
|
87
|
+
|
88
|
+
# The IO used to prompt users for input (default: $stdout)
|
89
|
+
attr_accessor :prompt_out
|
90
|
+
|
91
|
+
def initialize(config={}, app=Tap::App.instance)
|
92
|
+
super
|
93
|
+
@prompt_in = $stdin
|
94
|
+
@prompt_out = $stdout
|
95
|
+
@template_dir = File.expand_path("templates/#{self.class.to_s.underscore}")
|
96
|
+
end
|
97
|
+
|
98
|
+
# Builds the manifest, then executes the actions of the manifest.
|
99
|
+
# Process returns the results of iterate, which normally will be
|
100
|
+
# an array of files and directories created (or destroyed) by self.
|
101
|
+
def process(*argv)
|
102
|
+
actions = []
|
103
|
+
manifest(Manifest.new(actions), *argv)
|
104
|
+
|
105
|
+
iterate(actions) do |action, args, block|
|
106
|
+
send(action, *args, &block)
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
# Overridden in subclasses to add actions to the input Manifest.
|
111
|
+
# Any arguments passed to process will be passed to manifest
|
112
|
+
# unchanged.
|
113
|
+
def manifest(m, *argv)
|
114
|
+
raise NotImplementedError
|
115
|
+
end
|
116
|
+
|
117
|
+
# Peforms each of the input actions in order, and collects the
|
118
|
+
# results. The process method returns these results.
|
119
|
+
def iterate(actions)
|
120
|
+
actions.collect {|action| yield(action) }
|
121
|
+
end
|
122
|
+
|
123
|
+
# Constructs a path relative to destination_root.
|
124
|
+
def path(*paths)
|
125
|
+
File.expand_path(File.join(*paths), destination_root)
|
126
|
+
end
|
127
|
+
|
128
|
+
# Peforms a directory action (ex generate or destroy). Must be
|
129
|
+
# overridden by one of the action mixins (ex Generate or Destroy).
|
130
|
+
def directory(target, options={})
|
131
|
+
raise NotImplementedError
|
132
|
+
end
|
133
|
+
|
134
|
+
# Peforms a file action (ex generate or destroy). Calls to file specify
|
135
|
+
# input for a target by providing a block; the block recieves an IO and
|
136
|
+
# pushes content to it. Must be overridden by one of the action mixins
|
137
|
+
# (ex Generate or Destroy).
|
138
|
+
def file(target, options={}) # :yields: io
|
139
|
+
raise NotImplementedError
|
140
|
+
end
|
141
|
+
|
142
|
+
# Makes (or destroys) the root and each of the targets, relative
|
143
|
+
# to root. Options are passed onto directory.
|
144
|
+
def directories(root, targets, options={})
|
145
|
+
directory(root, options)
|
146
|
+
targets.each do |target|
|
147
|
+
directory(File.join(root, target), options)
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
# Makes (or destroys) the target by templating the source using
|
152
|
+
# the specified attributes. Source is expanded relative to
|
153
|
+
# template_dir. Options are passed onto file.
|
154
|
+
def template(target, source, attributes={}, options={})
|
155
|
+
template_path = File.expand_path(source, template_dir)
|
156
|
+
templater = Support::Templater.new(File.read(template_path), attributes)
|
157
|
+
|
158
|
+
file(target, options) do |file|
|
159
|
+
file << templater.build
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
# Yields each source file under template_dir to the block, with
|
164
|
+
# a target path of the source relative to template_dir.
|
165
|
+
def template_files
|
166
|
+
Dir.glob(template_dir + "/**/*").sort.each do |source|
|
167
|
+
next unless File.file?(source)
|
168
|
+
|
169
|
+
target = Tap::Root::Utils.relative_path(template_dir, source)
|
170
|
+
yield(source, target)
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
# Logs the action with the relative filepath from Dir.pwd to path.
|
175
|
+
def log_relative(action, path)
|
176
|
+
log(action, Tap::Root::Utils.relative_path(Dir.pwd, path))
|
177
|
+
end
|
178
|
+
end
|
179
|
+
end
|
180
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
module Tap
|
2
|
+
module Generator
|
3
|
+
|
4
|
+
# A mixin defining how to run manifest actions in reverse.
|
5
|
+
module Destroy
|
6
|
+
|
7
|
+
# Iterates over the actions in reverse, and collects the results.
|
8
|
+
def iterate(actions)
|
9
|
+
results = []
|
10
|
+
actions.reverse_each {|action| results << yield(action) }
|
11
|
+
results
|
12
|
+
end
|
13
|
+
|
14
|
+
# Removes the target directory if it exists. Missing, non-directory and
|
15
|
+
# non-empty targets are simply logged and not removed. When pretend is
|
16
|
+
# true, removal is logged but does not actually happen.
|
17
|
+
#
|
18
|
+
# No options currently affect the behavior of this method.
|
19
|
+
def directory(target, options={})
|
20
|
+
target = File.expand_path(target)
|
21
|
+
|
22
|
+
case
|
23
|
+
when !File.exists?(target)
|
24
|
+
log_relative :missing, target
|
25
|
+
when !File.directory?(target)
|
26
|
+
log_relative 'not a directory', target
|
27
|
+
when !Root::Utils.empty?(target)
|
28
|
+
log_relative 'not empty', target
|
29
|
+
else
|
30
|
+
log_relative :rm, target
|
31
|
+
FileUtils.rmdir(target) unless pretend
|
32
|
+
end
|
33
|
+
|
34
|
+
target
|
35
|
+
end
|
36
|
+
|
37
|
+
# Removes the target file if it exists. Missing and non-file and targets
|
38
|
+
# are simply logged and not removed. When pretend is true, removal is
|
39
|
+
# logged but does not actually happen.
|
40
|
+
#
|
41
|
+
# No options currently affect the behavior of this method.
|
42
|
+
def file(target, options={})
|
43
|
+
target = File.expand_path(target)
|
44
|
+
|
45
|
+
case
|
46
|
+
when File.file?(target)
|
47
|
+
log_relative :rm, target
|
48
|
+
FileUtils.rm(target) unless pretend
|
49
|
+
when File.directory?(target)
|
50
|
+
log_relative 'not a file', target
|
51
|
+
else
|
52
|
+
log_relative :missing, target
|
53
|
+
end
|
54
|
+
|
55
|
+
target
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'tap/generator/base'
|
2
|
+
|
3
|
+
module Tap
|
4
|
+
module Generator
|
5
|
+
|
6
|
+
# Methods used by the generate and destroy commands.
|
7
|
+
module Exe
|
8
|
+
|
9
|
+
def run(mod, argv=ARGV)
|
10
|
+
if argv.empty? || argv == ['--help']
|
11
|
+
yield
|
12
|
+
end
|
13
|
+
|
14
|
+
name = argv.shift
|
15
|
+
env, const = eeek('generator', name)
|
16
|
+
|
17
|
+
unless const
|
18
|
+
raise "unknown generator: #{name}"
|
19
|
+
end
|
20
|
+
|
21
|
+
generator, argv = const.constantize.parse(argv)
|
22
|
+
generator.template_dir = env.class_path(:templates, generator) {|dir| File.directory?(dir) }
|
23
|
+
generator.extend(mod).process(*argv)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,93 @@
|
|
1
|
+
autoload(:Tempfile, 'tempfile')
|
2
|
+
|
3
|
+
module Tap
|
4
|
+
module Generator
|
5
|
+
|
6
|
+
# A mixin defining how to run manifest actions.
|
7
|
+
module Generate
|
8
|
+
|
9
|
+
# Creates the target directory if it doesn't exist. When pretend is
|
10
|
+
# true, creation is logged but does not actually happen.
|
11
|
+
#
|
12
|
+
# No options currently affect the behavior of this method.
|
13
|
+
def directory(target, options={})
|
14
|
+
target = File.expand_path(target)
|
15
|
+
|
16
|
+
case
|
17
|
+
when File.exists?(target)
|
18
|
+
log_relative :exists, target
|
19
|
+
else
|
20
|
+
log_relative :create, target
|
21
|
+
FileUtils.mkdir_p(target) unless pretend
|
22
|
+
end
|
23
|
+
|
24
|
+
target
|
25
|
+
end
|
26
|
+
|
27
|
+
# Creates the target file; content may be added to the file by providing
|
28
|
+
# block. If the target file already exists, the new and existing content
|
29
|
+
# is compared and the user will be prompted for how to handle collisions.
|
30
|
+
# All activity is logged. When pretend is true, creation is logged but
|
31
|
+
# does not actually happen.
|
32
|
+
#
|
33
|
+
# No options currently affect the behavior of this method.
|
34
|
+
def file(target, options={})
|
35
|
+
source_file = Tempfile.new('generate')
|
36
|
+
yield(source_file) if block_given?
|
37
|
+
source_file.close
|
38
|
+
|
39
|
+
source = source_file.path
|
40
|
+
target = File.expand_path(target)
|
41
|
+
|
42
|
+
copy_file = true
|
43
|
+
msg = case
|
44
|
+
when !File.exists?(target)
|
45
|
+
:create
|
46
|
+
when FileUtils.cmp(source, target)
|
47
|
+
:exists
|
48
|
+
when force_file_collision?(target)
|
49
|
+
:force
|
50
|
+
else
|
51
|
+
copy_file = false
|
52
|
+
:skip
|
53
|
+
end
|
54
|
+
|
55
|
+
log_relative msg, target
|
56
|
+
if copy_file && !pretend
|
57
|
+
dir = File.dirname(target)
|
58
|
+
FileUtils.mkdir_p(dir) unless File.exists?(dir)
|
59
|
+
FileUtils.mv(source, target, :force => true)
|
60
|
+
end
|
61
|
+
|
62
|
+
target
|
63
|
+
end
|
64
|
+
|
65
|
+
protected
|
66
|
+
|
67
|
+
# Ask the user interactively whether to force collision.
|
68
|
+
def force_file_collision?(target)
|
69
|
+
return false if skip
|
70
|
+
return true if force
|
71
|
+
|
72
|
+
prompt_out.print "overwrite #{target}? [Ynaiq] "
|
73
|
+
prompt_out.flush
|
74
|
+
case prompt_in.gets.strip
|
75
|
+
when /^y(es)?$/i
|
76
|
+
true
|
77
|
+
when /^n(o)?$/i
|
78
|
+
false
|
79
|
+
when /^a(ll)?$/i
|
80
|
+
self.force = true
|
81
|
+
true
|
82
|
+
when /^i(gnore)?$/i
|
83
|
+
self.skip = true
|
84
|
+
false
|
85
|
+
when /^q(uit)?$/i
|
86
|
+
prompt_out.puts "aborting"
|
87
|
+
raise SystemExit
|
88
|
+
else force_file_collision?(target)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Tap::Generator::Generators
|
2
|
+
|
3
|
+
# :startdoc::generator a new tap command
|
4
|
+
#
|
5
|
+
# Generates a new tap command under the cmd directory. The
|
6
|
+
# new command can be run from the command line using:
|
7
|
+
#
|
8
|
+
# % tap <command>
|
9
|
+
#
|
10
|
+
class Command < Tap::Generator::Base
|
11
|
+
def manifest(m, command_name)
|
12
|
+
m.directory path('cmd')
|
13
|
+
|
14
|
+
template_files do |source, target|
|
15
|
+
m.template path('cmd', "#{command_name}.rb"), source, :command_name => command_name
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,118 @@
|
|
1
|
+
module Tap::Generator::Generators
|
2
|
+
|
3
|
+
# :startdoc::generator a config file generator
|
4
|
+
#
|
5
|
+
# Generates a new config file for a task. The configurations, defaults,
|
6
|
+
# and documentation is determined from the source file.
|
7
|
+
#
|
8
|
+
# Configurations for other types of configurable resources may also be
|
9
|
+
# generated. Specify the constant attribute identifying the resource
|
10
|
+
# using the 'resource' flag. This generates a config file for the Root
|
11
|
+
# generator:
|
12
|
+
#
|
13
|
+
# % tap generate config root --resource generator
|
14
|
+
#
|
15
|
+
class Config < Tap::Generator::Base
|
16
|
+
|
17
|
+
dump_delegates = lambda do |leader, delegate, block|
|
18
|
+
nested_delegates = delegate.default(false).delegates
|
19
|
+
indented_dump = Configurable::Utils.dump(nested_delegates, &block).gsub(/^/, " ")
|
20
|
+
"#{leader}: \n#{indented_dump}"
|
21
|
+
end
|
22
|
+
|
23
|
+
doc_format = lambda do |key, delegate|
|
24
|
+
# get the description
|
25
|
+
desc = delegate.attributes[:desc]
|
26
|
+
doc = desc.to_s
|
27
|
+
doc = desc.comment if doc.empty?
|
28
|
+
|
29
|
+
# wrap as lines
|
30
|
+
lines = Lazydoc::Utils.wrap(doc, 50).collect {|line| "# #{line}"}
|
31
|
+
lines << "" unless lines.empty?
|
32
|
+
|
33
|
+
if delegate.is_nest?
|
34
|
+
leader = "#{lines.join("\n")}#{key}"
|
35
|
+
DUMP_DELEGATES[leader, delegate, DOC_FORMAT]
|
36
|
+
else
|
37
|
+
default = delegate.default
|
38
|
+
|
39
|
+
# setup formatting
|
40
|
+
leader = default == nil ? '# ' : ''
|
41
|
+
config = YAML.dump({key => default})[5..-1]
|
42
|
+
"#{lines.join("\n")}#{leader}#{config.strip}\n\n"
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
nodoc_format = lambda do |key, delegate|
|
47
|
+
if delegate.is_nest?
|
48
|
+
DUMP_DELEGATES[key, delegate, NODOC_FORMAT]
|
49
|
+
else
|
50
|
+
default = delegate.default
|
51
|
+
|
52
|
+
# setup formatting
|
53
|
+
leader = default == nil ? '# ' : ''
|
54
|
+
config = YAML.dump({key => default})[5..-1]
|
55
|
+
"#{leader}#{config.strip}\n"
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
# Dumps a nested configuration.
|
60
|
+
DUMP_DELEGATES = dump_delegates
|
61
|
+
|
62
|
+
# Dumps configurations as YAML with documentation,
|
63
|
+
# used when the doc config is true.
|
64
|
+
DOC_FORMAT = doc_format
|
65
|
+
|
66
|
+
# Dumps configurations as YAML without documentation,
|
67
|
+
# used when the doc config is false.
|
68
|
+
NODOC_FORMAT = nodoc_format
|
69
|
+
|
70
|
+
config :doc, true, &c.switch # include documentation in the config
|
71
|
+
config :nest, false, &c.switch # generate nested config files
|
72
|
+
config :blanks, true, &c.switch # allow generation of empty config files
|
73
|
+
config :resource, 'task' # specify the resource type
|
74
|
+
|
75
|
+
# Lookup the named resource class. Lookup happens through the active Env
|
76
|
+
# instance, specifically using:
|
77
|
+
#
|
78
|
+
# Env.instance.constant_manifest(resource)[name]
|
79
|
+
#
|
80
|
+
# Raises an error if the name cannot be resolved to a resource.
|
81
|
+
def lookup(name)
|
82
|
+
env = Tap::Env.instance
|
83
|
+
env.constant_manifest(resource)[name] or raise "unknown #{resource}: #{name}"
|
84
|
+
end
|
85
|
+
|
86
|
+
def manifest(m, name, config_name=nil)
|
87
|
+
# setup
|
88
|
+
tasc = lookup(name)
|
89
|
+
config_name ||= tasc.to_s.underscore
|
90
|
+
config_file = path('config', config_name)
|
91
|
+
config_file += ".yml" if File.extname(config_file).empty?
|
92
|
+
|
93
|
+
# generate the dumps
|
94
|
+
dumps = Configurable::Utils.dump_file(
|
95
|
+
tasc.configurations,
|
96
|
+
config_file,
|
97
|
+
nest,
|
98
|
+
true,
|
99
|
+
&format_block)
|
100
|
+
|
101
|
+
# now put the dumps to the manifest
|
102
|
+
m.directory(path('config'))
|
103
|
+
|
104
|
+
dumps.each do |path, content|
|
105
|
+
next if content.empty? && !blanks
|
106
|
+
m.file(path) do |file|
|
107
|
+
file << content
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
# A hook to set a formatting block. By default format_blocks
|
113
|
+
# returns DOC_FORMAT or NODOC_FORMAT as per the doc config.
|
114
|
+
def format_block
|
115
|
+
doc ? DOC_FORMAT : NODOC_FORMAT
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'tap/generator/generators/task'
|
2
|
+
|
3
|
+
module Tap::Generator::Generators
|
4
|
+
|
5
|
+
# :startdoc::generator a generator task and test
|
6
|
+
#
|
7
|
+
# Generates a new generator.
|
8
|
+
class Generator < Tap::Generator::Generators::Task
|
9
|
+
|
10
|
+
config :test, true, &c.switch # specifies creation of a test file
|
11
|
+
|
12
|
+
def manifest(m, const_name)
|
13
|
+
super
|
14
|
+
|
15
|
+
const = Tap::Env::Constant.new(const_name.camelize)
|
16
|
+
|
17
|
+
# make the templates directory
|
18
|
+
m.directory path('templates', const.path)
|
19
|
+
|
20
|
+
# make a template file
|
21
|
+
# (note it's easier to do this as a file since erb is
|
22
|
+
# added, and would have to be escaped in a template)
|
23
|
+
m.file path('templates', const.path, 'template_file.erb') do |file|
|
24
|
+
file << "# A sample template file.\nkey: <%= key %>\n"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
require 'tap/generator/base'
|
2
|
+
require 'tap/constants'
|
3
|
+
|
4
|
+
module Tap::Generator::Generators
|
5
|
+
|
6
|
+
# :startdoc::generator a basic tap directory structure
|
7
|
+
#
|
8
|
+
# Generates a tap root directory structure. Use the switches to turn on or
|
9
|
+
# off the creation of various files:
|
10
|
+
#
|
11
|
+
# project
|
12
|
+
# |- MIT-LICENSE
|
13
|
+
# |- README
|
14
|
+
# |- Rakefile
|
15
|
+
# |- lib
|
16
|
+
# |- project.gemspec
|
17
|
+
# |- tap.yml
|
18
|
+
# `- test
|
19
|
+
# `- tap_test_helper.rb
|
20
|
+
#
|
21
|
+
class Root < Tap::Generator::Base
|
22
|
+
|
23
|
+
nest :gemspec do
|
24
|
+
config :name, "Your Name Here" # Author name
|
25
|
+
config :email, "your.email@pubfactory.edu" # Author email
|
26
|
+
config :homepage, "" # The project hompage
|
27
|
+
config :rubyforge_project, "" # The rubyforge project name
|
28
|
+
config :summary, "" # The project summary
|
29
|
+
end
|
30
|
+
|
31
|
+
config :env, false, &c.switch # Create a full tap.yml file
|
32
|
+
config :license, true, &c.switch # Create an MIT-LICENSE
|
33
|
+
config :history, true, &c.switch # Create History file
|
34
|
+
config :rapfile, false, &c.switch # Create a Rapfile
|
35
|
+
config :rakefile, true, &c.switch # Create a Rakefile
|
36
|
+
|
37
|
+
# ::args ROOT, PROJECT_NAME=basename(ROOT)
|
38
|
+
def manifest(m, root, project_name=nil)
|
39
|
+
r = Tap::Root.new(root)
|
40
|
+
project_name = File.basename(r.root) if project_name == nil
|
41
|
+
|
42
|
+
m.directory r.root
|
43
|
+
m.directory r['lib']
|
44
|
+
m.directory r['test']
|
45
|
+
|
46
|
+
template_files do |source, target|
|
47
|
+
case
|
48
|
+
when File.directory?(source)
|
49
|
+
m.directory r[target]
|
50
|
+
next
|
51
|
+
when source =~ /gemspec$/
|
52
|
+
locals = gemspec.config.to_hash.merge(
|
53
|
+
:project_name => project_name,
|
54
|
+
:license => license,
|
55
|
+
:history => history
|
56
|
+
)
|
57
|
+
m.template r[project_name + '.gemspec'], source, locals
|
58
|
+
next
|
59
|
+
when source =~ /Rakefile$/
|
60
|
+
next unless rakefile
|
61
|
+
when source =~ /Rapfile$/
|
62
|
+
next unless rapfile
|
63
|
+
when source =~ /MIT-LICENSE$/
|
64
|
+
next unless license
|
65
|
+
end
|
66
|
+
|
67
|
+
m.template r[target], source, :project_name => project_name, :license => license
|
68
|
+
end
|
69
|
+
|
70
|
+
m.file(r['History']) if history
|
71
|
+
m.file(r['tap.yml']) do |file|
|
72
|
+
Configurable::Utils.dump(Tap::Env.configurations, file) do |key, delegate|
|
73
|
+
default = delegate.default(false)
|
74
|
+
|
75
|
+
# get the description
|
76
|
+
desc = delegate.attributes[:desc]
|
77
|
+
doc = desc.to_s
|
78
|
+
doc = desc.comment if doc.empty?
|
79
|
+
|
80
|
+
# wrap as lines
|
81
|
+
lines = Lazydoc::Utils.wrap(doc, 78).collect {|line| "# #{line}"}
|
82
|
+
lines << "" unless lines.empty?
|
83
|
+
|
84
|
+
# note: this causes order to be lost...
|
85
|
+
default = default.to_hash if delegate.is_nest?
|
86
|
+
|
87
|
+
# setup formatting
|
88
|
+
leader = key == 'root' || default == nil ? '# ' : ''
|
89
|
+
config = YAML.dump({key => default})[5..-1].strip.gsub(/\n+/, "\n#{leader}")
|
90
|
+
"#{lines.join("\n")}#{leader}#{config}\n\n"
|
91
|
+
end if env
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
end
|
96
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'tap/env'
|
2
|
+
|
3
|
+
module Tap::Generator::Generators
|
4
|
+
|
5
|
+
# :startdoc::generator a task and test
|
6
|
+
#
|
7
|
+
# Generates a new Tap::Task and an associated test file.
|
8
|
+
class Task < Tap::Generator::Base
|
9
|
+
|
10
|
+
config :test, true, &c.switch # specifies creation of a test file
|
11
|
+
|
12
|
+
def manifest(m, const_name)
|
13
|
+
const = Tap::Env::Constant.new(const_name.camelize)
|
14
|
+
|
15
|
+
task_path = path('lib', "#{const.path}.rb")
|
16
|
+
m.directory File.dirname(task_path)
|
17
|
+
m.template task_path, "task.erb", :const => const
|
18
|
+
|
19
|
+
if test
|
20
|
+
test_path = path('test', "#{const.path}_test.rb")
|
21
|
+
m.directory File.dirname(test_path)
|
22
|
+
m.template test_path, "test.erb", :const => const
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Tap
|
2
|
+
module Generator
|
3
|
+
|
4
|
+
# Manifest records methods called upon it using method_missing. These
|
5
|
+
# actions are replayed on a generator in order (for generate) or in
|
6
|
+
# reverse order (for destroy).
|
7
|
+
class Manifest
|
8
|
+
|
9
|
+
# Makes a new Manifest. Method calls on self are recorded to actions.
|
10
|
+
def initialize(actions)
|
11
|
+
@actions = actions
|
12
|
+
end
|
13
|
+
|
14
|
+
# Records an action.
|
15
|
+
def method_missing(action, *args, &block)
|
16
|
+
@actions << [action, args, block]
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
require 'stringio'
|
2
|
+
|
3
|
+
module Tap
|
4
|
+
module Generator
|
5
|
+
|
6
|
+
# Preview is a testing module designed so that process will return an array
|
7
|
+
# of relative paths for the created files/directories (which are easy
|
8
|
+
# to specify in a test). Preview also collects the content of created files
|
9
|
+
# to be tested as needed.
|
10
|
+
#
|
11
|
+
# class Sample < Tap::Generator::Base
|
12
|
+
# def manifest(m)
|
13
|
+
# dir = path('dir')
|
14
|
+
#
|
15
|
+
# m.directory dir
|
16
|
+
# m.file(File.join(dir, 'file.txt')) {|io| io << "content"}
|
17
|
+
# end
|
18
|
+
# end
|
19
|
+
#
|
20
|
+
# These assertions will pass:
|
21
|
+
#
|
22
|
+
# s = Sample.new.extend Preview
|
23
|
+
# assert_equal %w{
|
24
|
+
# dir
|
25
|
+
# dir/file.txt
|
26
|
+
# }, s.process
|
27
|
+
#
|
28
|
+
# assert_equal "content", s.preview['dir/file.txt']
|
29
|
+
#
|
30
|
+
# Note that relative paths are relative to destination_root.
|
31
|
+
module Preview
|
32
|
+
|
33
|
+
# A hash of (relative_path, content) pairs representing
|
34
|
+
# content built to files.
|
35
|
+
attr_accessor :preview
|
36
|
+
|
37
|
+
def self.extended(base) # :nodoc:
|
38
|
+
base.instance_variable_set(:@preview, {})
|
39
|
+
end
|
40
|
+
|
41
|
+
# Returns the path of path, relative to destination_root. If path
|
42
|
+
# is destination_root, '.' will be returned.
|
43
|
+
def relative_path(path)
|
44
|
+
path = Root::Utils.relative_path(destination_root, path, destination_root) || path
|
45
|
+
path.empty? ? "." : path
|
46
|
+
end
|
47
|
+
|
48
|
+
# Returns the relative path of the target.
|
49
|
+
def directory(target, options={})
|
50
|
+
relative_path(target)
|
51
|
+
end
|
52
|
+
|
53
|
+
# Returns the relative path of the target. If a block is given,
|
54
|
+
# the block will be called with a StringIO and the results stored
|
55
|
+
# in builds.
|
56
|
+
def file(target, options={})
|
57
|
+
target = relative_path(target)
|
58
|
+
|
59
|
+
if block_given?
|
60
|
+
io = StringIO.new
|
61
|
+
yield(io)
|
62
|
+
preview[target] = io.string
|
63
|
+
end
|
64
|
+
|
65
|
+
target
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
data/tap.yml
ADDED
File without changes
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# tap <%= command_name %> {options} ARGS...
|
2
|
+
#
|
3
|
+
# The default command simply prints the input arguments
|
4
|
+
# and application information, then exits.
|
5
|
+
#
|
6
|
+
|
7
|
+
env = Tap::Env.instance
|
8
|
+
app = Tap::App.new
|
9
|
+
|
10
|
+
#
|
11
|
+
# handle options
|
12
|
+
#
|
13
|
+
|
14
|
+
ConfigParser.new do |opts|
|
15
|
+
opts.separator ""
|
16
|
+
opts.separator "options:"
|
17
|
+
|
18
|
+
opts.on("-h", "--help", "Show this message") do
|
19
|
+
puts Lazydoc.usage(__FILE__)
|
20
|
+
puts opts
|
21
|
+
exit
|
22
|
+
end
|
23
|
+
|
24
|
+
end.parse!(ARGV)
|
25
|
+
|
26
|
+
#
|
27
|
+
# add your script code here
|
28
|
+
#
|
29
|
+
|
30
|
+
puts "Received: #{ARGV.join(', ')}"
|
31
|
+
puts app.info
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'tap/generator/base'
|
2
|
+
|
3
|
+
<% redirect do |target| %># <%= const.const_name %>::generator <replace with manifest summary>
|
4
|
+
# <replace with command line description>
|
5
|
+
|
6
|
+
# <%= const.name %> Documentation
|
7
|
+
class <%= const.name %> < Tap::Generator::Base
|
8
|
+
|
9
|
+
config :key, 'value' # a sample config
|
10
|
+
|
11
|
+
# The generator will receive the inputs on the command line, and
|
12
|
+
# m, a Manifest object that records the actions of this method.
|
13
|
+
def manifest(m, *inputs)
|
14
|
+
|
15
|
+
# make a directory
|
16
|
+
# m.directory path
|
17
|
+
|
18
|
+
# make a file
|
19
|
+
# m.file path do |file|
|
20
|
+
# file << content
|
21
|
+
# end
|
22
|
+
|
23
|
+
# template a file in the templates directory using ERB.
|
24
|
+
# The last argument defines a hash of local variables
|
25
|
+
# for use in the template (here config is used).
|
26
|
+
m.template "<%= const.const_name.underscore %>_file.txt", "template_file.erb", config.to_hash
|
27
|
+
end
|
28
|
+
|
29
|
+
end <% module_nest(const.nesting, ' ') { target } end %>
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '<%= '../' * const.nesting_depth %>tap_test_helper.rb')
|
2
|
+
require '<%= const.path %>'
|
3
|
+
require 'tap/generator/preview.rb'
|
4
|
+
|
5
|
+
class <%= const.name %>Test < Test::Unit::TestCase
|
6
|
+
|
7
|
+
# Preview fakes out a generator for testing
|
8
|
+
Preview = Tap::Generator::Preview
|
9
|
+
|
10
|
+
acts_as_tap_test
|
11
|
+
|
12
|
+
def test_<%= const.basename %>
|
13
|
+
g = <%= const.const_name %>.new.extend Preview
|
14
|
+
|
15
|
+
# check the files and directories
|
16
|
+
assert_equal %w{
|
17
|
+
<%= const.const_name.underscore %>_file.txt
|
18
|
+
}, g.process
|
19
|
+
|
20
|
+
# check the content as necessary
|
21
|
+
assert_equal %q{
|
22
|
+
# A sample template file.
|
23
|
+
key: value
|
24
|
+
}, "\n" + g.preview['<%= const.const_name.underscore %>_file.txt']
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) <%= Time.now.year %>, <copyright holders>
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person
|
4
|
+
obtaining a copy of this software and associated documentation
|
5
|
+
files (the "Software"), to deal in the Software without
|
6
|
+
restriction, including without limitation the rights to use,
|
7
|
+
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
8
|
+
copies of the Software, and to permit persons to whom the
|
9
|
+
Software is furnished to do so, subject to the following
|
10
|
+
conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be
|
13
|
+
included in all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
16
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
17
|
+
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
18
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
19
|
+
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
20
|
+
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
21
|
+
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
22
|
+
OTHER DEALINGS IN THE SOFTWARE.
|
@@ -0,0 +1,85 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'rake/testtask'
|
3
|
+
require 'rake/rdoctask'
|
4
|
+
require 'rake/gempackagetask'
|
5
|
+
|
6
|
+
#
|
7
|
+
# Gem specification
|
8
|
+
#
|
9
|
+
|
10
|
+
def gemspec
|
11
|
+
data = File.read('<%= project_name %>.gemspec')
|
12
|
+
spec = nil
|
13
|
+
Thread.new { spec = eval("$SAFE = 3\n#{data}") }.join
|
14
|
+
spec
|
15
|
+
end
|
16
|
+
|
17
|
+
Rake::GemPackageTask.new(gemspec) do |pkg|
|
18
|
+
pkg.need_tar = true
|
19
|
+
end
|
20
|
+
|
21
|
+
desc 'Prints the gemspec manifest.'
|
22
|
+
task :print_manifest do
|
23
|
+
# collect files from the gemspec, labeling
|
24
|
+
# with true or false corresponding to the
|
25
|
+
# file existing or not
|
26
|
+
files = gemspec.files.inject({}) do |files, file|
|
27
|
+
files[File.expand_path(file)] = [File.exists?(file), file]
|
28
|
+
files
|
29
|
+
end
|
30
|
+
|
31
|
+
# gather non-rdoc/pkg files for the project
|
32
|
+
# and add to the files list if they are not
|
33
|
+
# included already (marking by the absence
|
34
|
+
# of a label)
|
35
|
+
Dir.glob("**/*").each do |file|
|
36
|
+
next if file =~ /^(rdoc|pkg|backup)/ || File.directory?(file)
|
37
|
+
|
38
|
+
path = File.expand_path(file)
|
39
|
+
files[path] = ["", file] unless files.has_key?(path)
|
40
|
+
end
|
41
|
+
|
42
|
+
# sort and output the results
|
43
|
+
files.values.sort_by {|exists, file| file }.each do |entry|
|
44
|
+
puts "%-5s %s" % entry
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
#
|
49
|
+
# Documentation tasks
|
50
|
+
#
|
51
|
+
|
52
|
+
desc 'Generate documentation.'
|
53
|
+
Rake::RDocTask.new(:rdoc) do |rdoc|
|
54
|
+
spec = gemspec
|
55
|
+
|
56
|
+
rdoc.rdoc_dir = 'rdoc'
|
57
|
+
rdoc.options.concat(spec.rdoc_options)
|
58
|
+
rdoc.rdoc_files.include( spec.extra_rdoc_files )
|
59
|
+
|
60
|
+
files = spec.files.select {|file| file =~ /^lib.*\.rb$/}
|
61
|
+
rdoc.rdoc_files.include( files )
|
62
|
+
|
63
|
+
# Using CDoc to template your RDoc will result in configurations being
|
64
|
+
# listed with documentation in a subsection following attributes. Not
|
65
|
+
# necessary, but nice.
|
66
|
+
require 'cdoc'
|
67
|
+
rdoc.template = 'cdoc/cdoc_html_template'
|
68
|
+
rdoc.options << '--fmt' << 'cdoc'
|
69
|
+
end
|
70
|
+
|
71
|
+
#
|
72
|
+
# Test tasks
|
73
|
+
#
|
74
|
+
|
75
|
+
desc 'Default: Run tests.'
|
76
|
+
task :default => :test
|
77
|
+
|
78
|
+
desc 'Run tests.'
|
79
|
+
Rake::TestTask.new(:test) do |t|
|
80
|
+
t.test_files = Dir.glob( File.join('test', ENV['pattern'] || '**/*_test.rb') )
|
81
|
+
t.ruby_opts = ['-rubygems']
|
82
|
+
t.verbose = true
|
83
|
+
t.warning = true
|
84
|
+
end
|
85
|
+
|
@@ -0,0 +1,11 @@
|
|
1
|
+
require 'tap/declarations'
|
2
|
+
|
3
|
+
module <%= project_name.camelize %>
|
4
|
+
extend Rap::Declarations
|
5
|
+
|
6
|
+
# ::desc your basic goodnight moon task
|
7
|
+
# Says goodnight with a configurable message.
|
8
|
+
task(:goodnight, :obj, :message => 'goodnight') do |task, args|
|
9
|
+
puts "#{task.message} #{args.obj}"
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
s.name = "<%= project_name %>"
|
3
|
+
s.version = "0.0.1"
|
4
|
+
s.author = "<%= name %>"
|
5
|
+
s.email = "<%= email %>"
|
6
|
+
s.homepage = "<%= homepage %>"
|
7
|
+
s.platform = Gem::Platform::RUBY
|
8
|
+
s.summary = "<%= summary %>"
|
9
|
+
s.require_path = "lib"
|
10
|
+
s.rubyforge_project = "<%= rubyforge_project %>"
|
11
|
+
s.add_dependency("tap", "= <%= Tap::VERSION %>")
|
12
|
+
s.add_development_dependency("tap-test")
|
13
|
+
s.has_rdoc = true
|
14
|
+
s.rdoc_options.concat %W{--main README -S -N --title <%= project_name.capitalize %>}
|
15
|
+
|
16
|
+
# list extra rdoc files here.
|
17
|
+
s.extra_rdoc_files = %W{
|
18
|
+
<%= history ? " History\n" : '' %>
|
19
|
+
README
|
20
|
+
<%= license ? " MIT-LICENSE\n" : '' %>
|
21
|
+
}
|
22
|
+
|
23
|
+
# list the files you want to include here. you can
|
24
|
+
# check this manifest using 'rap print_manifest'
|
25
|
+
s.files = %W{
|
26
|
+
tap.yml
|
27
|
+
}
|
28
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'tap/test/unit'
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'tap/task'
|
2
|
+
|
3
|
+
<% redirect do |target| %># <%= const.const_name %>::manifest <replace with manifest summary>
|
4
|
+
# <replace with command line description>
|
5
|
+
|
6
|
+
# <%= const.name %> Documentation
|
7
|
+
class <%= const.name %> < Tap::Task
|
8
|
+
|
9
|
+
# <config file documentation>
|
10
|
+
config :message, 'goodnight' # a sample config
|
11
|
+
|
12
|
+
def process(name)
|
13
|
+
log message, name
|
14
|
+
"#{message} #{name}"
|
15
|
+
end
|
16
|
+
end <% module_nest(const.nesting, ' ') { target } end %>
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '<%= '../' * const.nesting_depth %>tap_test_helper.rb')
|
2
|
+
require '<%= const.path %>'
|
3
|
+
|
4
|
+
class <%= const.name %>Test < Test::Unit::TestCase
|
5
|
+
acts_as_tap_test
|
6
|
+
|
7
|
+
def test_<%= const.basename %>
|
8
|
+
task = <%= const.const_name %>.new :message => "goodnight"
|
9
|
+
|
10
|
+
# a simple test
|
11
|
+
assert_equal({:message => 'goodnight'}, task.config)
|
12
|
+
assert_equal "goodnight moon", task.process("moon")
|
13
|
+
end
|
14
|
+
end
|
metadata
ADDED
@@ -0,0 +1,97 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: tap-gen
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Simon Chiang
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-05-25 00:00:00 -06:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: tap
|
17
|
+
type: :runtime
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 0.17.0
|
24
|
+
version:
|
25
|
+
description:
|
26
|
+
email: simon.a.chiang@gmail.com
|
27
|
+
executables: []
|
28
|
+
|
29
|
+
extensions: []
|
30
|
+
|
31
|
+
extra_rdoc_files:
|
32
|
+
- History
|
33
|
+
- README
|
34
|
+
- MIT-LICENSE
|
35
|
+
files:
|
36
|
+
- cmd/destroy.rb
|
37
|
+
- cmd/generate.rb
|
38
|
+
- lib/tap/generator/arguments.rb
|
39
|
+
- lib/tap/generator/base.rb
|
40
|
+
- lib/tap/generator/destroy.rb
|
41
|
+
- lib/tap/generator/exe.rb
|
42
|
+
- lib/tap/generator/generate.rb
|
43
|
+
- lib/tap/generator/generators/command.rb
|
44
|
+
- lib/tap/generator/generators/config.rb
|
45
|
+
- lib/tap/generator/generators/generator.rb
|
46
|
+
- lib/tap/generator/generators/root.rb
|
47
|
+
- lib/tap/generator/generators/task.rb
|
48
|
+
- lib/tap/generator/manifest.rb
|
49
|
+
- lib/tap/generator/preview.rb
|
50
|
+
- tap.yml
|
51
|
+
- templates/tap/generator/generators/command/command.erb
|
52
|
+
- templates/tap/generator/generators/generator/task.erb
|
53
|
+
- templates/tap/generator/generators/generator/test.erb
|
54
|
+
- templates/tap/generator/generators/root/MIT-LICENSE
|
55
|
+
- templates/tap/generator/generators/root/README
|
56
|
+
- templates/tap/generator/generators/root/Rakefile
|
57
|
+
- templates/tap/generator/generators/root/Rapfile
|
58
|
+
- templates/tap/generator/generators/root/gemspec
|
59
|
+
- templates/tap/generator/generators/root/test/tap_test_helper.rb
|
60
|
+
- templates/tap/generator/generators/task/task.erb
|
61
|
+
- templates/tap/generator/generators/task/test.erb
|
62
|
+
- History
|
63
|
+
- README
|
64
|
+
- MIT-LICENSE
|
65
|
+
has_rdoc: true
|
66
|
+
homepage: http://tap.rubyforge.org/tap-gen
|
67
|
+
post_install_message:
|
68
|
+
rdoc_options:
|
69
|
+
- --main
|
70
|
+
- README
|
71
|
+
- -S
|
72
|
+
- -N
|
73
|
+
- --title
|
74
|
+
- Tap-Generator
|
75
|
+
require_paths:
|
76
|
+
- lib
|
77
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
78
|
+
requirements:
|
79
|
+
- - ">="
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
version: "0"
|
82
|
+
version:
|
83
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
84
|
+
requirements:
|
85
|
+
- - ">="
|
86
|
+
- !ruby/object:Gem::Version
|
87
|
+
version: "0"
|
88
|
+
version:
|
89
|
+
requirements: []
|
90
|
+
|
91
|
+
rubyforge_project: tap
|
92
|
+
rubygems_version: 1.3.1
|
93
|
+
signing_key:
|
94
|
+
specification_version: 2
|
95
|
+
summary: Generators for Tap
|
96
|
+
test_files: []
|
97
|
+
|