rubigen
Get Version
1.0.3Ruby Generator Framework
What
A framework to allow Ruby applications to generate file/folder stubs
(like the rails
command does for Ruby on Rails, and the ‘script/generate’
command within a Rails application during development).
Background
RubiGen is originally extracted from Ruby on Rails (specifically the rails_generator from its railties gem).
The rails_generator was hardcoded with Rails-specific dependencies (RAILS_ROOT
),
Rails generators (‘app’ = Rails application; ‘model’ = Rails model+tests+migration),
and generally assumed it was the only generator framework within the Ruby world (it was).
So, any RubyGem whose name ended with ‘_generator’ was assumed to be a generator for
a Rails application.
But if you are developing a Merb application, then you may want a different set of generators. If you are developing a RubyGem, then you will want a different set of generators.
RubiGen exists to give different development environments their own generator framework.
Installing
RubiGen is only required at development time, and normally isn’t required at deployment time (unless your application uses it to generate files etc for its users).
On your development machine:
sudo gem install rubigen
Usage
RubiGen will be normally integrated into another RubyGem, such as newgem
or merb
or camping
,
rather than be used on its own.
These frameworks might use RubiGen for two reasons:
- To generate an initial stub for developers, e.g.
rails
generated a stub to write a Rails application.newgem
generates a stub to write a RubyGem.
BTW – RubiGen has a builtin applicationruby_app
which generates a bare-bones Ruby application stub (lib, test, and script folders, plus a Rakefile, and a script/generate script) - To generate components within their development areas, e.g. Rails had its
script/generate
script within each Rails application, which hooked back into the rails_generator to lookup and execute generators.
So, there are two steps to integrating RubiGen into your framework:
- Use it to generate an initial stub for the developers of your framework. This would create the folders
(
lib/app
,test
,script
,doc
,log
, etc) and starting files (Rakefile
,README.txt
,test/test_helper.rb
etc). Importantly, it would generate ascript/generate
file. Thescript/generate
file (example below) will allow developers of your framework to generate components/extensions within the framework.
RubiGen allows you to restrict which generators are available. For example, within RubyGem development environment (as generated bynewgem
), thescript/generator
only showsrubygem
-related generators. Merb could restrictscript/generator
to only show Merb related generators (or perhaps Merb and/or Rails generators) - Your framework RubyGem (e.g.
newgem
ormerb
RubyGems) needs to addrubigen
as a dependency, so that users of your RubyGem can access the generator framework.
Creating generators
There are two types of generators:
- Application Generators – used by developers of your framework to get started.
Generally, you will create one Application Generator for your framework.
It generates a base stub (such as the
rails
stub for new Rails applications) for your framework users. - Component Generators – used by developers to extend their application. You may include 1+ built-in generators with your framework. Developers can also write generators for your framework, and like Rails’ generator install them in various places and have access to their via RubiGen.
Creating an Application Generator for your Framework
Easy way
newgem (v0.13.0+) can generate an Application Generator for a RubyGem.
- Create new RubyGem:
newgem foobar
- Create generator:
script/generator application_generator foobar
- Update tests + generator
- Install
- Run with: foobar
For more documentation, run script/generator application_generator
DIY
Without RubiGen, to give your users a head start and create a stub for them, you will
copiously use mkdir_p
and File.open
. Your script will either be primitive (only
create the bare folders and very few files) or it will be very long and unreadable
(ok, perhaps I’m just talking about the newgem
script, which I am dubiously responsible
for… :P).
With RubiGen, you can create stubs using powerful, yet simple, syntax. Templates are
extracted into a templates
folder, and activating the generator from a script requires
only a few lines of code.
These are the newgem
files related to its Application Generator.
bin/
bin/newgem # Appliction Generator script; Usage: newgem gemname [options]
app_generators/
app_generators/newgem/
app_generators/newgem/newgem_generator.rb
app_generators/newgem/USAGE
app_generators/newgem/templates/
app_generators/newgem/templates/app.rb
app_generators/newgem/templates/History.txt
app_generators/newgem/templates/... lots and lots of templates
The bin/newgem
script is very simple, and looks like:
require 'rubygems' require 'rubigen' if %w(-v --version).include? ARGV.first require 'newgem/version' puts "#{File.basename($0)} #{Newgem::VERSION::STRING}" exit(0) end require 'rubigen/scripts/generate' RubiGen::Base.use_application_sources! RubiGen::Scripts::Generate.new.run(ARGV, :generator => 'newgem')
You can copy and paste this for your own generator script, and place it in your RubyGem’s bin
folder.
Change newgem
to your RubyGem’s name in the script above (and in all the folders listed above too)
NOTE: If you leave newgem
there, then it will execute the newgem_generator.rb
generator;
as the generators are loaded from all RubyGem’s having /app_generators
folders.
So, for your RubyGem, you need to keep the /app_generators
folder (as you are creating an
Application Generator, not a Component Generator), but change newgem
to your gem name
in
all the subfolders and files. ESPECIALLY newgem_generator.rb
-> yourgem_generator.rb
,
as this is how the generator is discovered (via RubiGen::Base.use_application_sources!
).
All the generator work is performed within yourgem_generator.rb
. A stub for it will be:
require 'rbconfig' class YourgemGenerator < RubiGen::Base DEFAULT_SHEBANG = File.join(Config::CONFIG['bindir'], Config::CONFIG['ruby_install_name']) default_options :shebang => DEFAULT_SHEBANG, :an_option => 'some_default' attr_reader :app_name, :module_name def initialize(runtime_args, runtime_options = {}) super usage if args.empty? @destination_root = args.shift @app_name = File.basename(File.expand_path(@destination_root)) @module_name = app_name.camelize extract_options end def manifest # Use /usr/bin/env if no special shebang was specified script_options = { :chmod => 0755, :shebang => options[:shebang] == DEFAULT_SHEBANG ? nil : options[:shebang] } windows = (RUBY_PLATFORM =~ /dos|win32|cygwin/i) || (RUBY_PLATFORM =~ /(:?mswin|mingw)/) record do |m| # Root directory and all subdirectories. m.directory '' BASEDIRS.each { |path| m.directory path } # Root m.template_copy_each %w( Rakefile ) m.file_copy_each %w( README.txt ) # Test helper m.template "test_helper.rb", "test/test_helper.rb" # Scripts %w( generate ).each do |file| m.template "script/#{file}", "script/#{file}", script_options m.template "script/win_script.cmd", "script/#{file}.cmd", :assigns => { :filename => file } if windows end end end protected def banner <<-EOS Create a stub for #{File.basename $0} to get started. Usage: #{File.basename $0} /path/to/your/app [options]" EOS end def add_options!(opts) opts.separator '' opts.separator "#{File.basename $0} options:" opts.on("-v", "--version", "Show the #{File.basename($0)} version number and quit.") end # Installation skeleton. Intermediate directories are automatically # created so don't sweat their absence here. BASEDIRS = %w( doc lib log script test tmp ) end
Easy peasy.
Creating a Component Generator for your Framework
You can include Component Generators in RubyGems, and they will be automatially picked up
by your framework’s script/generate
script.
Easy way
Use newgem, (v0.13.0+), and run:
script/generate component_generator
and follow the instructions.
Forum
http://groups.google.com/group/rubigen
How to submit patches
Read the 8 steps for fixing other people’s code and for section 8b: Submit patch to Google Groups, use the Google Group above.
The trunk repository is svn://rubyforge.org/var/svn/rubigen/trunk
for anonymous access.
Thanks go to…
Jeremy Kemper (bitsweat) who wrote the original Rails Generator.
License
This code is free to use under the terms of the MIT license.
Contact
Comments are welcome. Send an email to Dr Nic Williams via the forum
Dr Nic Williams, 22nd August 2007
Theme extended from Paul Battley