How to change source for a custom rails generator? (Thor)

后端 未结 4 1937
遥遥无期
遥遥无期 2020-12-21 15:18

I\'m making a custom generator that generates a new rails app, and I do it like this

require \'thor\'
require \'rails/generators/rails/app/app_generator\'

c         


        
相关标签:
4条回答
  • 2020-12-21 15:43

    The source_paths method doesn't work when using AppBuilder. (which is another option to using rails templates). I have a files directory next to the app_builder.rb file that this class is in. I have this working, though it seems there should still be a more elegant way.

    tree .
    |-- app_builder.rb
    |-- files
         `-- Gemfile
    
    class AppBuilder < Rails::AppBuilder
    
      def initialize generator
        super generator
        path = File.expand_path( File.join( '..', File.dirname( __FILE__ )) )
        source_paths << path
      end
    
      def gemfile
        copy_file 'files/Gemfile', 'Gemfile'
      end
    

    and then on the console:

    rails new my_app -b path_to_app_builder.rb

    The dots are required since the ruby file 'app_builder.rb' is slurped up and eval'd after the rails new command changes into the new app directory (I think).

    0 讨论(0)
  • 2020-12-21 15:45

    It's an old post, however, the problem remains the same, I spent time to figure that out. I let a comment here if it can help.

    Rails add by default the path lib/templates so you can custom any templates by copying them in this directory.

    Check out the correct directories structures https://github.com/rails/rails/tree/v6.0.1/railties/lib/rails/generators/rails

    There is subtle though and is not so obvious to catch.

    Take for instance the helper generator, as mentioned in the official Rails documentation, the structure is

    https://github.com/rails/rails/tree/v6.0.1/railties/lib/rails/generators/rails/helper

    - helper
      - templates
        - helper.rb.tt
      - helper_generator.rb 
    

    Here, what Railties expects to find in your project:

    - lib
      - templates 
        - helper
          - helper.rb
    

    your helper.rb is a copy of helper.rb.tt

    the last thing, if you plan to use it in Rails::Engine you have to tell it to load that path

    # lib/blorgh/engine.rb 
    module Blorgh
      class Engine < ::Rails::Engine
        isolate_namespace Blorgh
        config.generators.templates << File.expand_path('../templates', __dir__)
      end
    end
    

    Really hope that can help and save time for others.

    1. https://github.com/rails/rails/blob/v6.0.1/railties/lib/rails/application/configuration.rb#L188
    2. https://guides.rubyonrails.org/generators.html#customizing-your-workflow-by-changing-generators-templates
    3. https://github.com/rails/rails/blob/v6.0.1/railties/CHANGELOG.md
    4. https://guides.rubyonrails.org/engines.html
    0 讨论(0)
  • 2020-12-21 15:53

    This worked:

    require 'thor'
    require 'rails/generators/rails/app/app_generator'
    
    module Thor::Actions
      def source_paths
        [MY_TEMPLATES]
      end
    end
    
    class AppBuilder < Rails::AppBuilder
      ...
    end
    

    I don't understand why, but I've spent too much time on this already, so I don't care.

    0 讨论(0)
  • 2020-12-21 15:53

    Thor will access your source_paths method and add these to the defaults:

      # Returns the source paths in the following order:
      #
      #   1) This class source paths
      #   2) Source root
      #   3) Parents source paths
      #
      def source_paths_for_search
        paths = []
        paths += self.source_paths
        paths << self.source_root if self.source_root
        paths += from_superclass(:source_paths, [])
        paths
      end
    

    So all you need to do in your class is:

    class NewgemGenerator < Thor::Group
    
      include Thor::Actions
    
      def source_paths
        ['/whatever', './templates']
      end
    
    end
    

    Hope this helps :)

    0 讨论(0)
提交回复
热议问题