Class: Tap::Generator::Base
- Inherits:
-
Task
- Object
- Task
- Tap::Generator::Base
- Defined in:
- lib/tap/generator/base.rb
Overview
:startdoc:::- Base provides the basic structure of a generator and custom generators inherit from it. Base is patterned after the Ruby on Rails generators, but obviously takes on all the advantages of Tasks.
Usage
Tap generators define a manifest method that defines what files and directories are created by the generator. Then, at execution time, a mixin with the appropriate funtion (ie Generate or Destroy) is overlaid to figure out how to roll those actions forward or backwards.
Generators are identified using the ::generator flag rather than ::task, so that generators are available to the generate/destroy commands and not run.
Typically, generators live in a directory structure like this:
root
|- lib
| `- sample.rb
|
`- templates
`- sample
`- template_file.erb
Tap generators keep templates out of lib and under templates, in a directory is named after the generator class. Generators themselves take the form:
[sample.rb]
require 'tap/generator/base'
# ::generator generates a directory, and two files
#
# An extended description of the
# generator goes here...
#
class Sample < Tap::Generator::Base
config :key, 'value' # a sample config
def manifest(m, *args)
# make a directory
m.directory('path/to/dir')
# make a file
m.file('path/to/file.txt') do |file|
file << "some content"
end
# template a file
m.template('path/to/result.txt', 'template_file.erb', config.to_hash)
end
end
The arguments that a generator receives are specified by manifest (minus the ‘m’ argument which is standard) rather than process. Creating directories and files is straightforward, as above. Template renders the erb source file using attributes specified in the last argument; in the example template uses the generator configurations.
:startdoc:::+
Direct Known Subclasses
Generators::Command, Generators::Config, Generators::Resource, Generators::Root
Instance Attribute Summary collapse
-
#prompt_in ⇒ Object
The IO used to pull prompt inputs (default: $stdin).
-
#prompt_out ⇒ Object
The IO used to prompt users for input (default: $stdout).
-
#template_dir ⇒ Object
The generator-specific templates directory.
Instance Method Summary collapse
-
#action ⇒ Object
Returns the action for self (ie :generate or :destroy).
-
#directories(root, targets, options = {}) ⇒ Object
Makes (or destroys) the root and each of the targets, relative to root.
-
#directory(target, options = {}) ⇒ Object
Peforms a directory action (ex generate or destroy).
-
#file(target, options = {}) ⇒ Object
Peforms a file action (ex generate or destroy).
-
#initialize(config = {}, app = Tap::App.instance) ⇒ Base
constructor
A new instance of Base.
-
#iterate(actions) ⇒ Object
Peforms each of the input actions in order, and collects the results.
-
#log_relative(action, path) ⇒ Object
Logs the action with the relative filepath from Dir.pwd to path.
-
#manifest(m, *argv) ⇒ Object
Overridden in subclasses to add actions to the input Manifest.
-
#on(*actions, &block) ⇒ Object
Calls the block when specified by the action for self.
-
#path(*paths) ⇒ Object
Constructs a path relative to destination_root.
-
#process(*argv) ⇒ Object
Builds the manifest, then executes the actions of the manifest.
- #set(mod) ⇒ Object
-
#template(target, source, attributes = {}, options = {}) ⇒ Object
Makes (or destroys) the target by templating the source using the specified attributes.
-
#template_files ⇒ Object
Yields each source file under template_dir to the block, with a target path of the source relative to template_dir.
Constructor Details
#initialize(config = {}, app = Tap::App.instance) ⇒ Base
Returns a new instance of Base.
97 98 99 100 101 102 |
# File 'lib/tap/generator/base.rb', line 97 def initialize(config={}, app=Tap::App.instance) super @prompt_in = $stdin @prompt_out = $stdout @template_dir = app.env.path(:templates, self.class.to_s.underscore) {|dir| File.directory?(dir) } || File.("templates/#{self.class.to_s.underscore}") end |
Instance Attribute Details
#prompt_in ⇒ Object
The IO used to pull prompt inputs (default: $stdin)
92 93 94 |
# File 'lib/tap/generator/base.rb', line 92 def prompt_in @prompt_in end |
#prompt_out ⇒ Object
The IO used to prompt users for input (default: $stdout)
95 96 97 |
# File 'lib/tap/generator/base.rb', line 95 def prompt_out @prompt_out end |
#template_dir ⇒ Object
The generator-specific templates directory. By default: ‘templates/path/to/name’ for ‘lib/path/to/name.rb’
89 90 91 |
# File 'lib/tap/generator/base.rb', line 89 def template_dir @template_dir end |
Instance Method Details
#action ⇒ Object
Returns the action for self (ie :generate or :destroy)
204 205 206 |
# File 'lib/tap/generator/base.rb', line 204 def action raise NotImplementedError end |
#directories(root, targets, options = {}) ⇒ Object
Makes (or destroys) the root and each of the targets, relative to root. Options are passed onto directory.
156 157 158 159 160 161 162 |
# File 'lib/tap/generator/base.rb', line 156 def directories(root, targets, ={}) results = [directory(root, )] targets.each do |target| results << directory(File.join(root, target), ) end results end |
#directory(target, options = {}) ⇒ Object
Peforms a directory action (ex generate or destroy). Must be overridden by one of the action mixins (ex Generate or Destroy).
142 143 144 |
# File 'lib/tap/generator/base.rb', line 142 def directory(target, ={}) raise NotImplementedError end |
#file(target, options = {}) ⇒ Object
Peforms a file action (ex generate or destroy). Calls to file specify input for a target by providing a block; the block recieves an IO and pushes content to it. Must be overridden by one of the action mixins (ex Generate or Destroy).
150 151 152 |
# File 'lib/tap/generator/base.rb', line 150 def file(target, ={}) # :yields: io raise NotImplementedError end |
#iterate(actions) ⇒ Object
Peforms each of the input actions in order, and collects the results. The process method returns these results.
131 132 133 |
# File 'lib/tap/generator/base.rb', line 131 def iterate(actions) actions.collect {|action| yield(action) } end |
#log_relative(action, path) ⇒ Object
Logs the action with the relative filepath from Dir.pwd to path.
209 210 211 212 |
# File 'lib/tap/generator/base.rb', line 209 def log_relative(action, path) relative_path = Tap::Root::Utils.relative_path(Dir.pwd, path) log(action, relative_path || path) end |
#manifest(m, *argv) ⇒ Object
Overridden in subclasses to add actions to the input Manifest. Any arguments passed to process will be passed to manifest unchanged.
125 126 127 |
# File 'lib/tap/generator/base.rb', line 125 def manifest(m, *argv) raise NotImplementedError end |
#on(*actions, &block) ⇒ Object
Calls the block when specified by the action for self.
195 196 197 198 199 200 201 |
# File 'lib/tap/generator/base.rb', line 195 def on(*actions, &block) if actions.include?(action) block.call else nil end end |
#path(*paths) ⇒ Object
Constructs a path relative to destination_root.
136 137 138 |
# File 'lib/tap/generator/base.rb', line 136 def path(*paths) File.(File.join(*paths), destination_root) end |
#process(*argv) ⇒ Object
Builds the manifest, then executes the actions of the manifest. Process returns the results of iterate, which normally will be an array of files and directories created (or destroyed) by self.
113 114 115 116 117 118 119 120 |
# File 'lib/tap/generator/base.rb', line 113 def process(*argv) actions = [] manifest(Manifest.new(actions), *argv) iterate(actions) do |action, args, block| send(action, *args, &block) end end |
#set(mod) ⇒ Object
104 105 106 107 108 |
# File 'lib/tap/generator/base.rb', line 104 def set(mod) mod = app.env[mod] unless mod.class == Module extend(mod) self end |
#template(target, source, attributes = {}, options = {}) ⇒ Object
Makes (or destroys) the target by templating the source using the specified attributes. Source is expanded relative to template_dir. Options are passed onto file.
167 168 169 170 171 172 173 174 175 176 |
# File 'lib/tap/generator/base.rb', line 167 def template(target, source, attributes={}, ={}) raise "no template dir is set" unless template_dir template_path = File.(source, template_dir) templater = Templater.new(File.read(template_path), attributes) file(target, ) do |file| file << templater.build(nil, template_path) end end |
#template_files ⇒ Object
Yields each source file under template_dir to the block, with a target path of the source relative to template_dir.
180 181 182 183 184 185 186 187 188 189 190 191 192 |
# File 'lib/tap/generator/base.rb', line 180 def template_files raise "no template dir is set" unless template_dir targets = [] Dir.glob(template_dir + "/**/*").sort.each do |source| next unless File.file?(source) target = Tap::Root::Utils.relative_path(template_dir, source) yield(source, target) targets << target end targets end |