[Nitro] Generating scaffolding / stub codes?
James Britt
james_b at neurogami.com
Tue Feb 21 23:14:10 EST 2006
Bryan Soto wrote:
> On 2/21/06, *James Britt* <james_b at neurogami.com
...
>
> On the other hand, I wrote my own controller stub generator with very
> little effort.
>
> Perhaps there should be a way for people to submit their own generators
> for possible inclusion in future releases.
>
>
> If you're interested in submitting them, please just email them here. :)
> It's not exactly a formal process, but it could be a nice way to pioneer
> things.
I followed a times-tested procedure: Copy the files for 'app' and munge
them up. BTW, my controller gen no longer works, as I've installed
Nitro 0.28 and I now get this:
can't activate gen (= 0.27.0), already activated gen-0.28.0]
(Gem::Exception)
So there needs to be a way to separate the custom templates from
specific versions of gen, Nitro, etc.
But, assuming that:
Calling
gen app MyAppName
drives a call to
require "gen/#{generator}/gen.rb"
AKA
require "gen/app/gen.rb"
inside the gen script
So
gen controller Main
would invoke
require "gen/controller/gen.rb"
So created a new subdir, 'controller', off the gen directory (in my
gems tree)
As with the 'app' subdir needed for the app generator, my new folder has
a gen.rb file.
Basically stealing the behavior of the 'app' generator, I came up with this:
$NITRO_NO_ENVIRONMENT = true
require 'nano/dir/self/recurse'
require 'gen'
require 'nitro'
PROTO_DIR = File.join( Nitro::LibPath, '..', 'controller_proto')
# gen controller - Nitro controller generator.
#
# This generator will create some basic files to get you
# started fleshing out your Nitro web controller.
# The proto directory structure in the standard Nitro
# distribution is used as reference.
#
# === Example
#
# gen controller ~/my_controller
#
# This will generate a new Nitro controller in the
# ~/my_controller folder.
class AppGen < Gen
def setup
@ctrl_name = ARGV[0] || usage()
@ctrl_path = File.expand_path( File.dirname( @ctrl_name ) )
end
def run
if File.exists? @ctrl_name
STDERR.puts "ERROR: Path #{@ctrl_name} already exists! Aborting!"
exit 1
end
puts "Copying proto controller to '#@ctrl_name'"
src = IO.read( "#{PROTO_DIR}/proto_controller.rb" )
src.gsub!( 'PROTOTEMPLATES', @ctrl_name.downcase )
src.gsub!( 'PROTO', @ctrl_name.capitalize )
File.open( "#{@ctrl_path}/#{@ctrl_name.downcase}_controller.rb" ,
'wb' ){ |f| f.puts src}
puts 'Done'
end
end
$generator = AppGen.new
# The end :)
This first thing to note is that this code, as with 'app', expects to
find template files in PROTO_DIR. It then copies over those files to the
target location.
I created a 'controller_proto' along side the existing 'proto' dir used
by the 'app' generator. But you can see that this ties my customer
generator to that version of Nitro. :(
My generator needed to create class code based on the given for the
controller, so my template files have some BIGBLOCK strings that get
swapped out with the correct values.
class PROTOController < Nitro::Controller
def initialize( *args )
@template_root = "/templates/PROTOTEMPLATES"
super *args
end
private
def myname
__FILE__.split( '/' ).last.to_s
end
end
It's pretty simple; the issues now are figuring out how and where to
store such generators so that updating gen and/or Nitro does not break
anything. (I seem to recall issues with rubygems and installing items
to DATADIR or something. One hackish option is to install the prototype
folders to RUBY_BIN (or something) or some other known fixed place.)
> ...
> Re: gems;
>
> Looking at the gen script, it seems that if you follow the directory
> structure gen/#{generator}/gen.rb, or to use your controller generator
> as an example,
>
> gen/controller/gen.rb
>
> # gen controller params_go_here
>
> would actually find it now thanks to how Rubygems works. Completely
> untested though. Of course you'd potentially have a lot of collisions if
> it caught on so some formal system would have to be worked out.
That's how my stuff worked. Yes, collisions are possible; that's true
now of any gem, I believe. Have to see how gems handles it if I try to
install a gem that claims an existing name and version of some other gem.
> I'd
> imagine that's why the Rails folk went with the plugin idea?
>
I believe that plug-ins install to a specific application; they become
part of that application's base code and alter the core Rails classes at
runtime (I think; the one plugin I tried so screwed my Rails app I
removed it fairly quick, and haven't had a reason to use any others.)
But a Nitro generator (though there is no good reason to couple them to
Nitro, really) should be available system-wide.
--
James Britt
“Design depends largely on constraints.”
— Charles Eames
More information about the Nitro-general
mailing list