Class: Apimaster::Generators::Base
- Inherits:
-
Object
- Object
- Apimaster::Generators::Base
- Includes:
- Options
- Defined in:
- lib/apimaster/generators/base.rb
Overview
The base code generator is bare-bones. It sets up the source and destination paths and tells the logger whether to keep its trap shut.
It’s useful for copying files such as stylesheets, images, or javascripts.
For more comprehensive template-based passive code generation with arguments, you’ll want Apimaster::Generators::NamedBase.
Generators create a manifest of the actions they perform then hand the manifest to a command which replays the actions to do the heavy lifting (such as checking for existing files or creating directories if needed). Create, destroy, and list commands are included. Since a single manifest may be used by any command, creating new generators is as simple as writing some code templates and declaring what you’d like to do with them.
The manifest method must be implemented by subclasses, returning a Apimaster::Generators::Manifest. The record method is provided as a convenience for manifest creation. Example:
class StylesheetGenerators < Apimaster::Generators::Base
def manifest
record do |m|
m.directory('public/stylesheets')
m.file('application.css', 'public/stylesheets/application.css')
end
end
end
See Apimaster::Generators::Commands::Create for a list of methods available to the manifest.
Direct Known Subclasses
Constant Summary collapse
- DEFAULT_SHEBANG =
File.join(RbConfig::CONFIG['bindir'], RbConfig::CONFIG['ruby_install_name'])
Instance Attribute Summary collapse
-
#active ⇒ Object
Either Apimaster::Generators::Base, or a subclass (e.g. Rails::Generators::Base) Currently used to determine the lookup paths via the overriden const_missing mechansim in lookup.rb.
-
#args ⇒ Object
readonly
class_attribute :spec.
-
#destination_root ⇒ Object
readonly
class_attribute :spec.
-
#logger ⇒ Object
A logger instance available everywhere in the generator.
-
#source_root ⇒ Object
readonly
class_attribute :spec.
-
#spec ⇒ Object
Every generator that is dynamically looked up is tagged with a Spec describing where it was found.
-
#stdout ⇒ Object
readonly
class_attribute :spec.
Attributes included from Options
Instance Method Summary collapse
- #after_generate ⇒ Object
-
#base_name ⇒ Object
Return the basename of the destination_root, BUT, if it is trunk, tags, or branches, it continues to the parent path for the name.
- #camelize(term, uppercase_first_letter = true) ⇒ Object
-
#destination_path(relative_destination) ⇒ Object
Return the full path from the destination root for the given path.
-
#initialize(runtime_args, runtime_options = {}) ⇒ Base
constructor
A new instance of Base.
-
#manifest ⇒ Object
Generators must provide a manifest.
- #pluralize(word) ⇒ Object
-
#run ⇒ Object
Run the generator script.
-
#source_path(relative_source) ⇒ Object
Return the full path from the source root for the given path.
Methods included from Options
Constructor Details
#initialize(runtime_args, runtime_options = {}) ⇒ Base
Returns a new instance of Base.
104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 |
# File 'lib/apimaster/generators/base.rb', line 104 def initialize(runtime_args, = {}) [:source] = File.dirname(__FILE__) + '/templates' [:destination] = Dir.pwd [:collision] = :ask [:stdout] = STDOUT [:backtrace] = true @logger = SimpleLogger.new @args = runtime_args parse!(@args, ) # Derive source and destination paths. @source_root = [:source] || File.join(spec.path, 'templates') if [:destination] @destination_root = [:destination] end # Silence the logger if requested. #logger.quiet = options[:quiet] @stdout = [:stdout] # Raise usage error if help is requested. usage if [:help] end |
Instance Attribute Details
#active ⇒ Object
Either Apimaster::Generators::Base, or a subclass (e.g. Rails::Generators::Base) Currently used to determine the lookup paths via the overriden const_missing mechansim in lookup.rb
95 96 97 |
# File 'lib/apimaster/generators/base.rb', line 95 def active @active end |
#args ⇒ Object (readonly)
class_attribute :spec
102 103 104 |
# File 'lib/apimaster/generators/base.rb', line 102 def args @args end |
#destination_root ⇒ Object (readonly)
class_attribute :spec
102 103 104 |
# File 'lib/apimaster/generators/base.rb', line 102 def destination_root @destination_root end |
#logger ⇒ Object
A logger instance available everywhere in the generator.
90 91 92 |
# File 'lib/apimaster/generators/base.rb', line 90 def logger @logger end |
#source_root ⇒ Object (readonly)
class_attribute :spec
102 103 104 |
# File 'lib/apimaster/generators/base.rb', line 102 def source_root @source_root end |
#spec ⇒ Object
Every generator that is dynamically looked up is tagged with a Spec describing where it was found.
99 100 101 |
# File 'lib/apimaster/generators/base.rb', line 99 def spec @spec end |
#stdout ⇒ Object (readonly)
class_attribute :spec
102 103 104 |
# File 'lib/apimaster/generators/base.rb', line 102 def stdout @stdout end |
Instance Method Details
#after_generate ⇒ Object
179 180 |
# File 'lib/apimaster/generators/base.rb', line 179 def after_generate end |
#base_name ⇒ Object
Return the basename of the destination_root, BUT, if it is trunk, tags, or branches, it continues to the parent path for the name
169 170 171 172 173 174 175 176 177 |
# File 'lib/apimaster/generators/base.rb', line 169 def base_name name = File.basename(destination_root) root = destination_root while %w[trunk branches tags].include? name root = File.(File.join(root, "..")) name = File.basename(root) end name end |
#camelize(term, uppercase_first_letter = true) ⇒ Object
200 201 202 203 204 |
# File 'lib/apimaster/generators/base.rb', line 200 def camelize(term, uppercase_first_letter = true) string = term.to_s string = string.sub(/^[a-z\d]*/) { $&.capitalize } string.gsub(/(?:_|(\/))([a-z\d]*)/i) { "#{$1}#{$2.capitalize}" }.gsub('/', '::') end |
#destination_path(relative_destination) ⇒ Object
Return the full path from the destination root for the given path. Example for destination_root = ‘/dest’:
destination_path('some/path.rb') == '/dest/some/path.rb'
162 163 164 |
# File 'lib/apimaster/generators/base.rb', line 162 def destination_path(relative_destination) File.(File.join(destination_root, relative_destination)) end |
#manifest ⇒ Object
Generators must provide a manifest. Use the record method to create a new manifest and record your generator’s actions.
131 132 133 |
# File 'lib/apimaster/generators/base.rb', line 131 def manifest raise NotImplementedError, "No manifest for '#{spec.name}' generator." end |
#pluralize(word) ⇒ Object
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 238 239 |
# File 'lib/apimaster/generators/base.rb', line 206 def pluralize(word) rules = {} rules.store(/$/, 's') rules.store(/s$/i, 's') rules.store(/(ax|test)is$/i, '\1es') rules.store(/(octop|vir)us$/i, '\1i') rules.store(/(octop|vir)i$/i, '\1i') rules.store(/(alias|status)$/i, '\1es') rules.store(/(bu)s$/i, '\1ses') rules.store(/(buffal|tomat)o$/i, '\1oes') rules.store(/([ti])um$/i, '\1a') rules.store(/([ti])a$/i, '\1a') rules.store(/sis$/i, 'ses') rules.store(/(?:([^f])fe|([lr])f)$/i, '\1\2ves') rules.store(/(hive)$/i, '\1s') rules.store(/([^aeiouy]|qu)y$/i, '\1ies') rules.store(/(x|ch|ss|sh)$/i, '\1es') rules.store(/(matr|vert|ind)(?:ix|ex)$/i, '\1ices') rules.store(/(m|l)ouse$/i, '\1ice') rules.store(/(m|l)ice$/i, '\1ice') rules.store(/^(ox)$/i, '\1en') rules.store(/^(oxen)$/i, '\1') rules.store(/(quiz)$/i, '\1zes') uncountables = %w(equipment information rice money species series fish sheep jeans) result = word.to_s.dup if word.empty? || uncountables.any? { |inflection| result =~ /\b#{inflection}\Z/i } result else rules.each { |(rule, replacement)| break if result.gsub!(rule, replacement) } result end end |
#run ⇒ Object
Run the generator script. Takes an array of unparsed arguments and a hash of parsed arguments, takes the generator as an option or first remaining argument, and invokes the requested command.
185 186 187 188 189 190 191 192 193 194 195 196 197 198 |
# File 'lib/apimaster/generators/base.rb', line 185 def run name = args.shift if name # Look up generator instance and invoke command on it. manifest.replay(self) after_generate else puts 'Undefined name.' unless [:help] end rescue => e puts e puts " #{e.backtrace.join("\n ")}\n" if [:backtrace] raise SystemExit unless [:no_exit] end |
#source_path(relative_source) ⇒ Object
Return the full path from the source root for the given path. Example for source_root = ‘/source’:
source_path('some/path.rb') == '/source/some/path.rb'
The given path may include a colon ‘:’ character to indicate that the file belongs to another generator. This notation allows any generator to borrow files from another. Example:
source_path('model:fixture.yml') = '/model/source/path/fixture.yml'
143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 |
# File 'lib/apimaster/generators/base.rb', line 143 def source_path(relative_source) # Check whether we're referring to another generator's file. name, path = relative_source.split(':', 2) # If not, return the full path to our source file. if path.nil? File.join(source_root, name) # Otherwise, ask our referral for the file. else # FIXME: this is broken, though almost always true. Others' # source_root are not necessarily the templates dir. File.join(self.class.lookup(name).path, 'templates', path) end end |