johnkoht
johnkoht

Reputation: 602

Rails Gem: Running All Generators for given Namespace

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!

Upvotes: 3

Views: 387

Answers (2)

Emil
Emil

Reputation: 1260

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 .

Upvotes: 1

rovermicrover
rovermicrover

Reputation: 1453

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.

Upvotes: 1

Related Questions