# Creating executable rails 3 generators

**URL:** <https://www.ruby-forum.com/t/creating-executable-rails-3-generators/182472>\
**Category:** Rails\
**Created:** [January 28, 2010, 5:58pm UTC](https://www.ruby-forum.com/t/creating-executable-rails-3-generators/182472 "2010-01-28T17:58:20Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![Kristian](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/e8c25b/32.png) [@Kristian](https://www.ruby-forum.com/u/Kristian)\
**Post date:** [January 28, 2010, 5:58pm UTC](https://www.ruby-forum.com/t/creating-executable-rails-3-generators/182472/1 "2010-01-28T17:58:20Z")

</div>

For inspiration I have been looking into rails 3.0pre

## I found this in the file _bin/rails_

…  
require ‘rails/generators’  
require ‘generators/rails/app/app\_generator’

## Rails::Generators::AppGenerator.start

Aha! Require the app generator and then start it 🙂

## then in _framework.task_

…  
desc “Applies the template supplied by LOCATION=/path/to/template”  
task :template do  
…  
require ‘rails/generators’  
require ‘generators/rails/app/app\_generator’  
generator = Rails::Generators::AppGenerator.new [Rails.root],  
{}, :destination\_root =\> Rails.root  
generator.apply template, :verbose =\> false  
end

namespace :update do  
def invoke\_from\_app\_generator(method)  
require ‘rails/generators’  
require ‘generators/rails/app/app\_generator’

```
  generator = Rails::Generators::AppGenerator.new ["rails"],

```

{ :with\_dispatchers =\> true },  
:destination\_root =\> Rails.root  
generator.invoke(method)  
end

```
desc "Update config/boot.rb from your current rails install"
task :configs do
  invoke_from_app_generator :create_boot_file
  invoke_from_app_generator :create_config_files
end

desc "Update Prototype javascripts from your current rails

```

install"  
task :javascripts do  
invoke\_from\_app\_generator :create\_prototype\_files  
end

```
desc "Add new scripts to the application script/ directory"
task :scripts do
  invoke_from_app_generator :create_script_files
end

```

–

Here the utility method invoke\_from\_app\_generator requires the app  
generator and invokes a specific method.  
Specific tasks then use this utility method to execute specific parts  
of the app generator as needed…

## and in railties3.0pre.gemspec

## … s.default\_executable = %q{rails} s.executables = [“rails”] …

Defines the executable rails found in the _bin_ folder

So I assume, to make a gem executable, you simply need to

1. define the executables in the gemspec
2. put an executable in the bin folder, fx bin/my\_executable
3. have that executable require a generator and then call start on the  
generator
4. install the gem
5. run the executable passing in any defined arguments as per the  
generator

Commens, ideas, suggestions?

Thanks!

Kristian

---

<div class="post-metadata">

**Author:** ![Kristian](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/e8c25b/32.png) [@Kristian](https://www.ruby-forum.com/u/Kristian)\
**Post date:** [January 28, 2010, 6:41pm UTC](https://www.ruby-forum.com/t/creating-executable-rails-3-generators/182472/2 "2010-01-28T18:41:04Z")

</div>

It almost works… except I run into the following issue

module Nifty  
module Generators  
class ScaffoldGenerator \< Base  
…  
def initialize(\*args, &block)  
super

```
    args_for_c_m.each do |arg|
      if arg == '!'
        options[:invert] = true <<<<<< line 53

```

…  
if @model\_attributes.empty?  
options[:skip\_model] = true \<\<\<\<\<\<\<\<

## end

## $ nifty\_scaffold blip /opt/local/lib/ruby/gems/1.9.1/gems/railties-3.0.pre/lib/rails/vendor/ thor-0.12.3/lib/thor/core\_ext/hash\_with\_indifferent\_access.rb:26:in `[] =': can't modify frozen hash (RuntimeError) from /opt/local/lib/ruby/gems/1.9.1/gems/railties-3.0.pre/lib/rails/ vendor/thor-0.12.3/lib/thor/core_ext/hash_with_indifferent_access.rb: 26:in`[]=’ from /opt/local/lib/ruby/gems/1.9.1/gems/very\_nifty\_generators-0.1.2/ lib/generators/nifty/scaffold/scaffold\_generator.rb:53:in `initialize’

Is there a nice way to fix this? Do I have to create a non-frozen  
custom options collection or someone has a better idea?

Kristian
