3

I'm developing a gem core with multiple sub modules, each it's own gem. As a developer, you'll be able to install the core and any other of the gems. How can I create a rake task or generator to run the generators for ALL of the installed gems with generators under the main gem namespace.

Example, if I my gem is called admin:

module Admin
  module Generators
    class InstallGenerator < Rails::Generators::Base
    end
  end
end

And I have another generator for one of the sub-gems:

module Admin
  module Generators
    class PostsGenerator < Rails::Generators::Base
    end
  end
end

And another one:

module Admin
  module Generators
    class TagslGenerator < Rails::Generators::Base
    end
  end
end

And there might be up to 10 more gems that can be installed. Rather than rail g admin:... installing each one, I would like to create a rake task or generator that runs all of the tasks.

Thanks in advance!

johnkoht
  • 602
  • 6
  • 11
  • A rake task to run other rake tasks ? [This tutorial](http://jasonseifer.com/2010/04/06/rake-tutorial) explains how to do that. Does that help ? – Emil Apr 05 '13 at 20:52
  • Well these aren't rake tasks, they are generators. But I don't want to run all of them, only the ones available in the Namespace. So any generators in the Admin namspace will be run. – johnkoht Apr 05 '13 at 20:56

2 Answers2

1

First check out the following question and answer.

Find classes available in a Module

So all you have to do is access

Admin::Generators.constants.each do |c| 
   c = Admin::Generators.const_get(c)
   if c < Rails::Generators::Base
     c.new.run(your_args)
   end
end

Only thing is I have never invoked a generator like this so it might be a little bit more then c.new.run, but I think that should do it.

Community
  • 1
  • 1
rovermicrover
  • 1,453
  • 1
  • 15
  • 21
  • Need to add `c = Admin::Generators.const_get(c)` before trying `c < Rails::Generators::Base` – Emil Apr 05 '13 at 22:47
1

Keep an "AllGenerator" class under Admin module. The generator will have to do the following :

  1. For each class under the namespace that is a generator class,
  2. get the namespace from classname.
  3. Call the invoke method with the namespace.

Something like this :

module Admin
  module Generators
    class AllGenerator < Rails::Generators::Base
      def generator
        Rails::Generators.lookup!
        Admin::Generators.constants.each do |const|
          generator_class = Admin::Generators.const_get(const)
          next if self.class == generator_class
          if generator_class < Rails::Generators::Base
            namespace = generator_klass_to_namespace(generator_class)
            invoke(namespace)
          end
        end
      end
      private
        def generator_klass_to_namespace(klass)
          namespace = Thor::Util.namespace_from_thor_class(klass)
          return namespace.sub(/_generator$/, '').sub(/:generators:/, ':')
        end
    end

  end
end

Here's the link to the gist with complete tested code

This way, running rails g admin:all would run every other generator directly under Admin::Generators .

Emil
  • 1,240
  • 1
  • 15
  • 27
  • Looping over the Admin::Generators within the AllGenerator only returns the AllGenerator. When I run `rails g`, though, I can see all of the generators in the list and outputted to the console. – johnkoht Apr 05 '13 at 22:01
  • Can you share a gist of the code you are using to iterate over the generators ? – Emil Apr 05 '13 at 22:26
  • The other answer has an issue in it - need to add `const_get` to get the actual classes. See the updated answer. ( I've not tried this yet, hope it works :) ) – Emil Apr 05 '13 at 22:46
  • Thanks for this help. Looks like this works for the most part, but the AllGenerator doesn't seem to load any of the other generators. [Here's a gist](https://gist.github.com/johnkoht/9037bd748513c4a20ece) of the AllGenerator. When I run `rails g` I see all of my `puts` statements and I see all of the generators but not when I run the All command. Any thoughts? – johnkoht Apr 06 '13 at 14:17
  • Finally I tested this and guess what, it didn't work. I've fixed it, [here's the gist](https://gist.github.com/emilsoman/09dad782ef775a064458). I've tested this in a Rails app and it works as expected. Hope that helps. – Emil Apr 06 '13 at 17:38