Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/drnic/rubigen
Generator framework for your own Ruby framework
https://github.com/drnic/rubigen
Last synced: 3 days ago
JSON representation
Generator framework for your own Ruby framework
- Host: GitHub
- URL: https://github.com/drnic/rubigen
- Owner: drnic
- License: mit
- Created: 2008-03-04T22:45:35.000Z (almost 17 years ago)
- Default Branch: master
- Last Pushed: 2015-12-21T14:19:57.000Z (about 9 years ago)
- Last Synced: 2024-12-17T17:06:29.337Z (11 days ago)
- Language: Ruby
- Homepage: http://drnic.github.com/rubigen
- Size: 497 KB
- Stars: 74
- Watchers: 6
- Forks: 19
- Open Issues: 6
-
Metadata Files:
- Readme: README.rdoc
- Changelog: History.txt
- License: LICENSE
Awesome Lists containing this project
README
= RubiGen - Ruby Generator Framework
* http://drnic.github.com/rubigen
== DESCRIPTION:
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 an Adhearsion 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.
=== Thanks go to...
Jeremy Kemper wrote the original Rails Generator, which is 95% of the basis of RubiGen. He's awesome.
== Installation
RubiGen is only required at development time, and normally isn't required at deployment time
(unless your application uses it to generate files at runtime).On your development machine:
sudo gem install rubigen
== UsageRubiGen comes with a stand-alone executable to allow you to invoke generators:
For example, to run the rails' `model` generator:
rubigen rails model Person name:string
would replace the normal
script/generate model Person name:string
RubiGen has been traditionally integrated into another project, such as `rails`, `newgem` or `camping`,
rather than be used on its own.These frameworks might use RubiGen for two reasons:
1. 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 application `ruby_app` which generates a bare-bones Ruby application
stub (lib, test, and script folders, plus a Rakefile, and a script/generate script)
2. 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:
1. 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 a `script/generate` file.
The `script/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 by `newgem`), the `script/generator`
only shows `rubygem`-related generators. Rails could restrict `script/generator`
to only show Rails related generators
2. Your framework RubyGem (e.g. `newgem` or `rails`) needs to add `rubigen` as a
dependency, so that users of your RubyGem can access the generator framework.
= Creating generatorsThere are two types of generators:
1. 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.
2. 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 FrameworkWithout 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 # Application 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 templatesThe `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}"
exit(0)
endrequire '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
enddef 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
endprotected
def banner
<<-EOS
Create a stub for #{File.basename $0} to get started.Usage: #{File.basename $0} /path/to/your/app [options]"
EOS
enddef 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
)
endEasy peasy.
== Creating a Component Generator for your Framework