aboutsummaryrefslogtreecommitdiffstats
path: root/railties/lib/rails/command.rb
blob: 6587984b538758bacfdced298959d19b32ecc87e (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
require 'rails/commands/commands_tasks'

module Rails
  class Command
    attr_reader :argv

    def initialize(argv = [])
      @argv = argv

      @option_parser = build_option_parser
      @options = {}
    end

    def self.run(task_name, argv)
      command_name = command_name_for(task_name)

      if command = command_for(command_name)
        command.new(argv).run(command_name)
      else
        Rails::CommandsTasks.new(argv).run_command!(task_name)
      end
    end

    def run(command_name)
      parse_options_for(command_name)
      @option_parser.parse! @argv

      public_send(command_name)
    end

    def self.options_for(command_name, &options_to_parse)
      @@command_options[command_name] = options_to_parse
    end

    def self.set_banner(command_name, banner)
      options_for(command_name) { |opts, _| opts.banner = banner }
    end

    private
      @@commands = []
      @@command_options = {}

      def parse_options_for(command_name)
        @@command_options.fetch(command_name, proc {}).call(@option_parser, @options)
      end

      def build_option_parser
        OptionParser.new do |opts|
          opts.on('-h', '--help', 'Show this help.') do
            puts opts
            exit
          end
        end
      end

      def self.inherited(command)
        @@commands << command
      end

      def self.command_name_for(task_name)
        task_name.gsub(':', '_').to_sym
      end

      def self.command_for(command_name)
        @@commands.find do |command|
          command.public_instance_methods.include?(command_name)
        end
      end
  end
end