From 2ddb5997108c4612dd96747fb082ba7f93427a31 Mon Sep 17 00:00:00 2001
From: Chuck Callebs <chuck@callebs.io>
Date: Mon, 30 Nov 2015 16:33:33 -0500
Subject: Add Rails command infrastructure and encapsulate development caching

---
 railties/lib/rails/commands.rb                |  1 +
 railties/lib/rails/commands/command.rb        | 78 +++++++++++++++++++++++++++
 railties/lib/rails/commands/commands_tasks.rb |  6 ++-
 railties/lib/rails/commands/dev_cache.rb      | 21 ++++++++
 railties/lib/rails/tasks.rb                   |  1 -
 railties/lib/rails/tasks/dev.rake             | 14 -----
 6 files changed, 105 insertions(+), 16 deletions(-)
 create mode 100644 railties/lib/rails/commands/command.rb
 create mode 100644 railties/lib/rails/commands/dev_cache.rb
 delete mode 100644 railties/lib/rails/tasks/dev.rake

(limited to 'railties/lib/rails')

diff --git a/railties/lib/rails/commands.rb b/railties/lib/rails/commands.rb
index 12bd73db24..d4d8d3ac75 100644
--- a/railties/lib/rails/commands.rb
+++ b/railties/lib/rails/commands.rb
@@ -13,6 +13,7 @@ aliases = {
 command = ARGV.shift
 command = aliases[command] || command
 
+require 'rails/commands/dev_cache'
 require 'rails/commands/commands_tasks'
 
 Rails::CommandsTasks.new(ARGV).run_command!(command)
diff --git a/railties/lib/rails/commands/command.rb b/railties/lib/rails/commands/command.rb
new file mode 100644
index 0000000000..ffd1a50c79
--- /dev/null
+++ b/railties/lib/rails/commands/command.rb
@@ -0,0 +1,78 @@
+module Rails
+  module Commands
+    class Command
+      attr_reader :argv
+
+      def initialize(argv = '')
+        @argv = argv
+
+        @option_parser = build_option_parser
+        @options = {}
+      end
+
+      def run(task_name)
+        command_name = self.class.command_name_for(task_name)
+
+        parse_options_for(command_name)
+        @option_parser.parse! @argv
+
+        if command_instance = command_for(command_name)
+          command_instance.public_send(command_name)
+        else
+          puts @option_parser
+        end
+      end
+
+      def self.options_for(command_name, &options_to_parse)
+        @@command_options[command_name] = options_to_parse
+      end
+
+      def self.command_name_for(task_name)
+        task_name.gsub(':', '_').to_sym
+      end
+
+      def self.set_banner(command_name, banner)
+        options_for(command_name) { |opts, _| opts.banner = banner }
+      end
+
+      def exists?(task_name)
+        command_name = self.class.command_name_for(task_name)
+        !command_for(command_name).nil?
+      end
+
+      private
+        @@commands = []
+        @@command_options = {}
+
+        def parse_options_for(command_name)
+          @@command_options.fetch(command_name, -> {}).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 command_for(command_name)
+          klass = @@commands.find do |command|
+            command_instance_methods = command.public_instance_methods
+            command_instance_methods.include?(command_name)
+          end
+
+          if klass
+            klass.new(@argv)
+          else
+            nil
+          end
+        end
+    end
+  end
+end
diff --git a/railties/lib/rails/commands/commands_tasks.rb b/railties/lib/rails/commands/commands_tasks.rb
index 685d55eea8..f79b40b2ab 100644
--- a/railties/lib/rails/commands/commands_tasks.rb
+++ b/railties/lib/rails/commands/commands_tasks.rb
@@ -32,11 +32,15 @@ EOT
 
     def initialize(argv)
       @argv = argv
+      @rails_command = Rails::Commands::Command.new(argv)
     end
 
     def run_command!(command)
       command = parse_command(command)
-      if COMMAND_WHITELIST.include?(command)
+
+      if @rails_command.exists?(command)
+        @rails_command.run(command)
+      elsif COMMAND_WHITELIST.include?(command)
         send(command)
       else
         write_error_message(command)
diff --git a/railties/lib/rails/commands/dev_cache.rb b/railties/lib/rails/commands/dev_cache.rb
new file mode 100644
index 0000000000..43675c0e69
--- /dev/null
+++ b/railties/lib/rails/commands/dev_cache.rb
@@ -0,0 +1,21 @@
+require 'rails/commands/command'
+
+module Rails
+  module Commands
+    # This is a wrapper around the Rails dev:cache command
+    class DevCache < Command
+      set_banner :dev_cache, 'Toggle development mode caching on/off'      
+      def dev_cache
+        if File.exist? 'tmp/caching-dev.txt'
+          File.delete 'tmp/caching-dev.txt'
+          puts 'Development mode is no longer being cached.'
+        else
+          FileUtils.touch 'tmp/caching-dev.txt'
+          puts 'Development mode is now being cached.'
+        end
+
+        FileUtils.touch 'tmp/restart.txt'
+      end
+    end
+  end
+end
diff --git a/railties/lib/rails/tasks.rb b/railties/lib/rails/tasks.rb
index d3e33584d7..d60eaf6f4f 100644
--- a/railties/lib/rails/tasks.rb
+++ b/railties/lib/rails/tasks.rb
@@ -3,7 +3,6 @@ require 'rake'
 # Load Rails Rakefile extensions
 %w(
   annotations
-  dev
   framework
   initializers
   log
diff --git a/railties/lib/rails/tasks/dev.rake b/railties/lib/rails/tasks/dev.rake
deleted file mode 100644
index 4593100465..0000000000
--- a/railties/lib/rails/tasks/dev.rake
+++ /dev/null
@@ -1,14 +0,0 @@
-namespace :dev do
-  desc 'Toggle development mode caching on/off'
-  task :cache do
-    if File.exist? 'tmp/caching-dev.txt'
-      File.delete 'tmp/caching-dev.txt'
-      puts 'Development mode is no longer being cached.'
-    else
-      FileUtils.touch 'tmp/caching-dev.txt'
-      puts 'Development mode is now being cached.'
-    end
-
-    FileUtils.touch 'tmp/restart.txt'
-  end
-end
-- 
cgit v1.2.3