Created
November 7, 2009 05:59
-
-
Save mattetti/228560 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
From 6cfd58aa74c0c705d25e33113f847af1bfc2d207 Mon Sep 17 00:00:00 2001 | |
From: =?utf-8?q?Jos=C3=A9=20Valim?= <jose.valim@gmail.com> | |
Date: Fri, 6 Nov 2009 23:28:58 -0200 | |
Subject: [PATCH] Update Rails Generators to use Thor 0.12.0. | |
--- | |
railties/lib/rails/generators.rb | 2 +- | |
railties/lib/rails/generators/base.rb | 4 + | |
.../lib/rails/vendor/thor-0.11.8/CHANGELOG.rdoc | 77 --- | |
railties/lib/rails/vendor/thor-0.11.8/LICENSE | 20 - | |
railties/lib/rails/vendor/thor-0.11.8/README.rdoc | 234 --------- | |
railties/lib/rails/vendor/thor-0.11.8/Thorfile | 63 --- | |
railties/lib/rails/vendor/thor-0.11.8/lib/thor.rb | 242 --------- | |
.../rails/vendor/thor-0.11.8/lib/thor/actions.rb | 273 ----------- | |
.../thor-0.11.8/lib/thor/actions/create_file.rb | 102 ---- | |
.../thor-0.11.8/lib/thor/actions/directory.rb | 89 ---- | |
.../lib/thor/actions/empty_directory.rb | 133 ----- | |
.../lib/thor/actions/file_manipulation.rb | 219 --------- | |
.../lib/thor/actions/inject_into_file.rb | 101 ---- | |
.../lib/rails/vendor/thor-0.11.8/lib/thor/base.rb | 517 -------------------- | |
.../thor/core_ext/hash_with_indifferent_access.rb | 75 --- | |
.../thor-0.11.8/lib/thor/core_ext/ordered_hash.rb | 100 ---- | |
.../lib/rails/vendor/thor-0.11.8/lib/thor/error.rb | 27 - | |
.../lib/rails/vendor/thor-0.11.8/lib/thor/group.rb | 263 ---------- | |
.../vendor/thor-0.11.8/lib/thor/invocation.rb | 178 ------- | |
.../rails/vendor/thor-0.11.8/lib/thor/parser.rb | 4 - | |
.../vendor/thor-0.11.8/lib/thor/parser/argument.rb | 67 --- | |
.../thor-0.11.8/lib/thor/parser/arguments.rb | 145 ------ | |
.../vendor/thor-0.11.8/lib/thor/parser/option.rb | 132 ----- | |
.../vendor/thor-0.11.8/lib/thor/parser/options.rb | 142 ------ | |
.../vendor/thor-0.11.8/lib/thor/rake_compat.rb | 66 --- | |
.../rails/vendor/thor-0.11.8/lib/thor/runner.rb | 299 ----------- | |
.../lib/rails/vendor/thor-0.11.8/lib/thor/shell.rb | 78 --- | |
.../vendor/thor-0.11.8/lib/thor/shell/basic.rb | 219 --------- | |
.../vendor/thor-0.11.8/lib/thor/shell/color.rb | 108 ---- | |
.../lib/rails/vendor/thor-0.11.8/lib/thor/task.rb | 122 ----- | |
.../lib/rails/vendor/thor-0.11.8/lib/thor/util.rb | 251 ---------- | |
.../rails/vendor/thor-0.11.8/lib/thor/version.rb | 3 - | |
.../lib/rails/vendor/thor-0.12.0/CHANGELOG.rdoc | 82 +++ | |
railties/lib/rails/vendor/thor-0.12.0/LICENSE | 20 + | |
railties/lib/rails/vendor/thor-0.12.0/README.rdoc | 234 +++++++++ | |
railties/lib/rails/vendor/thor-0.12.0/Thorfile | 63 +++ | |
railties/lib/rails/vendor/thor-0.12.0/lib/thor.rb | 242 +++++++++ | |
.../rails/vendor/thor-0.12.0/lib/thor/actions.rb | 273 +++++++++++ | |
.../thor-0.12.0/lib/thor/actions/create_file.rb | 103 ++++ | |
.../thor-0.12.0/lib/thor/actions/directory.rb | 93 ++++ | |
.../lib/thor/actions/empty_directory.rb | 134 +++++ | |
.../lib/thor/actions/file_manipulation.rb | 219 +++++++++ | |
.../lib/thor/actions/inject_into_file.rb | 101 ++++ | |
.../lib/rails/vendor/thor-0.12.0/lib/thor/base.rb | 517 ++++++++++++++++++++ | |
.../thor/core_ext/hash_with_indifferent_access.rb | 75 +++ | |
.../thor-0.12.0/lib/thor/core_ext/ordered_hash.rb | 100 ++++ | |
.../lib/rails/vendor/thor-0.12.0/lib/thor/error.rb | 27 + | |
.../lib/rails/vendor/thor-0.12.0/lib/thor/group.rb | 263 ++++++++++ | |
.../vendor/thor-0.12.0/lib/thor/invocation.rb | 178 +++++++ | |
.../rails/vendor/thor-0.12.0/lib/thor/parser.rb | 4 + | |
.../vendor/thor-0.12.0/lib/thor/parser/argument.rb | 67 +++ | |
.../thor-0.12.0/lib/thor/parser/arguments.rb | 145 ++++++ | |
.../vendor/thor-0.12.0/lib/thor/parser/option.rb | 132 +++++ | |
.../vendor/thor-0.12.0/lib/thor/parser/options.rb | 142 ++++++ | |
.../vendor/thor-0.12.0/lib/thor/rake_compat.rb | 66 +++ | |
.../rails/vendor/thor-0.12.0/lib/thor/runner.rb | 299 +++++++++++ | |
.../lib/rails/vendor/thor-0.12.0/lib/thor/shell.rb | 78 +++ | |
.../vendor/thor-0.12.0/lib/thor/shell/basic.rb | 219 +++++++++ | |
.../vendor/thor-0.12.0/lib/thor/shell/color.rb | 108 ++++ | |
.../lib/rails/vendor/thor-0.12.0/lib/thor/task.rb | 122 +++++ | |
.../lib/rails/vendor/thor-0.12.0/lib/thor/util.rb | 251 ++++++++++ | |
.../rails/vendor/thor-0.12.0/lib/thor/version.rb | 3 + | |
62 files changed, 4365 insertions(+), 4350 deletions(-) | |
delete mode 100644 railties/lib/rails/vendor/thor-0.11.8/CHANGELOG.rdoc | |
delete mode 100644 railties/lib/rails/vendor/thor-0.11.8/LICENSE | |
delete mode 100644 railties/lib/rails/vendor/thor-0.11.8/README.rdoc | |
delete mode 100644 railties/lib/rails/vendor/thor-0.11.8/Thorfile | |
delete mode 100644 railties/lib/rails/vendor/thor-0.11.8/lib/thor.rb | |
delete mode 100644 railties/lib/rails/vendor/thor-0.11.8/lib/thor/actions.rb | |
delete mode 100644 railties/lib/rails/vendor/thor-0.11.8/lib/thor/actions/create_file.rb | |
delete mode 100644 railties/lib/rails/vendor/thor-0.11.8/lib/thor/actions/directory.rb | |
delete mode 100644 railties/lib/rails/vendor/thor-0.11.8/lib/thor/actions/empty_directory.rb | |
delete mode 100644 railties/lib/rails/vendor/thor-0.11.8/lib/thor/actions/file_manipulation.rb | |
delete mode 100644 railties/lib/rails/vendor/thor-0.11.8/lib/thor/actions/inject_into_file.rb | |
delete mode 100644 railties/lib/rails/vendor/thor-0.11.8/lib/thor/base.rb | |
delete mode 100644 railties/lib/rails/vendor/thor-0.11.8/lib/thor/core_ext/hash_with_indifferent_access.rb | |
delete mode 100644 railties/lib/rails/vendor/thor-0.11.8/lib/thor/core_ext/ordered_hash.rb | |
delete mode 100644 railties/lib/rails/vendor/thor-0.11.8/lib/thor/error.rb | |
delete mode 100644 railties/lib/rails/vendor/thor-0.11.8/lib/thor/group.rb | |
delete mode 100644 railties/lib/rails/vendor/thor-0.11.8/lib/thor/invocation.rb | |
delete mode 100644 railties/lib/rails/vendor/thor-0.11.8/lib/thor/parser.rb | |
delete mode 100644 railties/lib/rails/vendor/thor-0.11.8/lib/thor/parser/argument.rb | |
delete mode 100644 railties/lib/rails/vendor/thor-0.11.8/lib/thor/parser/arguments.rb | |
delete mode 100644 railties/lib/rails/vendor/thor-0.11.8/lib/thor/parser/option.rb | |
delete mode 100644 railties/lib/rails/vendor/thor-0.11.8/lib/thor/parser/options.rb | |
delete mode 100644 railties/lib/rails/vendor/thor-0.11.8/lib/thor/rake_compat.rb | |
delete mode 100644 railties/lib/rails/vendor/thor-0.11.8/lib/thor/runner.rb | |
delete mode 100644 railties/lib/rails/vendor/thor-0.11.8/lib/thor/shell.rb | |
delete mode 100644 railties/lib/rails/vendor/thor-0.11.8/lib/thor/shell/basic.rb | |
delete mode 100644 railties/lib/rails/vendor/thor-0.11.8/lib/thor/shell/color.rb | |
delete mode 100644 railties/lib/rails/vendor/thor-0.11.8/lib/thor/task.rb | |
delete mode 100644 railties/lib/rails/vendor/thor-0.11.8/lib/thor/util.rb | |
delete mode 100644 railties/lib/rails/vendor/thor-0.11.8/lib/thor/version.rb | |
create mode 100644 railties/lib/rails/vendor/thor-0.12.0/CHANGELOG.rdoc | |
create mode 100644 railties/lib/rails/vendor/thor-0.12.0/LICENSE | |
create mode 100644 railties/lib/rails/vendor/thor-0.12.0/README.rdoc | |
create mode 100644 railties/lib/rails/vendor/thor-0.12.0/Thorfile | |
create mode 100644 railties/lib/rails/vendor/thor-0.12.0/lib/thor.rb | |
create mode 100644 railties/lib/rails/vendor/thor-0.12.0/lib/thor/actions.rb | |
create mode 100644 railties/lib/rails/vendor/thor-0.12.0/lib/thor/actions/create_file.rb | |
create mode 100644 railties/lib/rails/vendor/thor-0.12.0/lib/thor/actions/directory.rb | |
create mode 100644 railties/lib/rails/vendor/thor-0.12.0/lib/thor/actions/empty_directory.rb | |
create mode 100644 railties/lib/rails/vendor/thor-0.12.0/lib/thor/actions/file_manipulation.rb | |
create mode 100644 railties/lib/rails/vendor/thor-0.12.0/lib/thor/actions/inject_into_file.rb | |
create mode 100644 railties/lib/rails/vendor/thor-0.12.0/lib/thor/base.rb | |
create mode 100644 railties/lib/rails/vendor/thor-0.12.0/lib/thor/core_ext/hash_with_indifferent_access.rb | |
create mode 100644 railties/lib/rails/vendor/thor-0.12.0/lib/thor/core_ext/ordered_hash.rb | |
create mode 100644 railties/lib/rails/vendor/thor-0.12.0/lib/thor/error.rb | |
create mode 100644 railties/lib/rails/vendor/thor-0.12.0/lib/thor/group.rb | |
create mode 100644 railties/lib/rails/vendor/thor-0.12.0/lib/thor/invocation.rb | |
create mode 100644 railties/lib/rails/vendor/thor-0.12.0/lib/thor/parser.rb | |
create mode 100644 railties/lib/rails/vendor/thor-0.12.0/lib/thor/parser/argument.rb | |
create mode 100644 railties/lib/rails/vendor/thor-0.12.0/lib/thor/parser/arguments.rb | |
create mode 100644 railties/lib/rails/vendor/thor-0.12.0/lib/thor/parser/option.rb | |
create mode 100644 railties/lib/rails/vendor/thor-0.12.0/lib/thor/parser/options.rb | |
create mode 100644 railties/lib/rails/vendor/thor-0.12.0/lib/thor/rake_compat.rb | |
create mode 100644 railties/lib/rails/vendor/thor-0.12.0/lib/thor/runner.rb | |
create mode 100644 railties/lib/rails/vendor/thor-0.12.0/lib/thor/shell.rb | |
create mode 100644 railties/lib/rails/vendor/thor-0.12.0/lib/thor/shell/basic.rb | |
create mode 100644 railties/lib/rails/vendor/thor-0.12.0/lib/thor/shell/color.rb | |
create mode 100644 railties/lib/rails/vendor/thor-0.12.0/lib/thor/task.rb | |
create mode 100644 railties/lib/rails/vendor/thor-0.12.0/lib/thor/util.rb | |
create mode 100644 railties/lib/rails/vendor/thor-0.12.0/lib/thor/version.rb | |
diff --git a/railties/lib/rails/generators.rb b/railties/lib/rails/generators.rb | |
index fa2c117..19412c2 100644 | |
--- a/railties/lib/rails/generators.rb | |
+++ b/railties/lib/rails/generators.rb | |
@@ -9,7 +9,7 @@ require 'active_support/core_ext/module/attribute_accessors' | |
require 'active_support/core_ext/string/inflections' | |
# TODO: Do not always push on vendored thor | |
-$LOAD_PATH.unshift("#{File.dirname(__FILE__)}/vendor/thor-0.11.8/lib") | |
+$LOAD_PATH.unshift("#{File.dirname(__FILE__)}/vendor/thor-0.12.0/lib") | |
require 'rails/generators/base' | |
require 'rails/generators/named_base' | |
diff --git a/railties/lib/rails/generators/base.rb b/railties/lib/rails/generators/base.rb | |
index af1bf26..a640054 100644 | |
--- a/railties/lib/rails/generators/base.rb | |
+++ b/railties/lib/rails/generators/base.rb | |
@@ -212,6 +212,10 @@ module Rails | |
def self.inherited(base) #:nodoc: | |
super | |
+ # Cache source root, we need to do this, since __FILE__ is a relative value | |
+ # and can point to wrong directions when inside an specified directory. | |
+ base.source_root | |
+ | |
if base.name && base.name !~ /Base$/ && defined?(Rails.root) && Rails.root | |
path = File.expand_path(File.join(Rails.root, 'lib', 'templates')) | |
if base.name.include?('::') | |
diff --git a/railties/lib/rails/vendor/thor-0.11.8/CHANGELOG.rdoc b/railties/lib/rails/vendor/thor-0.11.8/CHANGELOG.rdoc | |
deleted file mode 100644 | |
index dba25b7..0000000 | |
--- a/railties/lib/rails/vendor/thor-0.11.8/CHANGELOG.rdoc | |
+++ /dev/null | |
@@ -1,77 +0,0 @@ | |
-== TODO | |
- | |
-* Improve spec coverage for Thor::Runner | |
- | |
-== 0.11.x, released 2009-07-01 | |
- | |
-* Added a rake compatibility layer. It allows you to use spec and rdoc tasks on | |
- Thor classes. | |
- | |
-* BACKWARDS INCOMPATIBLE: aliases are not generated automatically anymore | |
- since it wrong behavior to the invocation system. | |
- | |
-* thor help now show information about any class/task. All those calls are | |
- possible: | |
- | |
- thor help describe | |
- thor help describe:amazing | |
- | |
- Or even with default namespaces: | |
- | |
- thor help :spec | |
- | |
-* Thor::Runner now invokes the default task if none is supplied: | |
- | |
- thor describe # invokes the default task, usually help | |
- | |
-* Thor::Runner now works with mappings: | |
- | |
- thor describe -h | |
- | |
-* Added some documentation and code refactoring. | |
- | |
-== 0.9.8, released 2008-10-20 | |
- | |
-* Fixed some tiny issues that were introduced lately. | |
- | |
-== 0.9.7, released 2008-10-13 | |
- | |
-* Setting global method options on the initialize method works as expected: | |
- All other tasks will accept these global options in addition to their own. | |
-* Added 'group' notion to Thor task sets (class Thor); by default all tasks | |
- are in the 'standard' group. Running 'thor -T' will only show the standard | |
- tasks - adding --all will show all tasks. You can also filter on a specific | |
- group using the --group option: thor -T --group advanced | |
- | |
-== 0.9.6, released 2008-09-13 | |
- | |
-* Generic improvements | |
- | |
-== 0.9.5, released 2008-08-27 | |
- | |
-* Improve Windows compatibility | |
-* Update (incorrect) README and task.thor sample file | |
-* Options hash is now frozen (once returned) | |
-* Allow magic predicates on options object. For instance: `options.force?` | |
-* Add support for :numeric type | |
-* BACKWARDS INCOMPATIBLE: Refactor Thor::Options. You cannot access shorthand forms in options hash anymore (for instance, options[:f]) | |
-* Allow specifying optional args with default values: method_options(:user => "mislav") | |
-* Don't write options for nil or false values. This allows, for example, turning color off when running specs. | |
-* Exit with the status of the spec command to help CI stuff out some. | |
- | |
-== 0.9.4, released 2008-08-13 | |
- | |
-* Try to add Windows compatibility. | |
-* BACKWARDS INCOMPATIBLE: options hash is now accessed as a property in your class and is not passed as last argument anymore | |
-* Allow options at the beginning of the argument list as well as the end. | |
-* Make options available with symbol keys in addition to string keys. | |
-* Allow true to be passed to Thor#method_options to denote a boolean option. | |
-* If loading a thor file fails, don't give up, just print a warning and keep going. | |
-* Make sure that we re-raise errors if they happened further down the pipe than we care about. | |
-* Only delete the old file on updating when the installation of the new one is a success | |
-* Make it Ruby 1.8.5 compatible. | |
-* Don't raise an error if a boolean switch is defined multiple times. | |
-* Thor::Options now doesn't parse through things that look like options but aren't. | |
-* Add URI detection to install task, and make sure we don't append ".thor" to URIs | |
-* Add rake2thor to the gem binfiles. | |
-* Make sure local Thorfiles override system-wide ones. | |
diff --git a/railties/lib/rails/vendor/thor-0.11.8/LICENSE b/railties/lib/rails/vendor/thor-0.11.8/LICENSE | |
deleted file mode 100644 | |
index 98722da..0000000 | |
--- a/railties/lib/rails/vendor/thor-0.11.8/LICENSE | |
+++ /dev/null | |
@@ -1,20 +0,0 @@ | |
-Copyright (c) 2008 Yehuda Katz | |
- | |
-Permission is hereby granted, free of charge, to any person obtaining | |
-a copy of this software and associated documentation files (the | |
-"Software"), to deal in the Software without restriction, including | |
-without limitation the rights to use, copy, modify, merge, publish, | |
-distribute, sublicense, and/or sell copies of the Software, and to | |
-permit persons to whom the Software is furnished to do so, subject to | |
-the following conditions: | |
- | |
-The above copyright notice and this permission notice shall be | |
-included in all copies or substantial portions of the Software. | |
- | |
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | |
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | |
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | |
-NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE | |
-LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION | |
-OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | |
-WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |
\ No newline at end of file | |
diff --git a/railties/lib/rails/vendor/thor-0.11.8/README.rdoc b/railties/lib/rails/vendor/thor-0.11.8/README.rdoc | |
deleted file mode 100644 | |
index f1106f0..0000000 | |
--- a/railties/lib/rails/vendor/thor-0.11.8/README.rdoc | |
+++ /dev/null | |
@@ -1,234 +0,0 @@ | |
-= thor | |
- | |
-Map options to a class. Simply create a class with the appropriate annotations | |
-and have options automatically map to functions and parameters. | |
- | |
-Example: | |
- | |
- class App < Thor # [1] | |
- map "-L" => :list # [2] | |
- | |
- desc "install APP_NAME", "install one of the available apps" # [3] | |
- method_options :force => :boolean, :alias => :string # [4] | |
- def install(name) | |
- user_alias = options[:alias] | |
- if options.force? | |
- # do something | |
- end | |
- # other code | |
- end | |
- | |
- desc "list [SEARCH]", "list all of the available apps, limited by SEARCH" | |
- def list(search="") | |
- # list everything | |
- end | |
- end | |
- | |
-Thor automatically maps commands as such: | |
- | |
- thor app:install myname --force | |
- | |
-That gets converted to: | |
- | |
- App.new.install("myname") | |
- # with {'force' => true} as options hash | |
- | |
-1. Inherit from Thor to turn a class into an option mapper | |
-2. Map additional non-valid identifiers to specific methods. In this case, convert -L to :list | |
-3. Describe the method immediately below. The first parameter is the usage information, and the second parameter is the description | |
-4. Provide any additional options that will be available the instance method options. | |
- | |
-== Types for <tt>method_options</tt> | |
- | |
-* :boolean - is parsed as <tt>--option</tt> or <tt>--option=true</tt> | |
-* :string - is parsed as <tt>--option=VALUE</tt> | |
-* :numeric - is parsed as <tt>--option=N</tt> | |
-* :array - is parsed as <tt>--option=one two three</tt> | |
-* :hash - is parsed as <tt>--option=name:string age:integer</tt> | |
- | |
-Besides, method_option allows a default value to be given, examples: | |
- | |
- method_options :force => false | |
- #=> Creates a boolean option with default value false | |
- | |
- method_options :alias => "bar" | |
- #=> Creates a string option with default value "bar" | |
- | |
- method_options :threshold => 3.0 | |
- #=> Creates a numeric option with default value 3.0 | |
- | |
-You can also supply <tt>:option => :required</tt> to mark an option as required. The | |
-type is assumed to be string. If you want a required hash with default values | |
-as option, you can use <tt>method_option</tt> which uses a more declarative style: | |
- | |
- method_option :attributes, :type => :hash, :default => {}, :required => true | |
- | |
-All arguments can be set to nil (except required arguments), by suppling a no or | |
-skip variant. For example: | |
- | |
- thor app name --no-attributes | |
- | |
-In previous versions, aliases for options were created automatically, but now | |
-they should be explicit. You can supply aliases in both short and declarative | |
-styles: | |
- | |
- method_options %w( force -f ) => :boolean | |
- | |
-Or: | |
- | |
- method_option :force, :type => :boolean, :aliases => "-f" | |
- | |
-You can supply as many aliases as you want. | |
- | |
-NOTE: Type :optional available in Thor 0.9.0 was deprecated. Use :string or :boolean instead. | |
- | |
-== Namespaces | |
- | |
-By default, your Thor tasks are invoked using Ruby namespace. In the example | |
-above, tasks are invoked as: | |
- | |
- thor app:install name --force | |
- | |
-However, you could namespace your class as: | |
- | |
- module Sinatra | |
- class App < Thor | |
- # tasks | |
- end | |
- end | |
- | |
-And then you should invoke your tasks as: | |
- | |
- thor sinatra:app:install name --force | |
- | |
-If desired, you can change the namespace: | |
- | |
- module Sinatra | |
- class App < Thor | |
- namespace :myapp | |
- # tasks | |
- end | |
- end | |
- | |
-And then your tasks hould be invoked as: | |
- | |
- thor myapp:install name --force | |
- | |
-== Invocations | |
- | |
-Thor comes with a invocation-dependency system as well which allows a task to be | |
-invoked only once. For example: | |
- | |
- class Counter < Thor | |
- desc "one", "Prints 1, 2, 3" | |
- def one | |
- puts 1 | |
- invoke :two | |
- invoke :three | |
- end | |
- | |
- desc "two", "Prints 2, 3" | |
- def two | |
- puts 2 | |
- invoke :three | |
- end | |
- | |
- desc "three", "Prints 3" | |
- def three | |
- puts 3 | |
- end | |
- end | |
- | |
-When invoking the task one: | |
- | |
- thor counter:one | |
- | |
-The output is "1 2 3", which means that the three task was invoked only once. | |
-You can even invoke tasks from another class, so be sure to check the | |
-documentation. | |
- | |
-== Thor::Group | |
- | |
-Thor has a special class called Thor::Group. The main difference to Thor class | |
-is that it invokes all tasks at once. The example above could be rewritten in | |
-Thor::Group as this: | |
- | |
- class Counter < Thor::Group | |
- desc "Prints 1, 2, 3" | |
- | |
- def one | |
- puts 1 | |
- end | |
- | |
- def two | |
- puts 2 | |
- end | |
- | |
- def three | |
- puts 3 | |
- end | |
- end | |
- | |
-When invoked: | |
- | |
- thor counter | |
- | |
-It prints "1 2 3" as well. Notice you should describe (using the method <tt>desc</tt>) | |
-only the class and not each task anymore. Thor::Group is a great tool to create | |
-generators, since you can define several steps which are invoked in the order they | |
-are defined (Thor::Group is the tool use in generators in Rails 3.0). | |
- | |
-Besides, Thor::Group can parse arguments and options as Thor tasks: | |
- | |
- class Counter < Thor::Group | |
- # number will be available as attr_accessor | |
- argument :number, :type => :numeric, :desc => "The number to start counting" | |
- desc "Prints the 'number' given upto 'number+2'" | |
- | |
- def one | |
- puts number + 0 | |
- end | |
- | |
- def two | |
- puts number + 1 | |
- end | |
- | |
- def three | |
- puts number + 2 | |
- end | |
- end | |
- | |
-The counter above expects one parameter and has the folling outputs: | |
- | |
- thor counter 5 | |
- # Prints "5 6 7" | |
- | |
- thor counter 11 | |
- # Prints "11 12 13" | |
- | |
-You can also give options to Thor::Group, but instead of using <tt>method_option</tt> | |
-and <tt>method_options</tt>, you should use <tt>class_option</tt> and <tt>class_options</tt>. | |
-Both argument and class_options methods are available to Thor class as well. | |
- | |
-== Actions | |
- | |
-Thor comes with several actions which helps with script and generator tasks. You | |
-might be familiar with them since some came from Rails Templates. They are: | |
-<tt>say</tt>, <tt>ask</tt>, <tt>yes?</tt>, <tt>no?</tt>, <tt>add_file</tt>, | |
-<tt>remove_file</tt>, <tt>copy_file</tt>, <tt>template</tt>, <tt>directory</tt>, | |
-<tt>inside</tt>, <tt>run</tt>, <tt>inject_into_file</tt> and a couple more. | |
- | |
-To use them, you just need to include Thor::Actions in your Thor classes: | |
- | |
- class App < Thor | |
- include Thor::Actions | |
- # tasks | |
- end | |
- | |
-Some actions like copy file requires that a class method called source_root is | |
-defined in your class. This is the directory where your templates should be | |
-placed. Be sure to check the documentation. | |
- | |
-== License | |
- | |
-See MIT LICENSE. | |
diff --git a/railties/lib/rails/vendor/thor-0.11.8/Thorfile b/railties/lib/rails/vendor/thor-0.11.8/Thorfile | |
deleted file mode 100644 | |
index f71a1e5..0000000 | |
--- a/railties/lib/rails/vendor/thor-0.11.8/Thorfile | |
+++ /dev/null | |
@@ -1,63 +0,0 @@ | |
-# enconding: utf-8 | |
- | |
-require File.join(File.dirname(__FILE__), "lib", "thor", "version") | |
-require 'thor/rake_compat' | |
-require 'spec/rake/spectask' | |
-require 'rdoc/task' | |
- | |
-GEM_NAME = 'thor' | |
-EXTRA_RDOC_FILES = ["README.rdoc", "LICENSE", "CHANGELOG.rdoc", "VERSION", "Thorfile"] | |
- | |
-class Default < Thor | |
- include Thor::RakeCompat | |
- | |
- Spec::Rake::SpecTask.new(:spec) do |t| | |
- t.libs << 'lib' | |
- t.spec_opts = ['--options', "spec/spec.opts"] | |
- t.spec_files = FileList['spec/**/*_spec.rb'] | |
- end | |
- | |
- Spec::Rake::SpecTask.new(:rcov) do |t| | |
- t.libs << 'lib' | |
- t.spec_opts = ['--options', "spec/spec.opts"] | |
- t.spec_files = FileList['spec/**/*_spec.rb'] | |
- t.rcov = true | |
- t.rcov_dir = "rcov" | |
- end | |
- | |
- RDoc::Task.new do |rdoc| | |
- rdoc.main = "README.rdoc" | |
- rdoc.rdoc_dir = "rdoc" | |
- rdoc.title = GEM_NAME | |
- rdoc.rdoc_files.include(*EXTRA_RDOC_FILES) | |
- rdoc.rdoc_files.include('lib/**/*.rb') | |
- rdoc.options << '--line-numbers' << '--inline-source' | |
- end | |
- | |
- begin | |
- require 'jeweler' | |
- Jeweler::Tasks.new do |s| | |
- s.name = GEM_NAME | |
- s.version = Thor::VERSION | |
- s.rubyforge_project = "textmate" | |
- s.platform = Gem::Platform::RUBY | |
- s.summary = "A scripting framework that replaces rake, sake and rubigen" | |
- s.email = "ruby-thor@googlegroups.com" | |
- s.homepage = "http://yehudakatz.com" | |
- s.description = "A scripting framework that replaces rake, sake and rubigen" | |
- s.authors = ['Yehuda Katz', 'José Valim'] | |
- s.has_rdoc = true | |
- s.extra_rdoc_files = EXTRA_RDOC_FILES | |
- s.require_path = 'lib' | |
- s.bindir = "bin" | |
- s.executables = %w( thor rake2thor ) | |
- s.files = s.extra_rdoc_files + Dir.glob("{bin,lib}/**/*") | |
- s.files.exclude 'spec/sandbox/**/*' | |
- s.test_files.exclude 'spec/sandbox/**/*' | |
- end | |
- | |
- Jeweler::RubyforgeTasks.new | |
- rescue LoadError | |
- puts "Jeweler, or one of its dependencies, is not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com" | |
- end | |
-end | |
diff --git a/railties/lib/rails/vendor/thor-0.11.8/lib/thor.rb b/railties/lib/rails/vendor/thor-0.11.8/lib/thor.rb | |
deleted file mode 100644 | |
index 68944f1..0000000 | |
--- a/railties/lib/rails/vendor/thor-0.11.8/lib/thor.rb | |
+++ /dev/null | |
@@ -1,242 +0,0 @@ | |
-require 'thor/base' | |
-require 'thor/group' | |
-require 'thor/actions' | |
- | |
-class Thor | |
- class << self | |
- # Sets the default task when thor is executed without an explicit task to be called. | |
- # | |
- # ==== Parameters | |
- # meth<Symbol>:: name of the defaut task | |
- # | |
- def default_task(meth=nil) | |
- case meth | |
- when :none | |
- @default_task = 'help' | |
- when nil | |
- @default_task ||= from_superclass(:default_task, 'help') | |
- else | |
- @default_task = meth.to_s | |
- end | |
- end | |
- | |
- # Defines the usage and the description of the next task. | |
- # | |
- # ==== Parameters | |
- # usage<String> | |
- # description<String> | |
- # | |
- def desc(usage, description, options={}) | |
- if options[:for] | |
- task = find_and_refresh_task(options[:for]) | |
- task.usage = usage if usage | |
- task.description = description if description | |
- else | |
- @usage, @desc = usage, description | |
- end | |
- end | |
- | |
- # Maps an input to a task. If you define: | |
- # | |
- # map "-T" => "list" | |
- # | |
- # Running: | |
- # | |
- # thor -T | |
- # | |
- # Will invoke the list task. | |
- # | |
- # ==== Parameters | |
- # Hash[String|Array => Symbol]:: Maps the string or the strings in the array to the given task. | |
- # | |
- def map(mappings=nil) | |
- @map ||= from_superclass(:map, {}) | |
- | |
- if mappings | |
- mappings.each do |key, value| | |
- if key.respond_to?(:each) | |
- key.each {|subkey| @map[subkey] = value} | |
- else | |
- @map[key] = value | |
- end | |
- end | |
- end | |
- | |
- @map | |
- end | |
- | |
- # Declares the options for the next task to be declared. | |
- # | |
- # ==== Parameters | |
- # Hash[Symbol => Object]:: The hash key is the name of the option and the value | |
- # is the type of the option. Can be :string, :array, :hash, :boolean, :numeric | |
- # or :required (string). If you give a value, the type of the value is used. | |
- # | |
- def method_options(options=nil) | |
- @method_options ||= {} | |
- build_options(options, @method_options) if options | |
- @method_options | |
- end | |
- | |
- # Adds an option to the set of class options. If :for is given as option, | |
- # it allows you to change the options from a previous defined task. | |
- # | |
- # def previous_task | |
- # # magic | |
- # end | |
- # | |
- # method_options :foo => :bar, :for => :previous_task | |
- # | |
- # def next_task | |
- # # magic | |
- # end | |
- # | |
- # ==== Parameters | |
- # name<Symbol>:: The name of the argument. | |
- # options<Hash>:: Described below. | |
- # | |
- # ==== Options | |
- # :desc - Description for the argument. | |
- # :required - If the argument is required or not. | |
- # :default - Default value for this argument. It cannot be required and have default values. | |
- # :aliases - Aliases for this option. | |
- # :type - The type of the argument, can be :string, :hash, :array, :numeric or :boolean. | |
- # :group - The group for this options. Use by class options to output options in different levels. | |
- # :banner - String to show on usage notes. | |
- # | |
- def method_option(name, options={}) | |
- scope = if options[:for] | |
- find_and_refresh_task(options[:for]).options | |
- else | |
- method_options | |
- end | |
- | |
- build_option(name, options, scope) | |
- end | |
- | |
- # Parses the task and options from the given args, instantiate the class | |
- # and invoke the task. This method is used when the arguments must be parsed | |
- # from an array. If you are inside Ruby and want to use a Thor class, you | |
- # can simply initialize it: | |
- # | |
- # script = MyScript.new(args, options, config) | |
- # script.invoke(:task, first_arg, second_arg, third_arg) | |
- # | |
- def start(given_args=ARGV, config={}) | |
- super do | |
- meth = normalize_task_name(given_args.shift) | |
- task = all_tasks[meth] | |
- | |
- if task | |
- args, opts = Thor::Options.split(given_args) | |
- config.merge!(:task_options => task.options) | |
- else | |
- args, opts = given_args, {} | |
- end | |
- | |
- task ||= Thor::Task::Dynamic.new(meth) | |
- trailing = args[Range.new(arguments.size, -1)] | |
- new(args, opts, config).invoke(task, trailing || []) | |
- end | |
- end | |
- | |
- # Prints help information. If a task name is given, it shows information | |
- # only about the specific task. | |
- # | |
- # ==== Parameters | |
- # meth<String>:: An optional task name to print usage information about. | |
- # | |
- # ==== Options | |
- # namespace:: When true, shows the namespace in the output before the usage. | |
- # skip_inherited:: When true, does not show tasks from superclass. | |
- # | |
- def help(shell, meth=nil, options={}) | |
- meth, options = nil, meth if meth.is_a?(Hash) | |
- | |
- if meth | |
- task = all_tasks[meth] | |
- raise UndefinedTaskError, "task '#{meth}' could not be found in namespace '#{self.namespace}'" unless task | |
- | |
- shell.say "Usage:" | |
- shell.say " #{banner(task, options[:namespace], false)}" | |
- shell.say | |
- class_options_help(shell, "Class", :Method => task.options.map { |_, o| o }) | |
- shell.say task.description | |
- else | |
- list = (options[:short] ? tasks : all_tasks).map do |_, task| | |
- item = [ banner(task, options[:namespace]) ] | |
- item << "# #{task.short_description}" if task.short_description | |
- item << " " | |
- end | |
- | |
- options[:ident] ||= 2 | |
- if options[:short] | |
- shell.print_list(list, :ident => options[:ident]) | |
- else | |
- shell.say "Tasks:" | |
- shell.print_list(list, :ident => options[:ident]) | |
- end | |
- | |
- Thor::Util.thor_classes_in(self).each do |subclass| | |
- namespace = options[:namespace] == true || subclass.namespace.gsub(/^#{self.namespace}:/, '') | |
- subclass.help(shell, options.merge(:short => true, :namespace => namespace)) | |
- end | |
- | |
- class_options_help(shell, "Class") unless options[:short] | |
- end | |
- end | |
- | |
- protected | |
- | |
- # The banner for this class. You can customize it if you are invoking the | |
- # thor class by another ways which is not the Thor::Runner. It receives | |
- # the task that is going to be invoked and a boolean which indicates if | |
- # the namespace should be displayed as arguments. | |
- # | |
- def banner(task, namespace=true, show_options=true) | |
- task.formatted_usage(self, namespace, show_options) | |
- end | |
- | |
- def baseclass #:nodoc: | |
- Thor | |
- end | |
- | |
- def create_task(meth) #:nodoc: | |
- if @usage && @desc | |
- tasks[meth.to_s] = Thor::Task.new(meth, @desc, @usage, method_options) | |
- @usage, @desc, @method_options = nil | |
- true | |
- elsif self.all_tasks[meth.to_s] || meth.to_sym == :method_missing | |
- true | |
- else | |
- puts "[WARNING] Attempted to create task #{meth.inspect} without usage or description. " << | |
- "Call desc if you want this method to be available as task or declare it inside a " << | |
- "no_tasks{} block. Invoked from #{caller[1].inspect}." | |
- false | |
- end | |
- end | |
- | |
- def initialize_added #:nodoc: | |
- class_options.merge!(method_options) | |
- @method_options = nil | |
- end | |
- | |
- # Receives a task name (can be nil), and try to get a map from it. | |
- # If a map can't be found use the sent name or the default task. | |
- # | |
- def normalize_task_name(meth) #:nodoc: | |
- mapping = map[meth.to_s] | |
- meth = mapping || meth || default_task | |
- meth.to_s.gsub('-','_') # treat foo-bar > foo_bar | |
- end | |
- end | |
- | |
- include Thor::Base | |
- | |
- map HELP_MAPPINGS => :help | |
- | |
- desc "help [TASK]", "Describe available tasks or one specific task" | |
- def help(task=nil) | |
- self.class.help(shell, task, :namespace => task && task.include?(?:)) | |
- end | |
-end | |
diff --git a/railties/lib/rails/vendor/thor-0.11.8/lib/thor/actions.rb b/railties/lib/rails/vendor/thor-0.11.8/lib/thor/actions.rb | |
deleted file mode 100644 | |
index d561ccb..0000000 | |
--- a/railties/lib/rails/vendor/thor-0.11.8/lib/thor/actions.rb | |
+++ /dev/null | |
@@ -1,273 +0,0 @@ | |
-require 'fileutils' | |
- | |
-Dir[File.join(File.dirname(__FILE__), "actions", "*.rb")].each do |action| | |
- require action | |
-end | |
- | |
-class Thor | |
- module Actions | |
- attr_accessor :behavior | |
- | |
- def self.included(base) #:nodoc: | |
- base.extend ClassMethods | |
- end | |
- | |
- module ClassMethods | |
- # Hold source paths for one Thor instance. source_paths_for_search is the | |
- # method responsible to gather source_paths from this current class, | |
- # inherited paths and the source root. | |
- # | |
- def source_paths | |
- @source_paths ||= [] | |
- end | |
- | |
- # 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.respond_to?(:source_root) | |
- paths += from_superclass(:source_paths, []) | |
- paths | |
- end | |
- | |
- # Add runtime options that help actions execution. | |
- # | |
- def add_runtime_options! | |
- class_option :pretend, :type => :boolean, :aliases => "-p", :group => :runtime, | |
- :desc => "Run but do not make any changes" | |
- | |
- class_option :force, :type => :boolean, :aliases => "-f", :group => :runtime, | |
- :desc => "Overwrite files that already exist" | |
- | |
- class_option :skip, :type => :boolean, :aliases => "-s", :group => :runtime, | |
- :desc => "Skip files that already exist" | |
- | |
- class_option :quiet, :type => :boolean, :aliases => "-q", :group => :runtime, | |
- :desc => "Supress status output" | |
- end | |
- end | |
- | |
- # Extends initializer to add more configuration options. | |
- # | |
- # ==== Configuration | |
- # behavior<Symbol>:: The actions default behavior. Can be :invoke or :revoke. | |
- # It also accepts :force, :skip and :pretend to set the behavior | |
- # and the respective option. | |
- # | |
- # destination_root<String>:: The root directory needed for some actions. | |
- # | |
- def initialize(args=[], options={}, config={}) | |
- self.behavior = case config[:behavior].to_s | |
- when "force", "skip" | |
- _cleanup_options_and_set(options, config[:behavior]) | |
- :invoke | |
- when "revoke" | |
- :revoke | |
- else | |
- :invoke | |
- end | |
- | |
- super | |
- self.destination_root = config[:destination_root] | |
- end | |
- | |
- # Wraps an action object and call it accordingly to the thor class behavior. | |
- # | |
- def action(instance) #:nodoc: | |
- if behavior == :revoke | |
- instance.revoke! | |
- else | |
- instance.invoke! | |
- end | |
- end | |
- | |
- # Returns the root for this thor class (also aliased as destination root). | |
- # | |
- def destination_root | |
- @destination_stack.last | |
- end | |
- | |
- # Sets the root for this thor class. Relatives path are added to the | |
- # directory where the script was invoked and expanded. | |
- # | |
- def destination_root=(root) | |
- @destination_stack ||= [] | |
- @destination_stack[0] = File.expand_path(root || '') | |
- end | |
- | |
- # Returns the given path relative to the absolute root (ie, root where | |
- # the script started). | |
- # | |
- def relative_to_original_destination_root(path, remove_dot=true) | |
- path = path.gsub(@destination_stack[0], '.') | |
- remove_dot ? (path[2..-1] || '') : path | |
- end | |
- | |
- # Holds source paths in instance so they can be manipulated. | |
- # | |
- def source_paths | |
- @source_paths ||= self.class.source_paths_for_search | |
- end | |
- | |
- # Receives a file or directory and search for it in the source paths. | |
- # | |
- def find_in_source_paths(file) | |
- relative_root = relative_to_original_destination_root(destination_root, false) | |
- | |
- source_paths.each do |source| | |
- source_file = File.expand_path(file, File.join(source, relative_root)) | |
- return source_file if File.exists?(source_file) | |
- end | |
- | |
- if source_paths.empty? | |
- raise Error, "You don't have any source path defined for class #{self.class.name}. To fix this, " << | |
- "you can define a source_root in your class." | |
- else | |
- raise Error, "Could not find #{file.inspect} in source paths." | |
- end | |
- end | |
- | |
- # Do something in the root or on a provided subfolder. If a relative path | |
- # is given it's referenced from the current root. The full path is yielded | |
- # to the block you provide. The path is set back to the previous path when | |
- # the method exits. | |
- # | |
- # ==== Parameters | |
- # dir<String>:: the directory to move to. | |
- # config<Hash>:: give :verbose => true to log and use padding. | |
- # | |
- def inside(dir='', config={}, &block) | |
- verbose = config.fetch(:verbose, false) | |
- | |
- say_status :inside, dir, verbose | |
- shell.padding += 1 if verbose | |
- @destination_stack.push File.expand_path(dir, destination_root) | |
- | |
- FileUtils.mkdir_p(destination_root) unless File.exist?(destination_root) | |
- FileUtils.cd(destination_root) { block.arity == 1 ? yield(destination_root) : yield } | |
- | |
- @destination_stack.pop | |
- shell.padding -= 1 if verbose | |
- end | |
- | |
- # Goes to the root and execute the given block. | |
- # | |
- def in_root | |
- inside(@destination_stack.first) { yield } | |
- end | |
- | |
- # Loads an external file and execute it in the instance binding. | |
- # | |
- # ==== Parameters | |
- # path<String>:: The path to the file to execute. Can be a web address or | |
- # a relative path from the source root. | |
- # | |
- # ==== Examples | |
- # | |
- # apply "http://gist.github.com/103208" | |
- # | |
- # apply "recipes/jquery.rb" | |
- # | |
- def apply(path, config={}) | |
- verbose = config.fetch(:verbose, true) | |
- path = find_in_source_paths(path) unless path =~ /^http\:\/\// | |
- | |
- say_status :apply, path, verbose | |
- shell.padding += 1 if verbose | |
- instance_eval(open(path).read) | |
- shell.padding -= 1 if verbose | |
- end | |
- | |
- # Executes a command. | |
- # | |
- # ==== Parameters | |
- # command<String>:: the command to be executed. | |
- # config<Hash>:: give :verbose => false to not log the status. Specify :with | |
- # to append an executable to command executation. | |
- # | |
- # ==== Example | |
- # | |
- # inside('vendor') do | |
- # run('ln -s ~/edge rails') | |
- # end | |
- # | |
- def run(command, config={}) | |
- return unless behavior == :invoke | |
- | |
- destination = relative_to_original_destination_root(destination_root, false) | |
- desc = "#{command} from #{destination.inspect}" | |
- | |
- if config[:with] | |
- desc = "#{File.basename(config[:with].to_s)} #{desc}" | |
- command = "#{config[:with]} #{command}" | |
- end | |
- | |
- say_status :run, desc, config.fetch(:verbose, true) | |
- system(command) unless options[:pretend] | |
- end | |
- | |
- # Executes a ruby script (taking into account WIN32 platform quirks). | |
- # | |
- # ==== Parameters | |
- # command<String>:: the command to be executed. | |
- # config<Hash>:: give :verbose => false to not log the status. | |
- # | |
- def run_ruby_script(command, config={}) | |
- return unless behavior == :invoke | |
- run "#{command}", config.merge(:with => Thor::Util.ruby_command) | |
- end | |
- | |
- # Run a thor command. A hash of options can be given and it's converted to | |
- # switches. | |
- # | |
- # ==== Parameters | |
- # task<String>:: the task to be invoked | |
- # args<Array>:: arguments to the task | |
- # config<Hash>:: give :verbose => false to not log the status. Other options | |
- # are given as parameter to Thor. | |
- # | |
- # ==== Examples | |
- # | |
- # thor :install, "http://gist.github.com/103208" | |
- # #=> thor install http://gist.github.com/103208 | |
- # | |
- # thor :list, :all => true, :substring => 'rails' | |
- # #=> thor list --all --substring=rails | |
- # | |
- def thor(task, *args) | |
- config = args.last.is_a?(Hash) ? args.pop : {} | |
- verbose = config.key?(:verbose) ? config.delete(:verbose) : true | |
- | |
- args.unshift task | |
- args.push Thor::Options.to_switches(config) | |
- command = args.join(' ').strip | |
- | |
- run command, :with => :thor, :verbose => verbose | |
- end | |
- | |
- protected | |
- | |
- # Allow current root to be shared between invocations. | |
- # | |
- def _shared_configuration #:nodoc: | |
- super.merge!(:destination_root => self.destination_root) | |
- end | |
- | |
- def _cleanup_options_and_set(options, key) #:nodoc: | |
- case options | |
- when Array | |
- %w(--force -f --skip -s).each { |i| options.delete(i) } | |
- options << "--#{key}" | |
- when Hash | |
- [:force, :skip, "force", "skip"].each { |i| options.delete(i) } | |
- options.merge!(key => true) | |
- end | |
- end | |
- | |
- end | |
-end | |
diff --git a/railties/lib/rails/vendor/thor-0.11.8/lib/thor/actions/create_file.rb b/railties/lib/rails/vendor/thor-0.11.8/lib/thor/actions/create_file.rb | |
deleted file mode 100644 | |
index 8f6bade..0000000 | |
--- a/railties/lib/rails/vendor/thor-0.11.8/lib/thor/actions/create_file.rb | |
+++ /dev/null | |
@@ -1,102 +0,0 @@ | |
-require 'thor/actions/empty_directory' | |
- | |
-class Thor | |
- module Actions | |
- | |
- # Create a new file relative to the destination root with the given data, | |
- # which is the return value of a block or a data string. | |
- # | |
- # ==== Parameters | |
- # destination<String>:: the relative path to the destination root. | |
- # data<String|NilClass>:: the data to append to the file. | |
- # config<Hash>:: give :verbose => false to not log the status. | |
- # | |
- # ==== Examples | |
- # | |
- # create_file "lib/fun_party.rb" do | |
- # hostname = ask("What is the virtual hostname I should use?") | |
- # "vhost.name = #{hostname}" | |
- # end | |
- # | |
- # create_file "config/apach.conf", "your apache config" | |
- # | |
- def create_file(destination, data=nil, config={}, &block) | |
- action CreateFile.new(self, destination, block || data.to_s, config) | |
- end | |
- alias :add_file :create_file | |
- | |
- # AddFile is a subset of Template, which instead of rendering a file with | |
- # ERB, it gets the content from the user. | |
- # | |
- class CreateFile < EmptyDirectory #:nodoc: | |
- attr_reader :data | |
- | |
- def initialize(base, destination, data, config={}) | |
- @data = data | |
- super(base, destination, config) | |
- end | |
- | |
- # Checks if the content of the file at the destination is identical to the rendered result. | |
- # | |
- # ==== Returns | |
- # Boolean:: true if it is identical, false otherwise. | |
- # | |
- def identical? | |
- exists? && File.read(destination) == render | |
- end | |
- | |
- # Holds the content to be added to the file. | |
- # | |
- def render | |
- @render ||= if data.is_a?(Proc) | |
- data.call | |
- else | |
- data | |
- end | |
- end | |
- | |
- def invoke! | |
- invoke_with_conflict_check do | |
- FileUtils.mkdir_p(File.dirname(destination)) | |
- File.open(destination, 'w'){ |f| f.write render } | |
- end | |
- end | |
- | |
- protected | |
- | |
- # Now on conflict we check if the file is identical or not. | |
- # | |
- def on_conflict_behavior(&block) | |
- if identical? | |
- say_status :identical, :blue | |
- else | |
- options = base.options.merge(config) | |
- force_or_skip_or_conflict(options[:force], options[:skip], &block) | |
- end | |
- end | |
- | |
- # If force is true, run the action, otherwise check if it's not being | |
- # skipped. If both are false, show the file_collision menu, if the menu | |
- # returns true, force it, otherwise skip. | |
- # | |
- def force_or_skip_or_conflict(force, skip, &block) | |
- if force | |
- say_status :force, :yellow | |
- block.call unless pretend? | |
- elsif skip | |
- say_status :skip, :yellow | |
- else | |
- say_status :conflict, :red | |
- force_or_skip_or_conflict(force_on_collision?, true, &block) | |
- end | |
- end | |
- | |
- # Shows the file collision menu to the user and gets the result. | |
- # | |
- def force_on_collision? | |
- base.shell.file_collision(destination){ render } | |
- end | |
- | |
- end | |
- end | |
-end | |
diff --git a/railties/lib/rails/vendor/thor-0.11.8/lib/thor/actions/directory.rb b/railties/lib/rails/vendor/thor-0.11.8/lib/thor/actions/directory.rb | |
deleted file mode 100644 | |
index 063ac57..0000000 | |
--- a/railties/lib/rails/vendor/thor-0.11.8/lib/thor/actions/directory.rb | |
+++ /dev/null | |
@@ -1,89 +0,0 @@ | |
-require 'thor/actions/empty_directory' | |
- | |
-class Thor | |
- module Actions | |
- | |
- # Copies recursively the files from source directory to root directory. | |
- # If any of the files finishes with .tt, it's considered to be a template | |
- # and is placed in the destination without the extension .tt. If any | |
- # empty directory is found, it's copied and all .empty_directory files are | |
- # ignored. Remember that file paths can also be encoded, let's suppose a doc | |
- # directory with the following files: | |
- # | |
- # doc/ | |
- # components/.empty_directory | |
- # README | |
- # rdoc.rb.tt | |
- # %app_name%.rb | |
- # | |
- # When invoked as: | |
- # | |
- # directory "doc" | |
- # | |
- # It will create a doc directory in the destination with the following | |
- # files (assuming that the app_name is "blog"): | |
- # | |
- # doc/ | |
- # components/ | |
- # README | |
- # rdoc.rb | |
- # blog.rb | |
- # | |
- # ==== Parameters | |
- # source<String>:: the relative path to the source root. | |
- # destination<String>:: the relative path to the destination root. | |
- # config<Hash>:: give :verbose => false to not log the status. | |
- # If :recursive => false, does not look for paths recursively. | |
- # | |
- # ==== Examples | |
- # | |
- # directory "doc" | |
- # directory "doc", "docs", :recursive => false | |
- # | |
- def directory(source, destination=nil, config={}) | |
- action Directory.new(self, source, destination || source, config) | |
- end | |
- | |
- class Directory < EmptyDirectory #:nodoc: | |
- attr_reader :source | |
- | |
- def initialize(base, source, destination=nil, config={}) | |
- @source = File.expand_path(base.find_in_source_paths(source.to_s)) | |
- super(base, destination, { :recursive => true }.merge(config)) | |
- end | |
- | |
- def invoke! | |
- base.empty_directory given_destination, config | |
- execute! | |
- end | |
- | |
- def revoke! | |
- execute! | |
- end | |
- | |
- protected | |
- | |
- def execute! | |
- lookup = config[:recursive] ? File.join(source, '**') : source | |
- lookup = File.join(lookup, '{*,.[a-z]*}') | |
- | |
- Dir[lookup].each do |file_source| | |
- next if File.directory?(file_source) | |
- file_destination = File.join(given_destination, file_source.gsub(source, '.')) | |
- | |
- case file_source | |
- when /\.empty_directory$/ | |
- dirname = File.dirname(file_destination).gsub(/\/\.$/, '') | |
- next if dirname == given_destination | |
- base.empty_directory(dirname, config) | |
- when /\.tt$/ | |
- base.template(file_source, file_destination[0..-4], config) | |
- else | |
- base.copy_file(file_source, file_destination, config) | |
- end | |
- end | |
- end | |
- | |
- end | |
- end | |
-end | |
diff --git a/railties/lib/rails/vendor/thor-0.11.8/lib/thor/actions/empty_directory.rb b/railties/lib/rails/vendor/thor-0.11.8/lib/thor/actions/empty_directory.rb | |
deleted file mode 100644 | |
index 03c1fe4..0000000 | |
--- a/railties/lib/rails/vendor/thor-0.11.8/lib/thor/actions/empty_directory.rb | |
+++ /dev/null | |
@@ -1,133 +0,0 @@ | |
-class Thor | |
- module Actions | |
- | |
- # Creates an empty directory. | |
- # | |
- # ==== Parameters | |
- # destination<String>:: the relative path to the destination root. | |
- # config<Hash>:: give :verbose => false to not log the status. | |
- # | |
- # ==== Examples | |
- # | |
- # empty_directory "doc" | |
- # | |
- def empty_directory(destination, config={}) | |
- action EmptyDirectory.new(self, destination, config) | |
- end | |
- | |
- # Class which holds create directory logic. This is the base class for | |
- # other actions like create_file and directory. | |
- # | |
- # This implementation is based in Templater actions, created by Jonas Nicklas | |
- # and Michael S. Klishin under MIT LICENSE. | |
- # | |
- class EmptyDirectory #:nodoc: | |
- attr_reader :base, :destination, :given_destination, :relative_destination, :config | |
- | |
- # Initializes given the source and destination. | |
- # | |
- # ==== Parameters | |
- # base<Thor::Base>:: A Thor::Base instance | |
- # source<String>:: Relative path to the source of this file | |
- # destination<String>:: Relative path to the destination of this file | |
- # config<Hash>:: give :verbose => false to not log the status. | |
- # | |
- def initialize(base, destination, config={}) | |
- @base, @config = base, { :verbose => true }.merge(config) | |
- self.destination = destination | |
- end | |
- | |
- # Checks if the destination file already exists. | |
- # | |
- # ==== Returns | |
- # Boolean:: true if the file exists, false otherwise. | |
- # | |
- def exists? | |
- ::File.exists?(destination) | |
- end | |
- | |
- def invoke! | |
- invoke_with_conflict_check do | |
- ::FileUtils.mkdir_p(destination) | |
- end | |
- end | |
- | |
- def revoke! | |
- say_status :remove, :red | |
- ::FileUtils.rm_rf(destination) if !pretend? && exists? | |
- end | |
- | |
- protected | |
- | |
- # Shortcut for pretend. | |
- # | |
- def pretend? | |
- base.options[:pretend] | |
- end | |
- | |
- # Sets the absolute destination value from a relative destination value. | |
- # It also stores the given and relative destination. Let's suppose our | |
- # script is being executed on "dest", it sets the destination root to | |
- # "dest". The destination, given_destination and relative_destination | |
- # are related in the following way: | |
- # | |
- # inside "bar" do | |
- # empty_directory "baz" | |
- # end | |
- # | |
- # destination #=> dest/bar/baz | |
- # relative_destination #=> bar/baz | |
- # given_destination #=> baz | |
- # | |
- def destination=(destination) | |
- if destination | |
- @given_destination = convert_encoded_instructions(destination.to_s) | |
- @destination = ::File.expand_path(@given_destination, base.destination_root) | |
- @relative_destination = base.relative_to_original_destination_root(@destination) | |
- end | |
- end | |
- | |
- # Filenames in the encoded form are converted. If you have a file: | |
- # | |
- # %class_name%.rb | |
- # | |
- # It gets the class name from the base and replace it: | |
- # | |
- # user.rb | |
- # | |
- def convert_encoded_instructions(filename) | |
- filename.gsub(/%(.*?)%/) do |string| | |
- instruction = $1.strip | |
- base.respond_to?(instruction) ? base.send(instruction) : string | |
- end | |
- end | |
- | |
- # Receives a hash of options and just execute the block if some | |
- # conditions are met. | |
- # | |
- def invoke_with_conflict_check(&block) | |
- if exists? | |
- on_conflict_behavior(&block) | |
- else | |
- say_status :create, :green | |
- block.call unless pretend? | |
- end | |
- | |
- destination | |
- end | |
- | |
- # What to do when the destination file already exists. | |
- # | |
- def on_conflict_behavior(&block) | |
- say_status :exist, :blue | |
- end | |
- | |
- # Shortcut to say_status shell method. | |
- # | |
- def say_status(status, color) | |
- base.shell.say_status status, relative_destination, color if config[:verbose] | |
- end | |
- | |
- end | |
- end | |
-end | |
diff --git a/railties/lib/rails/vendor/thor-0.11.8/lib/thor/actions/file_manipulation.rb b/railties/lib/rails/vendor/thor-0.11.8/lib/thor/actions/file_manipulation.rb | |
deleted file mode 100644 | |
index d77d90d..0000000 | |
--- a/railties/lib/rails/vendor/thor-0.11.8/lib/thor/actions/file_manipulation.rb | |
+++ /dev/null | |
@@ -1,219 +0,0 @@ | |
-require 'erb' | |
-require 'open-uri' | |
- | |
-class Thor | |
- module Actions | |
- | |
- # Copies the file from the relative source to the relative destination. If | |
- # the destination is not given it's assumed to be equal to the source. | |
- # | |
- # ==== Parameters | |
- # source<String>:: the relative path to the source root. | |
- # destination<String>:: the relative path to the destination root. | |
- # config<Hash>:: give :verbose => false to not log the status. | |
- # | |
- # ==== Examples | |
- # | |
- # copy_file "README", "doc/README" | |
- # | |
- # copy_file "doc/README" | |
- # | |
- def copy_file(source, destination=nil, config={}) | |
- destination ||= source | |
- source = File.expand_path(find_in_source_paths(source.to_s)) | |
- | |
- create_file destination, nil, config do | |
- File.read(source) | |
- end | |
- end | |
- | |
- # Gets the content at the given address and places it at the given relative | |
- # destination. If a block is given instead of destination, the content of | |
- # the url is yielded and used as location. | |
- # | |
- # ==== Parameters | |
- # source<String>:: the address of the given content. | |
- # destination<String>:: the relative path to the destination root. | |
- # config<Hash>:: give :verbose => false to not log the status. | |
- # | |
- # ==== Examples | |
- # | |
- # get "http://gist.github.com/103208", "doc/README" | |
- # | |
- # get "http://gist.github.com/103208" do |content| | |
- # content.split("\n").first | |
- # end | |
- # | |
- def get(source, destination=nil, config={}, &block) | |
- source = File.expand_path(find_in_source_paths(source.to_s)) unless source =~ /^http\:\/\// | |
- render = open(source).read | |
- | |
- destination ||= if block_given? | |
- block.arity == 1 ? block.call(render) : block.call | |
- else | |
- File.basename(source) | |
- end | |
- | |
- create_file destination, render, config | |
- end | |
- | |
- # Gets an ERB template at the relative source, executes it and makes a copy | |
- # at the relative destination. If the destination is not given it's assumed | |
- # to be equal to the source removing .tt from the filename. | |
- # | |
- # ==== Parameters | |
- # source<String>:: the relative path to the source root. | |
- # destination<String>:: the relative path to the destination root. | |
- # config<Hash>:: give :verbose => false to not log the status. | |
- # | |
- # ==== Examples | |
- # | |
- # template "README", "doc/README" | |
- # | |
- # template "doc/README" | |
- # | |
- def template(source, destination=nil, config={}) | |
- destination ||= source | |
- source = File.expand_path(find_in_source_paths(source.to_s)) | |
- context = instance_eval('binding') | |
- | |
- create_file destination, nil, config do | |
- ERB.new(::File.read(source), nil, '-').result(context) | |
- end | |
- end | |
- | |
- # Changes the mode of the given file or directory. | |
- # | |
- # ==== Parameters | |
- # mode<Integer>:: the file mode | |
- # path<String>:: the name of the file to change mode | |
- # config<Hash>:: give :verbose => false to not log the status. | |
- # | |
- # ==== Example | |
- # | |
- # chmod "script/*", 0755 | |
- # | |
- def chmod(path, mode, config={}) | |
- return unless behavior == :invoke | |
- path = File.expand_path(path, destination_root) | |
- say_status :chmod, relative_to_original_destination_root(path), config.fetch(:verbose, true) | |
- FileUtils.chmod_R(mode, path) unless options[:pretend] | |
- end | |
- | |
- # Prepend text to a file. Since it depends on inject_into_file, it's reversible. | |
- # | |
- # ==== Parameters | |
- # path<String>:: path of the file to be changed | |
- # data<String>:: the data to prepend to the file, can be also given as a block. | |
- # config<Hash>:: give :verbose => false to not log the status. | |
- # | |
- # ==== Example | |
- # | |
- # prepend_file 'config/environments/test.rb', 'config.gem "rspec"' | |
- # | |
- # prepend_file 'config/environments/test.rb' do | |
- # 'config.gem "rspec"' | |
- # end | |
- # | |
- def prepend_file(path, *args, &block) | |
- config = args.last.is_a?(Hash) ? args.pop : {} | |
- config.merge!(:after => /\A/) | |
- inject_into_file(path, *(args << config), &block) | |
- end | |
- | |
- # Append text to a file. Since it depends on inject_into_file, it's reversible. | |
- # | |
- # ==== Parameters | |
- # path<String>:: path of the file to be changed | |
- # data<String>:: the data to append to the file, can be also given as a block. | |
- # config<Hash>:: give :verbose => false to not log the status. | |
- # | |
- # ==== Example | |
- # | |
- # append_file 'config/environments/test.rb', 'config.gem "rspec"' | |
- # | |
- # append_file 'config/environments/test.rb' do | |
- # 'config.gem "rspec"' | |
- # end | |
- # | |
- def append_file(path, *args, &block) | |
- config = args.last.is_a?(Hash) ? args.pop : {} | |
- config.merge!(:before => /\z/) | |
- inject_into_file(path, *(args << config), &block) | |
- end | |
- | |
- # Injects text right after the class definition. Since it depends on | |
- # inject_into_file, it's reversible. | |
- # | |
- # ==== Parameters | |
- # path<String>:: path of the file to be changed | |
- # klass<String|Class>:: the class to be manipulated | |
- # data<String>:: the data to append to the class, can be also given as a block. | |
- # config<Hash>:: give :verbose => false to not log the status. | |
- # | |
- # ==== Examples | |
- # | |
- # inject_into_class "app/controllers/application_controller.rb", " filter_parameter :password\n" | |
- # | |
- # inject_into_class "app/controllers/application_controller.rb", ApplicationController do | |
- # " filter_parameter :password\n" | |
- # end | |
- # | |
- def inject_into_class(path, klass, *args, &block) | |
- config = args.last.is_a?(Hash) ? args.pop : {} | |
- config.merge!(:after => /class #{klass}\n|class #{klass} .*\n/) | |
- inject_into_file(path, *(args << config), &block) | |
- end | |
- | |
- # Run a regular expression replacement on a file. | |
- # | |
- # ==== Parameters | |
- # path<String>:: path of the file to be changed | |
- # flag<Regexp|String>:: the regexp or string to be replaced | |
- # replacement<String>:: the replacement, can be also given as a block | |
- # config<Hash>:: give :verbose => false to not log the status. | |
- # | |
- # ==== Example | |
- # | |
- # gsub_file 'app/controllers/application_controller.rb', /#\s*(filter_parameter_logging :password)/, '\1' | |
- # | |
- # gsub_file 'README', /rake/, :green do |match| | |
- # match << " no more. Use thor!" | |
- # end | |
- # | |
- def gsub_file(path, flag, *args, &block) | |
- return unless behavior == :invoke | |
- config = args.last.is_a?(Hash) ? args.pop : {} | |
- | |
- path = File.expand_path(path, destination_root) | |
- say_status :gsub, relative_to_original_destination_root(path), config.fetch(:verbose, true) | |
- | |
- unless options[:pretend] | |
- content = File.read(path) | |
- content.gsub!(flag, *args, &block) | |
- File.open(path, 'wb') { |file| file.write(content) } | |
- end | |
- end | |
- | |
- # Removes a file at the given location. | |
- # | |
- # ==== Parameters | |
- # path<String>:: path of the file to be changed | |
- # config<Hash>:: give :verbose => false to not log the status. | |
- # | |
- # ==== Example | |
- # | |
- # remove_file 'README' | |
- # remove_file 'app/controllers/application_controller.rb' | |
- # | |
- def remove_file(path, config={}) | |
- return unless behavior == :invoke | |
- path = File.expand_path(path, destination_root) | |
- | |
- say_status :remove, relative_to_original_destination_root(path), config.fetch(:verbose, true) | |
- ::FileUtils.rm_rf(path) if !options[:pretend] && File.exists?(path) | |
- end | |
- alias :remove_dir :remove_file | |
- | |
- end | |
-end | |
diff --git a/railties/lib/rails/vendor/thor-0.11.8/lib/thor/actions/inject_into_file.rb b/railties/lib/rails/vendor/thor-0.11.8/lib/thor/actions/inject_into_file.rb | |
deleted file mode 100644 | |
index 0636ec6..0000000 | |
--- a/railties/lib/rails/vendor/thor-0.11.8/lib/thor/actions/inject_into_file.rb | |
+++ /dev/null | |
@@ -1,101 +0,0 @@ | |
-require 'thor/actions/empty_directory' | |
- | |
-class Thor | |
- module Actions | |
- | |
- # Injects the given content into a file. Different from gsub_file, this | |
- # method is reversible. | |
- # | |
- # ==== Parameters | |
- # destination<String>:: Relative path to the destination root | |
- # data<String>:: Data to add to the file. Can be given as a block. | |
- # config<Hash>:: give :verbose => false to not log the status and the flag | |
- # for injection (:after or :before). | |
- # | |
- # ==== Examples | |
- # | |
- # inject_into_file "config/environment.rb", "config.gem :thor", :after => "Rails::Initializer.run do |config|\n" | |
- # | |
- # inject_into_file "config/environment.rb", :after => "Rails::Initializer.run do |config|\n" do | |
- # gems = ask "Which gems would you like to add?" | |
- # gems.split(" ").map{ |gem| " config.gem :#{gem}" }.join("\n") | |
- # end | |
- # | |
- def inject_into_file(destination, *args, &block) | |
- if block_given? | |
- data, config = block, args.shift | |
- else | |
- data, config = args.shift, args.shift | |
- end | |
- action InjectIntoFile.new(self, destination, data, config) | |
- end | |
- | |
- class InjectIntoFile < EmptyDirectory #:nodoc: | |
- attr_reader :replacement, :flag, :behavior | |
- | |
- def initialize(base, destination, data, config) | |
- super(base, destination, { :verbose => true }.merge(config)) | |
- | |
- @behavior, @flag = if @config.key?(:after) | |
- [:after, @config.delete(:after)] | |
- else | |
- [:before, @config.delete(:before)] | |
- end | |
- | |
- @replacement = data.is_a?(Proc) ? data.call : data | |
- @flag = Regexp.escape(@flag) unless @flag.is_a?(Regexp) | |
- end | |
- | |
- def invoke! | |
- say_status :invoke | |
- | |
- content = if @behavior == :after | |
- '\0' + replacement | |
- else | |
- replacement + '\0' | |
- end | |
- | |
- replace!(/#{flag}/, content) | |
- end | |
- | |
- def revoke! | |
- say_status :revoke | |
- | |
- regexp = if @behavior == :after | |
- content = '\1\2' | |
- /(#{flag})(.*)(#{Regexp.escape(replacement)})/m | |
- else | |
- content = '\2\3' | |
- /(#{Regexp.escape(replacement)})(.*)(#{flag})/m | |
- end | |
- | |
- replace!(regexp, content) | |
- end | |
- | |
- protected | |
- | |
- def say_status(behavior) | |
- status = if flag == /\A/ | |
- behavior == :invoke ? :prepend : :unprepend | |
- elsif flag == /\z/ | |
- behavior == :invoke ? :append : :unappend | |
- else | |
- behavior == :invoke ? :inject : :deinject | |
- end | |
- | |
- super(status, config[:verbose]) | |
- end | |
- | |
- # Adds the content to the file. | |
- # | |
- def replace!(regexp, string) | |
- unless base.options[:pretend] | |
- content = File.read(destination) | |
- content.gsub!(regexp, string) | |
- File.open(destination, 'wb') { |file| file.write(content) } | |
- end | |
- end | |
- | |
- end | |
- end | |
-end | |
diff --git a/railties/lib/rails/vendor/thor-0.11.8/lib/thor/base.rb b/railties/lib/rails/vendor/thor-0.11.8/lib/thor/base.rb | |
deleted file mode 100644 | |
index 700d794..0000000 | |
--- a/railties/lib/rails/vendor/thor-0.11.8/lib/thor/base.rb | |
+++ /dev/null | |
@@ -1,517 +0,0 @@ | |
-require 'thor/core_ext/hash_with_indifferent_access' | |
-require 'thor/core_ext/ordered_hash' | |
-require 'thor/error' | |
-require 'thor/shell' | |
-require 'thor/invocation' | |
-require 'thor/parser' | |
-require 'thor/task' | |
-require 'thor/util' | |
- | |
-class Thor | |
- # Shortcuts for help. | |
- HELP_MAPPINGS = %w(-h -? --help -D) | |
- | |
- # Thor methods that should not be overwritten by the user. | |
- THOR_RESERVED_WORDS = %w(invoke shell options behavior root destination_root relative_root | |
- action add_file create_file in_root inside run run_ruby_script) | |
- | |
- module Base | |
- attr_accessor :options | |
- | |
- # It receives arguments in an Array and two hashes, one for options and | |
- # other for configuration. | |
- # | |
- # Notice that it does not check if all required arguments were supplied. | |
- # It should be done by the parser. | |
- # | |
- # ==== Parameters | |
- # args<Array[Object]>:: An array of objects. The objects are applied to their | |
- # respective accessors declared with <tt>argument</tt>. | |
- # | |
- # options<Hash>:: An options hash that will be available as self.options. | |
- # The hash given is converted to a hash with indifferent | |
- # access, magic predicates (options.skip?) and then frozen. | |
- # | |
- # config<Hash>:: Configuration for this Thor class. | |
- # | |
- def initialize(args=[], options={}, config={}) | |
- Thor::Arguments.parse(self.class.arguments, args).each do |key, value| | |
- send("#{key}=", value) | |
- end | |
- | |
- parse_options = self.class.class_options | |
- | |
- if options.is_a?(Array) | |
- task_options = config.delete(:task_options) # hook for start | |
- parse_options = parse_options.merge(task_options) if task_options | |
- array_options, hash_options = options, {} | |
- else | |
- array_options, hash_options = [], options | |
- end | |
- | |
- options = Thor::Options.parse(parse_options, array_options) | |
- self.options = Thor::CoreExt::HashWithIndifferentAccess.new(options).merge!(hash_options) | |
- self.options.freeze | |
- end | |
- | |
- class << self | |
- def included(base) #:nodoc: | |
- base.send :extend, ClassMethods | |
- base.send :include, Invocation | |
- base.send :include, Shell | |
- end | |
- | |
- # Returns the classes that inherits from Thor or Thor::Group. | |
- # | |
- # ==== Returns | |
- # Array[Class] | |
- # | |
- def subclasses | |
- @subclasses ||= [] | |
- end | |
- | |
- # Returns the files where the subclasses are kept. | |
- # | |
- # ==== Returns | |
- # Hash[path<String> => Class] | |
- # | |
- def subclass_files | |
- @subclass_files ||= Hash.new{ |h,k| h[k] = [] } | |
- end | |
- | |
- # Whenever a class inherits from Thor or Thor::Group, we should track the | |
- # class and the file on Thor::Base. This is the method responsable for it. | |
- # | |
- def register_klass_file(klass) #:nodoc: | |
- file = caller[1].match(/(.*):\d+/)[1] | |
- Thor::Base.subclasses << klass unless Thor::Base.subclasses.include?(klass) | |
- | |
- file_subclasses = Thor::Base.subclass_files[File.expand_path(file)] | |
- file_subclasses << klass unless file_subclasses.include?(klass) | |
- end | |
- end | |
- | |
- module ClassMethods | |
- # Adds an argument to the class and creates an attr_accessor for it. | |
- # | |
- # Arguments are different from options in several aspects. The first one | |
- # is how they are parsed from the command line, arguments are retrieved | |
- # from position: | |
- # | |
- # thor task NAME | |
- # | |
- # Instead of: | |
- # | |
- # thor task --name=NAME | |
- # | |
- # Besides, arguments are used inside your code as an accessor (self.argument), | |
- # while options are all kept in a hash (self.options). | |
- # | |
- # Finally, arguments cannot have type :default or :boolean but can be | |
- # optional (supplying :optional => :true or :required => false), although | |
- # you cannot have a required argument after a non-required argument. If you | |
- # try it, an error is raised. | |
- # | |
- # ==== Parameters | |
- # name<Symbol>:: The name of the argument. | |
- # options<Hash>:: Described below. | |
- # | |
- # ==== Options | |
- # :desc - Description for the argument. | |
- # :required - If the argument is required or not. | |
- # :optional - If the argument is optional or not. | |
- # :type - The type of the argument, can be :string, :hash, :array, :numeric. | |
- # :default - Default value for this argument. It cannot be required and have default values. | |
- # :banner - String to show on usage notes. | |
- # | |
- # ==== Errors | |
- # ArgumentError:: Raised if you supply a required argument after a non required one. | |
- # | |
- def argument(name, options={}) | |
- is_thor_reserved_word?(name, :argument) | |
- no_tasks { attr_accessor name } | |
- | |
- required = if options.key?(:optional) | |
- !options[:optional] | |
- elsif options.key?(:required) | |
- options[:required] | |
- else | |
- options[:default].nil? | |
- end | |
- | |
- remove_argument name | |
- | |
- arguments.each do |argument| | |
- next if argument.required? | |
- raise ArgumentError, "You cannot have #{name.to_s.inspect} as required argument after " << | |
- "the non-required argument #{argument.human_name.inspect}." | |
- end if required | |
- | |
- arguments << Thor::Argument.new(name, options[:desc], required, options[:type], | |
- options[:default], options[:banner]) | |
- end | |
- | |
- # Returns this class arguments, looking up in the ancestors chain. | |
- # | |
- # ==== Returns | |
- # Array[Thor::Argument] | |
- # | |
- def arguments | |
- @arguments ||= from_superclass(:arguments, []) | |
- end | |
- | |
- # Adds a bunch of options to the set of class options. | |
- # | |
- # class_options :foo => false, :bar => :required, :baz => :string | |
- # | |
- # If you prefer more detailed declaration, check class_option. | |
- # | |
- # ==== Parameters | |
- # Hash[Symbol => Object] | |
- # | |
- def class_options(options=nil) | |
- @class_options ||= from_superclass(:class_options, {}) | |
- build_options(options, @class_options) if options | |
- @class_options | |
- end | |
- | |
- # Adds an option to the set of class options | |
- # | |
- # ==== Parameters | |
- # name<Symbol>:: The name of the argument. | |
- # options<Hash>:: Described below. | |
- # | |
- # ==== Options | |
- # :desc - Description for the argument. | |
- # :required - If the argument is required or not. | |
- # :default - Default value for this argument. | |
- # :group - The group for this options. Use by class options to output options in different levels. | |
- # :aliases - Aliases for this option. | |
- # :type - The type of the argument, can be :string, :hash, :array, :numeric or :boolean. | |
- # :banner - String to show on usage notes. | |
- # | |
- def class_option(name, options={}) | |
- build_option(name, options, class_options) | |
- end | |
- | |
- # Removes a previous defined argument. If :undefine is given, undefine | |
- # accessors as well. | |
- # | |
- # ==== Paremeters | |
- # names<Array>:: Arguments to be removed | |
- # | |
- # ==== Examples | |
- # | |
- # remove_argument :foo | |
- # remove_argument :foo, :bar, :baz, :undefine => true | |
- # | |
- def remove_argument(*names) | |
- options = names.last.is_a?(Hash) ? names.pop : {} | |
- | |
- names.each do |name| | |
- arguments.delete_if { |a| a.name == name.to_s } | |
- undef_method name, "#{name}=" if options[:undefine] | |
- end | |
- end | |
- | |
- # Removes a previous defined class option. | |
- # | |
- # ==== Paremeters | |
- # names<Array>:: Class options to be removed | |
- # | |
- # ==== Examples | |
- # | |
- # remove_class_option :foo | |
- # remove_class_option :foo, :bar, :baz | |
- # | |
- def remove_class_option(*names) | |
- names.each do |name| | |
- class_options.delete(name) | |
- end | |
- end | |
- | |
- # Defines the group. This is used when thor list is invoked so you can specify | |
- # that only tasks from a pre-defined group will be shown. Defaults to standard. | |
- # | |
- # ==== Parameters | |
- # name<String|Symbol> | |
- # | |
- def group(name=nil) | |
- case name | |
- when nil | |
- @group ||= from_superclass(:group, 'standard') | |
- else | |
- @group = name.to_s | |
- end | |
- end | |
- | |
- # Returns the tasks for this Thor class. | |
- # | |
- # ==== Returns | |
- # OrderedHash:: An ordered hash with tasks names as keys and Thor::Task | |
- # objects as values. | |
- # | |
- def tasks | |
- @tasks ||= Thor::CoreExt::OrderedHash.new | |
- end | |
- | |
- # Returns the tasks for this Thor class and all subclasses. | |
- # | |
- # ==== Returns | |
- # OrderedHash:: An ordered hash with tasks names as keys and Thor::Task | |
- # objects as values. | |
- # | |
- def all_tasks | |
- @all_tasks ||= from_superclass(:all_tasks, Thor::CoreExt::OrderedHash.new) | |
- @all_tasks.merge(tasks) | |
- end | |
- | |
- # Removes a given task from this Thor class. This is usually done if you | |
- # are inheriting from another class and don't want it to be available | |
- # anymore. | |
- # | |
- # By default it only remove the mapping to the task. But you can supply | |
- # :undefine => true to undefine the method from the class as well. | |
- # | |
- # ==== Parameters | |
- # name<Symbol|String>:: The name of the task to be removed | |
- # options<Hash>:: You can give :undefine => true if you want tasks the method | |
- # to be undefined from the class as well. | |
- # | |
- def remove_task(*names) | |
- options = names.last.is_a?(Hash) ? names.pop : {} | |
- | |
- names.each do |name| | |
- tasks.delete(name.to_s) | |
- all_tasks.delete(name.to_s) | |
- undef_method name if options[:undefine] | |
- end | |
- end | |
- | |
- # All methods defined inside the given block are not added as tasks. | |
- # | |
- # So you can do: | |
- # | |
- # class MyScript < Thor | |
- # no_tasks do | |
- # def this_is_not_a_task | |
- # end | |
- # end | |
- # end | |
- # | |
- # You can also add the method and remove it from the task list: | |
- # | |
- # class MyScript < Thor | |
- # def this_is_not_a_task | |
- # end | |
- # remove_task :this_is_not_a_task | |
- # end | |
- # | |
- def no_tasks | |
- @no_tasks = true | |
- yield | |
- @no_tasks = false | |
- end | |
- | |
- # Sets the namespace for the Thor or Thor::Group class. By default the | |
- # namespace is retrieved from the class name. If your Thor class is named | |
- # Scripts::MyScript, the help method, for example, will be called as: | |
- # | |
- # thor scripts:my_script -h | |
- # | |
- # If you change the namespace: | |
- # | |
- # namespace :my_scripts | |
- # | |
- # You change how your tasks are invoked: | |
- # | |
- # thor my_scripts -h | |
- # | |
- # Finally, if you change your namespace to default: | |
- # | |
- # namespace :default | |
- # | |
- # Your tasks can be invoked with a shortcut. Instead of: | |
- # | |
- # thor :my_task | |
- # | |
- def namespace(name=nil) | |
- case name | |
- when nil | |
- @namespace ||= Thor::Util.namespace_from_thor_class(self, false) | |
- else | |
- @namespace = name.to_s | |
- end | |
- end | |
- | |
- # Default way to start generators from the command line. | |
- # | |
- def start(given_args=ARGV, config={}) | |
- config[:shell] ||= Thor::Base.shell.new | |
- yield | |
- rescue Thor::Error => e | |
- if given_args.include?("--debug") | |
- raise e | |
- else | |
- config[:shell].error e.message | |
- end | |
- exit(1) if exit_on_failure? | |
- end | |
- | |
- protected | |
- | |
- # Prints the class options per group. If an option does not belong to | |
- # any group, it uses the ungrouped name value. This method provide to | |
- # hooks to add extra options, one of them if the third argument called | |
- # extra_group that should be a hash in the format :group => Array[Options]. | |
- # | |
- # The second is by returning a lambda used to print values. The lambda | |
- # requires two options: the group name and the array of options. | |
- # | |
- def class_options_help(shell, ungrouped_name=nil, extra_group=nil) #:nodoc: | |
- groups = {} | |
- | |
- class_options.each do |_, value| | |
- groups[value.group] ||= [] | |
- groups[value.group] << value | |
- end | |
- | |
- printer = proc do |group_name, options| | |
- list = [] | |
- padding = options.collect{ |o| o.aliases.size }.max.to_i * 4 | |
- | |
- options.each do |option| | |
- item = [ option.usage(padding) ] | |
- item.push(option.description ? "# #{option.description}" : "") | |
- | |
- list << item | |
- list << [ "", "# Default: #{option.default}" ] if option.show_default? | |
- end | |
- | |
- unless list.empty? | |
- shell.say(group_name ? "#{group_name} options:" : "Options:") | |
- shell.print_table(list, :ident => 2) | |
- shell.say "" | |
- end | |
- end | |
- | |
- # Deal with default group | |
- global_options = groups.delete(nil) || [] | |
- printer.call(ungrouped_name, global_options) if global_options | |
- | |
- # Print all others | |
- groups = extra_group.merge(groups) if extra_group | |
- groups.each(&printer) | |
- printer | |
- end | |
- | |
- # Raises an error if the word given is a Thor reserved word. | |
- # | |
- def is_thor_reserved_word?(word, type) #:nodoc: | |
- return false unless THOR_RESERVED_WORDS.include?(word.to_s) | |
- raise "#{word.inspect} is a Thor reserved word and cannot be defined as #{type}" | |
- end | |
- | |
- # Build an option and adds it to the given scope. | |
- # | |
- # ==== Parameters | |
- # name<Symbol>:: The name of the argument. | |
- # options<Hash>:: Described in both class_option and method_option. | |
- # | |
- def build_option(name, options, scope) #:nodoc: | |
- scope[name] = Thor::Option.new(name, options[:desc], options[:required], | |
- options[:type], options[:default], options[:banner], | |
- options[:group], options[:aliases]) | |
- end | |
- | |
- # Receives a hash of options, parse them and add to the scope. This is a | |
- # fast way to set a bunch of options: | |
- # | |
- # build_options :foo => true, :bar => :required, :baz => :string | |
- # | |
- # ==== Parameters | |
- # Hash[Symbol => Object] | |
- # | |
- def build_options(options, scope) #:nodoc: | |
- options.each do |key, value| | |
- scope[key] = Thor::Option.parse(key, value) | |
- end | |
- end | |
- | |
- # Finds a task with the given name. If the task belongs to the current | |
- # class, just return it, otherwise dup it and add the fresh copy to the | |
- # current task hash. | |
- # | |
- def find_and_refresh_task(name) #:nodoc: | |
- task = if task = tasks[name.to_s] | |
- task | |
- elsif task = all_tasks[name.to_s] | |
- tasks[name.to_s] = task.clone | |
- else | |
- raise ArgumentError, "You supplied :for => #{name.inspect}, but the task #{name.inspect} could not be found." | |
- end | |
- end | |
- | |
- # Everytime someone inherits from a Thor class, register the klass | |
- # and file into baseclass. | |
- # | |
- def inherited(klass) | |
- Thor::Base.register_klass_file(klass) | |
- end | |
- | |
- # Fire this callback whenever a method is added. Added methods are | |
- # tracked as tasks by invoking the create_task method. | |
- # | |
- def method_added(meth) | |
- meth = meth.to_s | |
- | |
- if meth == "initialize" | |
- initialize_added | |
- return | |
- end | |
- | |
- # Return if it's not a public instance method | |
- return unless public_instance_methods.include?(meth) || | |
- public_instance_methods.include?(meth.to_sym) | |
- | |
- return if @no_tasks || !create_task(meth) | |
- | |
- is_thor_reserved_word?(meth, :task) | |
- Thor::Base.register_klass_file(self) | |
- end | |
- | |
- # Retrieves a value from superclass. If it reaches the baseclass, | |
- # returns default. | |
- # | |
- def from_superclass(method, default=nil) | |
- if self == baseclass || !superclass.respond_to?(method, true) | |
- default | |
- else | |
- value = superclass.send(method) | |
- value.dup if value | |
- end | |
- end | |
- | |
- # A flag that makes the process exit with status 1 if any error happens. | |
- # | |
- def exit_on_failure? | |
- false | |
- end | |
- | |
- # SIGNATURE: Sets the baseclass. This is where the superclass lookup | |
- # finishes. | |
- def baseclass #:nodoc: | |
- end | |
- | |
- # SIGNATURE: Creates a new task if valid_task? is true. This method is | |
- # called when a new method is added to the class. | |
- def create_task(meth) #:nodoc: | |
- end | |
- | |
- # SIGNATURE: Defines behavior when the initialize method is added to the | |
- # class. | |
- def initialize_added #:nodoc: | |
- end | |
- end | |
- end | |
-end | |
diff --git a/railties/lib/rails/vendor/thor-0.11.8/lib/thor/core_ext/hash_with_indifferent_access.rb b/railties/lib/rails/vendor/thor-0.11.8/lib/thor/core_ext/hash_with_indifferent_access.rb | |
deleted file mode 100644 | |
index 78bc5cf..0000000 | |
--- a/railties/lib/rails/vendor/thor-0.11.8/lib/thor/core_ext/hash_with_indifferent_access.rb | |
+++ /dev/null | |
@@ -1,75 +0,0 @@ | |
-class Thor | |
- module CoreExt #:nodoc: | |
- | |
- # A hash with indifferent access and magic predicates. | |
- # | |
- # hash = Thor::CoreExt::HashWithIndifferentAccess.new 'foo' => 'bar', 'baz' => 'bee', 'force' => true | |
- # | |
- # hash[:foo] #=> 'bar' | |
- # hash['foo'] #=> 'bar' | |
- # hash.foo? #=> true | |
- # | |
- class HashWithIndifferentAccess < ::Hash #:nodoc: | |
- | |
- def initialize(hash={}) | |
- super() | |
- hash.each do |key, value| | |
- self[convert_key(key)] = value | |
- end | |
- end | |
- | |
- def [](key) | |
- super(convert_key(key)) | |
- end | |
- | |
- def []=(key, value) | |
- super(convert_key(key), value) | |
- end | |
- | |
- def delete(key) | |
- super(convert_key(key)) | |
- end | |
- | |
- def values_at(*indices) | |
- indices.collect { |key| self[convert_key(key)] } | |
- end | |
- | |
- def merge(other) | |
- dup.merge!(other) | |
- end | |
- | |
- def merge!(other) | |
- other.each do |key, value| | |
- self[convert_key(key)] = value | |
- end | |
- self | |
- end | |
- | |
- protected | |
- | |
- def convert_key(key) | |
- key.is_a?(Symbol) ? key.to_s : key | |
- end | |
- | |
- # Magic predicates. For instance: | |
- # | |
- # options.force? # => !!options['force'] | |
- # options.shebang # => "/usr/lib/local/ruby" | |
- # options.test_framework?(:rspec) # => options[:test_framework] == :rspec | |
- # | |
- def method_missing(method, *args, &block) | |
- method = method.to_s | |
- if method =~ /^(\w+)\?$/ | |
- if args.empty? | |
- !!self[$1] | |
- else | |
- self[$1] == args.first | |
- end | |
- else | |
- self[method] | |
- end | |
- end | |
- | |
- end | |
- end | |
-end | |
diff --git a/railties/lib/rails/vendor/thor-0.11.8/lib/thor/core_ext/ordered_hash.rb b/railties/lib/rails/vendor/thor-0.11.8/lib/thor/core_ext/ordered_hash.rb | |
deleted file mode 100644 | |
index 27fea5b..0000000 | |
--- a/railties/lib/rails/vendor/thor-0.11.8/lib/thor/core_ext/ordered_hash.rb | |
+++ /dev/null | |
@@ -1,100 +0,0 @@ | |
-class Thor | |
- module CoreExt #:nodoc: | |
- | |
- if RUBY_VERSION >= '1.9' | |
- class OrderedHash < ::Hash | |
- end | |
- else | |
- # This class is based on the Ruby 1.9 ordered hashes. | |
- # | |
- # It keeps the semantics and most of the efficiency of normal hashes | |
- # while also keeping track of the order in which elements were set. | |
- # | |
- class OrderedHash #:nodoc: | |
- include Enumerable | |
- | |
- Node = Struct.new(:key, :value, :next, :prev) | |
- | |
- def initialize | |
- @hash = {} | |
- end | |
- | |
- def [](key) | |
- @hash[key] && @hash[key].value | |
- end | |
- | |
- def []=(key, value) | |
- if node = @hash[key] | |
- node.value = value | |
- else | |
- node = Node.new(key, value) | |
- | |
- if @first.nil? | |
- @first = @last = node | |
- else | |
- node.prev = @last | |
- @last.next = node | |
- @last = node | |
- end | |
- end | |
- | |
- @hash[key] = node | |
- value | |
- end | |
- | |
- def delete(key) | |
- if node = @hash[key] | |
- prev_node = node.prev | |
- next_node = node.next | |
- | |
- next_node.prev = prev_node if next_node | |
- prev_node.next = next_node if prev_node | |
- | |
- @first = next_node if @first == node | |
- @last = prev_node if @last == node | |
- | |
- value = node.value | |
- end | |
- | |
- @hash.delete(key) | |
- value | |
- end | |
- | |
- def keys | |
- self.map { |k, v| k } | |
- end | |
- | |
- def values | |
- self.map { |k, v| v } | |
- end | |
- | |
- def each | |
- return unless @first | |
- yield [@first.key, @first.value] | |
- node = @first | |
- yield [node.key, node.value] while node = node.next | |
- self | |
- end | |
- | |
- def merge(other) | |
- hash = self.class.new | |
- | |
- self.each do |key, value| | |
- hash[key] = value | |
- end | |
- | |
- other.each do |key, value| | |
- hash[key] = value | |
- end | |
- | |
- hash | |
- end | |
- | |
- def empty? | |
- @hash.empty? | |
- end | |
- end | |
- end | |
- | |
- end | |
-end | |
diff --git a/railties/lib/rails/vendor/thor-0.11.8/lib/thor/error.rb b/railties/lib/rails/vendor/thor-0.11.8/lib/thor/error.rb | |
deleted file mode 100644 | |
index f9b31a3..0000000 | |
--- a/railties/lib/rails/vendor/thor-0.11.8/lib/thor/error.rb | |
+++ /dev/null | |
@@ -1,27 +0,0 @@ | |
-class Thor | |
- # Thor::Error is raised when it's caused by wrong usage of thor classes. Those | |
- # errors have their backtrace supressed and are nicely shown to the user. | |
- # | |
- # Errors that are caused by the developer, like declaring a method which | |
- # overwrites a thor keyword, it SHOULD NOT raise a Thor::Error. This way, we | |
- # ensure that developer errors are shown with full backtrace. | |
- # | |
- class Error < StandardError | |
- end | |
- | |
- # Raised when a task was not found. | |
- # | |
- class UndefinedTaskError < Error | |
- end | |
- | |
- # Raised when a task was found, but not invoked properly. | |
- # | |
- class InvocationError < Error | |
- end | |
- | |
- class RequiredArgumentMissingError < InvocationError | |
- end | |
- | |
- class MalformattedArgumentError < InvocationError | |
- end | |
-end | |
diff --git a/railties/lib/rails/vendor/thor-0.11.8/lib/thor/group.rb b/railties/lib/rails/vendor/thor-0.11.8/lib/thor/group.rb | |
deleted file mode 100644 | |
index 1e59df2..0000000 | |
--- a/railties/lib/rails/vendor/thor-0.11.8/lib/thor/group.rb | |
+++ /dev/null | |
@@ -1,263 +0,0 @@ | |
-# Thor has a special class called Thor::Group. The main difference to Thor class | |
-# is that it invokes all tasks at once. It also include some methods that allows | |
-# invocations to be done at the class method, which are not available to Thor | |
-# tasks. | |
-# | |
-class Thor::Group | |
- class << self | |
- # The descrition for this Thor::Group. If none is provided, but a source root | |
- # exists, tries to find the USAGE one folder above it, otherwise searches | |
- # in the superclass. | |
- # | |
- # ==== Parameters | |
- # description<String>:: The description for this Thor::Group. | |
- # | |
- def desc(description=nil) | |
- case description | |
- when nil | |
- @desc ||= from_superclass(:desc, nil) | |
- else | |
- @desc = description | |
- end | |
- end | |
- | |
- # Start works differently in Thor::Group, it simply invokes all tasks | |
- # inside the class. | |
- # | |
- def start(given_args=ARGV, config={}) | |
- super do | |
- if Thor::HELP_MAPPINGS.include?(given_args.first) | |
- help(config[:shell]) | |
- return | |
- end | |
- | |
- args, opts = Thor::Options.split(given_args) | |
- new(args, opts, config).invoke | |
- end | |
- end | |
- | |
- # Prints help information. | |
- # | |
- # ==== Options | |
- # short:: When true, shows only usage. | |
- # | |
- def help(shell, options={}) | |
- if options[:short] | |
- shell.say banner | |
- else | |
- shell.say "Usage:" | |
- shell.say " #{banner}" | |
- shell.say | |
- class_options_help(shell) | |
- shell.say self.desc if self.desc | |
- end | |
- end | |
- | |
- # Stores invocations for this class merging with superclass values. | |
- # | |
- def invocations #:nodoc: | |
- @invocations ||= from_superclass(:invocations, {}) | |
- end | |
- | |
- # Stores invocation blocks used on invoke_from_option. | |
- # | |
- def invocation_blocks #:nodoc: | |
- @invocation_blocks ||= from_superclass(:invocation_blocks, {}) | |
- end | |
- | |
- # Invoke the given namespace or class given. It adds an instance | |
- # method that will invoke the klass and task. You can give a block to | |
- # configure how it will be invoked. | |
- # | |
- # The namespace/class given will have its options showed on the help | |
- # usage. Check invoke_from_option for more information. | |
- # | |
- def invoke(*names, &block) | |
- options = names.last.is_a?(Hash) ? names.pop : {} | |
- verbose = options.fetch(:verbose, :white) | |
- | |
- names.each do |name| | |
- invocations[name] = false | |
- invocation_blocks[name] = block if block_given? | |
- | |
- class_eval <<-METHOD, __FILE__, __LINE__ | |
- def _invoke_#{name.to_s.gsub(/\W/, '_')} | |
- klass, task = self.class.prepare_for_invocation(nil, #{name.inspect}) | |
- | |
- if klass | |
- say_status :invoke, #{name.inspect}, #{verbose.inspect} | |
- block = self.class.invocation_blocks[#{name.inspect}] | |
- _invoke_for_class_method klass, task, &block | |
- else | |
- say_status :error, %(#{name.inspect} [not found]), :red | |
- end | |
- end | |
- METHOD | |
- end | |
- end | |
- | |
- # Invoke a thor class based on the value supplied by the user to the | |
- # given option named "name". A class option must be created before this | |
- # method is invoked for each name given. | |
- # | |
- # ==== Examples | |
- # | |
- # class GemGenerator < Thor::Group | |
- # class_option :test_framework, :type => :string | |
- # invoke_from_option :test_framework | |
- # end | |
- # | |
- # ==== Boolean options | |
- # | |
- # In some cases, you want to invoke a thor class if some option is true or | |
- # false. This is automatically handled by invoke_from_option. Then the | |
- # option name is used to invoke the generator. | |
- # | |
- # ==== Preparing for invocation | |
- # | |
- # In some cases you want to customize how a specified hook is going to be | |
- # invoked. You can do that by overwriting the class method | |
- # prepare_for_invocation. The class method must necessarily return a klass | |
- # and an optional task. | |
- # | |
- # ==== Custom invocations | |
- # | |
- # You can also supply a block to customize how the option is giong to be | |
- # invoked. The block receives two parameters, an instance of the current | |
- # class and the klass to be invoked. | |
- # | |
- def invoke_from_option(*names, &block) | |
- options = names.last.is_a?(Hash) ? names.pop : {} | |
- verbose = options.fetch(:verbose, :white) | |
- | |
- names.each do |name| | |
- unless class_options.key?(name) | |
- raise ArgumentError, "You have to define the option #{name.inspect} " << | |
- "before setting invoke_from_option." | |
- end | |
- | |
- invocations[name] = true | |
- invocation_blocks[name] = block if block_given? | |
- | |
- class_eval <<-METHOD, __FILE__, __LINE__ | |
- def _invoke_from_option_#{name.to_s.gsub(/\W/, '_')} | |
- return unless options[#{name.inspect}] | |
- | |
- value = options[#{name.inspect}] | |
- value = #{name.inspect} if TrueClass === value | |
- klass, task = self.class.prepare_for_invocation(#{name.inspect}, value) | |
- | |
- if klass | |
- say_status :invoke, value, #{verbose.inspect} | |
- block = self.class.invocation_blocks[#{name.inspect}] | |
- _invoke_for_class_method klass, task, &block | |
- else | |
- say_status :error, %(\#{value} [not found]), :red | |
- end | |
- end | |
- METHOD | |
- end | |
- end | |
- | |
- # Remove a previously added invocation. | |
- # | |
- # ==== Examples | |
- # | |
- # remove_invocation :test_framework | |
- # | |
- def remove_invocation(*names) | |
- names.each do |name| | |
- remove_task(name) | |
- remove_class_option(name) | |
- invocations.delete(name) | |
- invocation_blocks.delete(name) | |
- end | |
- end | |
- | |
- # Overwrite class options help to allow invoked generators options to be | |
- # shown recursively when invoking a generator. | |
- # | |
- def class_options_help(shell, ungrouped_name=nil, extra_group=nil) #:nodoc: | |
- group_options = {} | |
- | |
- get_options_from_invocations(group_options, class_options) do |klass| | |
- klass.send(:get_options_from_invocations, group_options, class_options) | |
- end | |
- | |
- group_options.merge!(extra_group) if extra_group | |
- super(shell, ungrouped_name, group_options) | |
- end | |
- | |
- # Get invocations array and merge options from invocations. Those | |
- # options are added to group_options hash. Options that already exists | |
- # in base_options are not added twice. | |
- # | |
- def get_options_from_invocations(group_options, base_options) #:nodoc: | |
- invocations.each do |name, from_option| | |
- value = if from_option | |
- option = class_options[name] | |
- option.type == :boolean ? name : option.default | |
- else | |
- name | |
- end | |
- next unless value | |
- | |
- klass, task = prepare_for_invocation(name, value) | |
- next unless klass && klass.respond_to?(:class_options) | |
- | |
- value = value.to_s | |
- human_name = value.respond_to?(:classify) ? value.classify : value | |
- | |
- group_options[human_name] ||= [] | |
- group_options[human_name] += klass.class_options.values.select do |option| | |
- base_options[option.name.to_sym].nil? && option.group.nil? && | |
- !group_options.values.flatten.any? { |i| i.name == option.name } | |
- end | |
- | |
- yield klass if block_given? | |
- end | |
- end | |
- | |
- protected | |
- | |
- # The banner for this class. You can customize it if you are invoking the | |
- # thor class by another ways which is not the Thor::Runner. | |
- # | |
- def banner | |
- "#{self.namespace} #{self.arguments.map {|a| a.usage }.join(' ')}" | |
- end | |
- | |
- def baseclass #:nodoc: | |
- Thor::Group | |
- end | |
- | |
- def create_task(meth) #:nodoc: | |
- tasks[meth.to_s] = Thor::Task.new(meth, nil, nil, nil) | |
- true | |
- end | |
- end | |
- | |
- include Thor::Base | |
- | |
- protected | |
- | |
- # Shortcut to invoke with padding and block handling. Use internally by | |
- # invoke and invoke_from_option class methods. | |
- # | |
- def _invoke_for_class_method(klass, task=nil, *args, &block) #:nodoc: | |
- shell.padding += 1 | |
- | |
- result = if block_given? | |
- if block.arity == 2 | |
- block.call(self, klass) | |
- else | |
- block.call(self, klass, task) | |
- end | |
- else | |
- invoke klass, task, *args | |
- end | |
- | |
- shell.padding -= 1 | |
- result | |
- end | |
-end | |
diff --git a/railties/lib/rails/vendor/thor-0.11.8/lib/thor/invocation.rb b/railties/lib/rails/vendor/thor-0.11.8/lib/thor/invocation.rb | |
deleted file mode 100644 | |
index 32e6a72..0000000 | |
--- a/railties/lib/rails/vendor/thor-0.11.8/lib/thor/invocation.rb | |
+++ /dev/null | |
@@ -1,178 +0,0 @@ | |
-class Thor | |
- module Invocation | |
- def self.included(base) #:nodoc: | |
- base.extend ClassMethods | |
- end | |
- | |
- module ClassMethods | |
- # Prepare for class methods invocations. This method must return a klass to | |
- # have the invoked class options showed in help messages in generators. | |
- # | |
- def prepare_for_invocation(key, name) #:nodoc: | |
- case name | |
- when Symbol, String | |
- Thor::Util.namespace_to_thor_class_and_task(name.to_s, false) | |
- else | |
- name | |
- end | |
- end | |
- end | |
- | |
- # Make initializer aware of invocations and the initializer proc. | |
- # | |
- def initialize(args=[], options={}, config={}, &block) #:nodoc: | |
- @_invocations = config[:invocations] || Hash.new { |h,k| h[k] = [] } | |
- @_initializer = [ args, options, config ] | |
- super | |
- end | |
- | |
- # Receives a name and invokes it. The name can be a string (either "task" or | |
- # "namespace:task"), a Thor::Task, a Class or a Thor instance. If the task | |
- # cannot be guessed by name, it can also be supplied as second argument. | |
- # | |
- # You can also supply the arguments, options and configuration values for | |
- # the task to be invoked, if none is given, the same values used to | |
- # initialize the invoker are used to initialize the invoked. | |
- # | |
- # ==== Examples | |
- # | |
- # class A < Thor | |
- # def foo | |
- # invoke :bar | |
- # invoke "b:hello", ["José"] | |
- # end | |
- # | |
- # def bar | |
- # invoke "b:hello", ["José"] | |
- # end | |
- # end | |
- # | |
- # class B < Thor | |
- # def hello(name) | |
- # puts "hello #{name}" | |
- # end | |
- # end | |
- # | |
- # You can notice that the method "foo" above invokes two tasks: "bar", | |
- # which belongs to the same class and "hello" which belongs to the class B. | |
- # | |
- # By using an invocation system you ensure that a task is invoked only once. | |
- # In the example above, invoking "foo" will invoke "b:hello" just once, even | |
- # if it's invoked later by "bar" method. | |
- # | |
- # When class A invokes class B, all arguments used on A initialization are | |
- # supplied to B. This allows lazy parse of options. Let's suppose you have | |
- # some rspec tasks: | |
- # | |
- # class Rspec < Thor::Group | |
- # class_option :mock_framework, :type => :string, :default => :rr | |
- # | |
- # def invoke_mock_framework | |
- # invoke "rspec:#{options[:mock_framework]}" | |
- # end | |
- # end | |
- # | |
- # As you noticed, it invokes the given mock framework, which might have its | |
- # own options: | |
- # | |
- # class Rspec::RR < Thor::Group | |
- # class_option :style, :type => :string, :default => :mock | |
- # end | |
- # | |
- # Since it's not rspec concern to parse mock framework options, when RR | |
- # is invoked all options are parsed again, so RR can extract only the options | |
- # that it's going to use. | |
- # | |
- # If you want Rspec::RR to be initialized with its own set of options, you | |
- # have to do that explicitely: | |
- # | |
- # invoke "rspec:rr", [], :style => :foo | |
- # | |
- # Besides giving an instance, you can also give a class to invoke: | |
- # | |
- # invoke Rspec::RR, [], :style => :foo | |
- # | |
- def invoke(name=nil, task=nil, args=nil, opts=nil, config=nil) | |
- task, args, opts, config = nil, task, args, opts if task.nil? || task.is_a?(Array) | |
- args, opts, config = nil, args, opts if args.is_a?(Hash) | |
- | |
- object, task = _prepare_for_invocation(name, task) | |
- klass, instance = _initialize_klass_with_initializer(object, args, opts, config) | |
- | |
- method_args = [] | |
- current = @_invocations[klass] | |
- | |
- iterator = proc do |_, task| | |
- unless current.include?(task.name) | |
- current << task.name | |
- task.run(instance, method_args) | |
- end | |
- end | |
- | |
- if task | |
- args ||= [] | |
- method_args = args[Range.new(klass.arguments.size, -1)] || [] | |
- iterator.call(nil, task) | |
- else | |
- klass.all_tasks.map(&iterator) | |
- end | |
- end | |
- | |
- protected | |
- | |
- # Configuration values that are shared between invocations. | |
- # | |
- def _shared_configuration #:nodoc: | |
- { :invocations => @_invocations } | |
- end | |
- | |
- # Prepare for invocation in the instance level. In this case, we have to | |
- # take into account that a just a task name from the current class was | |
- # given or even a Thor::Task object. | |
- # | |
- def _prepare_for_invocation(name, sent_task=nil) #:nodoc: | |
- if name.is_a?(Thor::Task) | |
- task = name | |
- elsif task = self.class.all_tasks[name.to_s] | |
- object = self | |
- else | |
- object, task = self.class.prepare_for_invocation(nil, name) | |
- task ||= sent_task | |
- end | |
- | |
- # If the object was not set, use self and use the name as task. | |
- object, task = self, name unless object | |
- return object, _validate_task(object, task) | |
- end | |
- | |
- # Check if the object given is a Thor class object and get a task object | |
- # for it. | |
- # | |
- def _validate_task(object, task) #:nodoc: | |
- klass = object.is_a?(Class) ? object : object.class | |
- raise "Expected Thor class, got #{klass}" unless klass <= Thor::Base | |
- | |
- task ||= klass.default_task if klass <= Thor | |
- task = klass.all_tasks[task.to_s] || Thor::Task::Dynamic.new(task) if task && !task.is_a?(Thor::Task) | |
- task | |
- end | |
- | |
- # Initialize klass using values stored in the @_initializer. | |
- # | |
- def _initialize_klass_with_initializer(object, args, opts, config) #:nodoc: | |
- if object.is_a?(Class) | |
- klass = object | |
- | |
- stored_args, stored_opts, stored_config = @_initializer | |
- args ||= stored_args.dup | |
- opts ||= stored_opts.dup | |
- | |
- config ||= {} | |
- config = stored_config.merge(_shared_configuration).merge!(config) | |
- [ klass, klass.new(args, opts, config) ] | |
- else | |
- [ object.class, object ] | |
- end | |
- end | |
- end | |
-end | |
diff --git a/railties/lib/rails/vendor/thor-0.11.8/lib/thor/parser.rb b/railties/lib/rails/vendor/thor-0.11.8/lib/thor/parser.rb | |
deleted file mode 100644 | |
index 57a3f6e..0000000 | |
--- a/railties/lib/rails/vendor/thor-0.11.8/lib/thor/parser.rb | |
+++ /dev/null | |
@@ -1,4 +0,0 @@ | |
-require 'thor/parser/argument' | |
-require 'thor/parser/arguments' | |
-require 'thor/parser/option' | |
-require 'thor/parser/options' | |
diff --git a/railties/lib/rails/vendor/thor-0.11.8/lib/thor/parser/argument.rb b/railties/lib/rails/vendor/thor-0.11.8/lib/thor/parser/argument.rb | |
deleted file mode 100644 | |
index aa8ace4..0000000 | |
--- a/railties/lib/rails/vendor/thor-0.11.8/lib/thor/parser/argument.rb | |
+++ /dev/null | |
@@ -1,67 +0,0 @@ | |
-class Thor | |
- class Argument #:nodoc: | |
- VALID_TYPES = [ :numeric, :hash, :array, :string ] | |
- | |
- attr_reader :name, :description, :required, :type, :default, :banner | |
- alias :human_name :name | |
- | |
- def initialize(name, description=nil, required=true, type=:string, default=nil, banner=nil) | |
- class_name = self.class.name.split("::").last | |
- | |
- raise ArgumentError, "#{class_name} name can't be nil." if name.nil? | |
- raise ArgumentError, "Type :#{type} is not valid for #{class_name.downcase}s." if type && !valid_type?(type) | |
- | |
- @name = name.to_s | |
- @description = description | |
- @required = required || false | |
- @type = (type || :string).to_sym | |
- @default = default | |
- @banner = banner || default_banner | |
- | |
- validate! # Trigger specific validations | |
- end | |
- | |
- def usage | |
- required? ? banner : "[#{banner}]" | |
- end | |
- | |
- def required? | |
- required | |
- end | |
- | |
- def show_default? | |
- case default | |
- when Array, String, Hash | |
- !default.empty? | |
- else | |
- default | |
- end | |
- end | |
- | |
- protected | |
- | |
- def validate! | |
- raise ArgumentError, "An argument cannot be required and have default value." if required? && !default.nil? | |
- end | |
- | |
- def valid_type?(type) | |
- VALID_TYPES.include?(type.to_sym) | |
- end | |
- | |
- def default_banner | |
- case type | |
- when :boolean | |
- nil | |
- when :string, :default | |
- human_name.upcase | |
- when :numeric | |
- "N" | |
- when :hash | |
- "key:value" | |
- when :array | |
- "one two three" | |
- end | |
- end | |
- | |
- end | |
-end | |
diff --git a/railties/lib/rails/vendor/thor-0.11.8/lib/thor/parser/arguments.rb b/railties/lib/rails/vendor/thor-0.11.8/lib/thor/parser/arguments.rb | |
deleted file mode 100644 | |
index fb5d965..0000000 | |
--- a/railties/lib/rails/vendor/thor-0.11.8/lib/thor/parser/arguments.rb | |
+++ /dev/null | |
@@ -1,145 +0,0 @@ | |
-class Thor | |
- class Arguments #:nodoc: | |
- NUMERIC = /(\d*\.\d+|\d+)/ | |
- | |
- # Receives an array of args and returns two arrays, one with arguments | |
- # and one with switches. | |
- # | |
- def self.split(args) | |
- arguments = [] | |
- | |
- args.each do |item| | |
- break if item =~ /^-/ | |
- arguments << item | |
- end | |
- | |
- return arguments, args[Range.new(arguments.size, -1)] | |
- end | |
- | |
- def self.parse(base, args) | |
- new(base).parse(args) | |
- end | |
- | |
- # Takes an array of Thor::Argument objects. | |
- # | |
- def initialize(arguments=[]) | |
- @assigns, @non_assigned_required = {}, [] | |
- @switches = arguments | |
- | |
- arguments.each do |argument| | |
- if argument.default | |
- @assigns[argument.human_name] = argument.default | |
- elsif argument.required? | |
- @non_assigned_required << argument | |
- end | |
- end | |
- end | |
- | |
- def parse(args) | |
- @pile = args.dup | |
- | |
- @switches.each do |argument| | |
- break unless peek | |
- @non_assigned_required.delete(argument) | |
- @assigns[argument.human_name] = send(:"parse_#{argument.type}", argument.human_name) | |
- end | |
- | |
- check_requirement! | |
- @assigns | |
- end | |
- | |
- private | |
- | |
- def peek | |
- @pile.first | |
- end | |
- | |
- def shift | |
- @pile.shift | |
- end | |
- | |
- def unshift(arg) | |
- unless arg.kind_of?(Array) | |
- @pile.unshift(arg) | |
- else | |
- @pile = arg + @pile | |
- end | |
- end | |
- | |
- def current_is_value? | |
- peek && peek.to_s !~ /^-/ | |
- end | |
- | |
- # Runs through the argument array getting strings that contains ":" and | |
- # mark it as a hash: | |
- # | |
- # [ "name:string", "age:integer" ] | |
- # | |
- # Becomes: | |
- # | |
- # { "name" => "string", "age" => "integer" } | |
- # | |
- def parse_hash(name) | |
- return shift if peek.is_a?(Hash) | |
- hash = {} | |
- | |
- while current_is_value? && peek.include?(?:) | |
- key, value = shift.split(':') | |
- hash[key] = value | |
- end | |
- hash | |
- end | |
- | |
- # Runs through the argument array getting all strings until no string is | |
- # found or a switch is found. | |
- # | |
- # ["a", "b", "c"] | |
- # | |
- # And returns it as an array: | |
- # | |
- # ["a", "b", "c"] | |
- # | |
- def parse_array(name) | |
- return shift if peek.is_a?(Array) | |
- array = [] | |
- | |
- while current_is_value? | |
- array << shift | |
- end | |
- array | |
- end | |
- | |
- # Check if the peel is numeric ofrmat and return a Float or Integer. | |
- # Otherwise raises an error. | |
- # | |
- def parse_numeric(name) | |
- return shift if peek.is_a?(Numeric) | |
- | |
- unless peek =~ NUMERIC && $& == peek | |
- raise MalformattedArgumentError, "expected numeric value for '#{name}'; got #{peek.inspect}" | |
- end | |
- | |
- $&.index('.') ? shift.to_f : shift.to_i | |
- end | |
- | |
- # Parse string, i.e., just return the current value in the pile. | |
- # | |
- def parse_string(name) | |
- shift | |
- end | |
- | |
- # Raises an error if @non_assigned_required array is not empty. | |
- # | |
- def check_requirement! | |
- unless @non_assigned_required.empty? | |
- names = @non_assigned_required.map do |o| | |
- o.respond_to?(:switch_name) ? o.switch_name : o.human_name | |
- end.join("', '") | |
- | |
- class_name = self.class.name.split('::').last.downcase | |
- raise RequiredArgumentMissingError, "no value provided for required #{class_name} '#{names}'" | |
- end | |
- end | |
- | |
- end | |
-end | |
diff --git a/railties/lib/rails/vendor/thor-0.11.8/lib/thor/parser/option.rb b/railties/lib/rails/vendor/thor-0.11.8/lib/thor/parser/option.rb | |
deleted file mode 100644 | |
index 9e40ec7..0000000 | |
--- a/railties/lib/rails/vendor/thor-0.11.8/lib/thor/parser/option.rb | |
+++ /dev/null | |
@@ -1,132 +0,0 @@ | |
-class Thor | |
- class Option < Argument #:nodoc: | |
- attr_reader :aliases, :group | |
- | |
- VALID_TYPES = [:boolean, :numeric, :hash, :array, :string] | |
- | |
- def initialize(name, description=nil, required=nil, type=nil, default=nil, banner=nil, group=nil, aliases=nil) | |
- super(name, description, required, type, default, banner) | |
- @aliases = [*aliases].compact | |
- @group = group.to_s.capitalize if group | |
- end | |
- | |
- # This parse quick options given as method_options. It makes several | |
- # assumptions, but you can be more specific using the option method. | |
- # | |
- # parse :foo => "bar" | |
- # #=> Option foo with default value bar | |
- # | |
- # parse [:foo, :baz] => "bar" | |
- # #=> Option foo with default value bar and alias :baz | |
- # | |
- # parse :foo => :required | |
- # #=> Required option foo without default value | |
- # | |
- # parse :foo => 2 | |
- # #=> Option foo with default value 2 and type numeric | |
- # | |
- # parse :foo => :numeric | |
- # #=> Option foo without default value and type numeric | |
- # | |
- # parse :foo => true | |
- # #=> Option foo with default value true and type boolean | |
- # | |
- # The valid types are :boolean, :numeric, :hash, :array and :string. If none | |
- # is given a default type is assumed. This default type accepts arguments as | |
- # string (--foo=value) or booleans (just --foo). | |
- # | |
- # By default all options are optional, unless :required is given. | |
- # | |
- def self.parse(key, value) | |
- if key.is_a?(Array) | |
- name, *aliases = key | |
- else | |
- name, aliases = key, [] | |
- end | |
- | |
- name = name.to_s | |
- default = value | |
- | |
- type = case value | |
- when Symbol | |
- default = nil | |
- | |
- if VALID_TYPES.include?(value) | |
- value | |
- elsif required = (value == :required) | |
- :string | |
- elsif value == :optional | |
- # TODO Remove this warning in the future. | |
- warn "Optional type is deprecated. Choose :boolean or :string instead. Assumed to be :boolean." | |
- :boolean | |
- end | |
- when TrueClass, FalseClass | |
- :boolean | |
- when Numeric | |
- :numeric | |
- when Hash, Array, String | |
- value.class.name.downcase.to_sym | |
- end | |
- | |
- self.new(name.to_s, nil, required, type, default, nil, nil, aliases) | |
- end | |
- | |
- def switch_name | |
- @switch_name ||= dasherized? ? name : dasherize(name) | |
- end | |
- | |
- def human_name | |
- @human_name ||= dasherized? ? undasherize(name) : name | |
- end | |
- | |
- def usage(padding=0) | |
- sample = if banner && !banner.to_s.empty? | |
- "#{switch_name}=#{banner}" | |
- else | |
- switch_name | |
- end | |
- | |
- sample = "[#{sample}]" unless required? | |
- | |
- if aliases.empty? | |
- (" " * padding) << sample | |
- else | |
- "#{aliases.join(', ')}, #{sample}" | |
- end | |
- end | |
- | |
- # Allow some type predicates as: boolean?, string? and etc. | |
- # | |
- def method_missing(method, *args, &block) | |
- given = method.to_s.sub(/\?$/, '').to_sym | |
- if valid_type?(given) | |
- self.type == given | |
- else | |
- super | |
- end | |
- end | |
- | |
- protected | |
- | |
- def validate! | |
- raise ArgumentError, "An option cannot be boolean and required." if boolean? && required? | |
- end | |
- | |
- def valid_type?(type) | |
- VALID_TYPES.include?(type.to_sym) | |
- end | |
- | |
- def dasherized? | |
- name.index('-') == 0 | |
- end | |
- | |
- def undasherize(str) | |
- str.sub(/^-{1,2}/, '') | |
- end | |
- | |
- def dasherize(str) | |
- (str.length > 1 ? "--" : "-") + str.gsub('_', '-') | |
- end | |
- | |
- end | |
-end | |
diff --git a/railties/lib/rails/vendor/thor-0.11.8/lib/thor/parser/options.rb b/railties/lib/rails/vendor/thor-0.11.8/lib/thor/parser/options.rb | |
deleted file mode 100644 | |
index 7509230..0000000 | |
--- a/railties/lib/rails/vendor/thor-0.11.8/lib/thor/parser/options.rb | |
+++ /dev/null | |
@@ -1,142 +0,0 @@ | |
-class Thor | |
- # This is a modified version of Daniel Berger's Getopt::Long class, licensed | |
- # under Ruby's license. | |
- # | |
- class Options < Arguments #:nodoc: | |
- LONG_RE = /^(--\w+[-\w+]*)$/ | |
- SHORT_RE = /^(-[a-z])$/i | |
- EQ_RE = /^(--\w+[-\w+]*|-[a-z])=(.*)$/i | |
- SHORT_SQ_RE = /^-([a-z]{2,})$/i # Allow either -x -v or -xv style for single char args | |
- SHORT_NUM = /^(-[a-z])#{NUMERIC}$/i | |
- | |
- # Receives a hash and makes it switches. | |
- # | |
- def self.to_switches(options) | |
- options.map do |key, value| | |
- case value | |
- when true | |
- "--#{key}" | |
- when Array | |
- "--#{key} #{value.map{ |v| v.inspect }.join(' ')}" | |
- when Hash | |
- "--#{key} #{value.map{ |k,v| "#{k}:#{v}" }.join(' ')}" | |
- when nil, false | |
- "" | |
- else | |
- "--#{key} #{value.inspect}" | |
- end | |
- end.join(" ") | |
- end | |
- | |
- # Takes a hash of Thor::Option objects. | |
- # | |
- def initialize(options={}) | |
- options = options.values | |
- super(options) | |
- @shorts, @switches = {}, {} | |
- | |
- options.each do |option| | |
- @switches[option.switch_name] = option | |
- | |
- option.aliases.each do |short| | |
- @shorts[short.to_s] ||= option.switch_name | |
- end | |
- end | |
- end | |
- | |
- def parse(args) | |
- @pile = args.dup | |
- | |
- while peek | |
- if current_is_switch? | |
- case shift | |
- when SHORT_SQ_RE | |
- unshift($1.split('').map { |f| "-#{f}" }) | |
- next | |
- when EQ_RE, SHORT_NUM | |
- unshift($2) | |
- switch = $1 | |
- when LONG_RE, SHORT_RE | |
- switch = $1 | |
- end | |
- | |
- switch = normalize_switch(switch) | |
- next unless option = switch_option(switch) | |
- | |
- @assigns[option.human_name] = parse_peek(switch, option) | |
- else | |
- shift | |
- end | |
- end | |
- | |
- check_requirement! | |
- @assigns | |
- end | |
- | |
- protected | |
- | |
- # Returns true if the current value in peek is a registered switch. | |
- # | |
- def current_is_switch? | |
- case peek | |
- when LONG_RE, SHORT_RE, EQ_RE, SHORT_NUM | |
- switch?($1) | |
- when SHORT_SQ_RE | |
- $1.split('').any? { |f| switch?("-#{f}") } | |
- end | |
- end | |
- | |
- def switch?(arg) | |
- switch_option(arg) || @shorts.key?(arg) | |
- end | |
- | |
- def switch_option(arg) | |
- if match = no_or_skip?(arg) | |
- @switches[arg] || @switches["--#{match}"] | |
- else | |
- @switches[arg] | |
- end | |
- end | |
- | |
- def no_or_skip?(arg) | |
- arg =~ /^--(no|skip)-([-\w]+)$/ | |
- $2 | |
- end | |
- | |
- # Check if the given argument is actually a shortcut. | |
- # | |
- def normalize_switch(arg) | |
- @shorts.key?(arg) ? @shorts[arg] : arg | |
- end | |
- | |
- # Parse boolean values which can be given as --foo=true, --foo or --no-foo. | |
- # | |
- def parse_boolean(switch) | |
- if current_is_value? | |
- ["true", "TRUE", "t", "T", true].include?(shift) | |
- else | |
- @switches.key?(switch) || !no_or_skip?(switch) | |
- end | |
- end | |
- | |
- # Parse the value at the peek analyzing if it requires an input or not. | |
- # | |
- def parse_peek(switch, option) | |
- unless current_is_value? | |
- if option.boolean? | |
- # No problem for boolean types | |
- elsif no_or_skip?(switch) | |
- return nil # User set value to nil | |
- elsif option.string? && !option.required? | |
- return option.human_name # Return the option name | |
- else | |
- raise MalformattedArgumentError, "no value provided for option '#{switch}'" | |
- end | |
- end | |
- | |
- @non_assigned_required.delete(option) | |
- send(:"parse_#{option.type}", switch) | |
- end | |
- | |
- end | |
-end | |
diff --git a/railties/lib/rails/vendor/thor-0.11.8/lib/thor/rake_compat.rb b/railties/lib/rails/vendor/thor-0.11.8/lib/thor/rake_compat.rb | |
deleted file mode 100644 | |
index 0d0757f..0000000 | |
--- a/railties/lib/rails/vendor/thor-0.11.8/lib/thor/rake_compat.rb | |
+++ /dev/null | |
@@ -1,66 +0,0 @@ | |
-require 'rake' | |
- | |
-class Thor | |
- # Adds a compatibility layer to your Thor classes which allows you to use | |
- # rake package tasks. For example, to use rspec rake tasks, one can do: | |
- # | |
- # require 'thor/rake_compat' | |
- # | |
- # class Default < Thor | |
- # include Thor::RakeCompat | |
- # | |
- # Spec::Rake::SpecTask.new(:spec) do |t| | |
- # t.spec_opts = ['--options', "spec/spec.opts"] | |
- # t.spec_files = FileList['spec/**/*_spec.rb'] | |
- # end | |
- # end | |
- # | |
- module RakeCompat | |
- def self.rake_classes | |
- @rake_classes ||= [] | |
- end | |
- | |
- def self.included(base) | |
- # Hack. Make rakefile point to invoker, so rdoc task is generated properly. | |
- rakefile = File.basename(caller[0].match(/(.*):\d+/)[1]) | |
- Rake.application.instance_variable_set(:@rakefile, rakefile) | |
- self.rake_classes << base | |
- end | |
- end | |
-end | |
- | |
-class Object #:nodoc: | |
- alias :rake_task :task | |
- alias :rake_namespace :namespace | |
- | |
- def task(*args, &block) | |
- task = rake_task(*args, &block) | |
- | |
- if klass = Thor::RakeCompat.rake_classes.last | |
- non_namespaced_name = task.name.split(':').last | |
- | |
- description = non_namespaced_name | |
- description << task.arg_names.map{ |n| n.to_s.upcase }.join(' ') | |
- description.strip! | |
- | |
- klass.desc description, task.comment || non_namespaced_name | |
- klass.send :define_method, non_namespaced_name do |*args| | |
- Rake::Task[task.name.to_sym].invoke(*args) | |
- end | |
- end | |
- | |
- task | |
- end | |
- | |
- def namespace(name, &block) | |
- if klass = Thor::RakeCompat.rake_classes.last | |
- const_name = Thor::Util.camel_case(name.to_s).to_sym | |
- klass.const_set(const_name, Class.new(Thor)) | |
- new_klass = klass.const_get(const_name) | |
- Thor::RakeCompat.rake_classes << new_klass | |
- end | |
- | |
- rake_namespace(name, &block) | |
- Thor::RakeCompat.rake_classes.pop | |
- end | |
-end | |
diff --git a/railties/lib/rails/vendor/thor-0.11.8/lib/thor/runner.rb b/railties/lib/rails/vendor/thor-0.11.8/lib/thor/runner.rb | |
deleted file mode 100644 | |
index 9dc70ea..0000000 | |
--- a/railties/lib/rails/vendor/thor-0.11.8/lib/thor/runner.rb | |
+++ /dev/null | |
@@ -1,299 +0,0 @@ | |
-require 'fileutils' | |
-require 'open-uri' | |
-require 'yaml' | |
-require 'digest/md5' | |
-require 'pathname' | |
- | |
-class Thor::Runner < Thor #:nodoc: | |
- map "-T" => :list, "-i" => :install, "-u" => :update | |
- | |
- # Override Thor#help so it can give information about any class and any method. | |
- # | |
- def help(meth=nil) | |
- if meth && !self.respond_to?(meth) | |
- initialize_thorfiles(meth) | |
- klass, task = Thor::Util.namespace_to_thor_class_and_task(meth) | |
- # Send mapping -h because it works with Thor::Group too | |
- klass.start(["-h", task].compact, :shell => self.shell) | |
- else | |
- super | |
- end | |
- end | |
- | |
- # If a task is not found on Thor::Runner, method missing is invoked and | |
- # Thor::Runner is then responsable for finding the task in all classes. | |
- # | |
- def method_missing(meth, *args) | |
- meth = meth.to_s | |
- initialize_thorfiles(meth) | |
- klass, task = Thor::Util.namespace_to_thor_class_and_task(meth) | |
- args.unshift(task) if task | |
- klass.start(args, :shell => shell) | |
- end | |
- | |
- desc "install NAME", "Install an optionally named Thor file into your system tasks" | |
- method_options :as => :string, :relative => :boolean | |
- def install(name) | |
- initialize_thorfiles | |
- | |
- # If a directory name is provided as the argument, look for a 'main.thor' | |
- # task in said directory. | |
- begin | |
- if File.directory?(File.expand_path(name)) | |
- base, package = File.join(name, "main.thor"), :directory | |
- contents = open(base).read | |
- else | |
- base, package = name, :file | |
- contents = open(name).read | |
- end | |
- rescue OpenURI::HTTPError | |
- raise Error, "Error opening URI '#{name}'" | |
- rescue Errno::ENOENT | |
- raise Error, "Error opening file '#{name}'" | |
- end | |
- | |
- say "Your Thorfile contains:" | |
- say contents | |
- | |
- return false if no?("Do you wish to continue [y/N]?") | |
- | |
- as = options["as"] || begin | |
- first_line = contents.split("\n")[0] | |
- (match = first_line.match(/\s*#\s*module:\s*([^\n]*)/)) ? match[1].strip : nil | |
- end | |
- | |
- unless as | |
- basename = File.basename(name) | |
- as = ask("Please specify a name for #{name} in the system repository [#{basename}]:") | |
- as = basename if as.empty? | |
- end | |
- | |
- location = if options[:relative] || name =~ /^http:\/\// | |
- name | |
- else | |
- File.expand_path(name) | |
- end | |
- | |
- thor_yaml[as] = { | |
- :filename => Digest::MD5.hexdigest(name + as), | |
- :location => location, | |
- :namespaces => Thor::Util.namespaces_in_content(contents, base) | |
- } | |
- | |
- save_yaml(thor_yaml) | |
- say "Storing thor file in your system repository" | |
- destination = File.join(thor_root, thor_yaml[as][:filename]) | |
- | |
- if package == :file | |
- File.open(destination, "w") { |f| f.puts contents } | |
- else | |
- FileUtils.cp_r(name, destination) | |
- end | |
- | |
- thor_yaml[as][:filename] # Indicate success | |
- end | |
- | |
- desc "uninstall NAME", "Uninstall a named Thor module" | |
- def uninstall(name) | |
- raise Error, "Can't find module '#{name}'" unless thor_yaml[name] | |
- say "Uninstalling #{name}." | |
- FileUtils.rm_rf(File.join(thor_root, "#{thor_yaml[name][:filename]}")) | |
- | |
- thor_yaml.delete(name) | |
- save_yaml(thor_yaml) | |
- | |
- puts "Done." | |
- end | |
- | |
- desc "update NAME", "Update a Thor file from its original location" | |
- def update(name) | |
- raise Error, "Can't find module '#{name}'" if !thor_yaml[name] || !thor_yaml[name][:location] | |
- | |
- say "Updating '#{name}' from #{thor_yaml[name][:location]}" | |
- | |
- old_filename = thor_yaml[name][:filename] | |
- self.options = self.options.merge("as" => name) | |
- filename = install(thor_yaml[name][:location]) | |
- | |
- unless filename == old_filename | |
- File.delete(File.join(thor_root, old_filename)) | |
- end | |
- end | |
- | |
- desc "installed", "List the installed Thor modules and tasks" | |
- method_options :internal => :boolean | |
- def installed | |
- initialize_thorfiles(nil, true) | |
- | |
- klasses = Thor::Base.subclasses | |
- klasses -= [Thor, Thor::Runner] unless options["internal"] | |
- | |
- display_klasses(true, klasses) | |
- end | |
- | |
- desc "list [SEARCH]", "List the available thor tasks (--substring means .*SEARCH)" | |
- method_options :substring => :boolean, :group => :string, :all => :boolean | |
- def list(search="") | |
- initialize_thorfiles | |
- | |
- search = ".*#{search}" if options["substring"] | |
- search = /^#{search}.*/i | |
- group = options[:group] || "standard" | |
- | |
- klasses = Thor::Base.subclasses.select do |k| | |
- (options[:all] || k.group == group) && k.namespace =~ search | |
- end | |
- | |
- display_klasses(false, klasses) | |
- end | |
- | |
- private | |
- | |
- def thor_root | |
- Thor::Util.thor_root | |
- end | |
- | |
- def thor_yaml | |
- @thor_yaml ||= begin | |
- yaml_file = File.join(thor_root, "thor.yml") | |
- yaml = YAML.load_file(yaml_file) if File.exists?(yaml_file) | |
- yaml || {} | |
- end | |
- end | |
- | |
- # Save the yaml file. If none exists in thor root, creates one. | |
- # | |
- def save_yaml(yaml) | |
- yaml_file = File.join(thor_root, "thor.yml") | |
- | |
- unless File.exists?(yaml_file) | |
- FileUtils.mkdir_p(thor_root) | |
- yaml_file = File.join(thor_root, "thor.yml") | |
- FileUtils.touch(yaml_file) | |
- end | |
- | |
- File.open(yaml_file, "w") { |f| f.puts yaml.to_yaml } | |
- end | |
- | |
- def self.exit_on_failure? | |
- true | |
- end | |
- | |
- # Load the thorfiles. If relevant_to is supplied, looks for specific files | |
- # in the thor_root instead of loading them all. | |
- # | |
- # By default, it also traverses the current path until find Thor files, as | |
- # described in thorfiles. This look up can be skipped by suppliying | |
- # skip_lookup true. | |
- # | |
- def initialize_thorfiles(relevant_to=nil, skip_lookup=false) | |
- thorfiles(relevant_to, skip_lookup).each do |f| | |
- Thor::Util.load_thorfile(f) unless Thor::Base.subclass_files.keys.include?(File.expand_path(f)) | |
- end | |
- end | |
- | |
- # Finds Thorfiles by traversing from your current directory down to the root | |
- # directory of your system. If at any time we find a Thor file, we stop. | |
- # | |
- # We also ensure that system-wide Thorfiles are loaded first, so local | |
- # Thorfiles can override them. | |
- # | |
- # ==== Example | |
- # | |
- # If we start at /Users/wycats/dev/thor ... | |
- # | |
- # 1. /Users/wycats/dev/thor | |
- # 2. /Users/wycats/dev | |
- # 3. /Users/wycats <-- we find a Thorfile here, so we stop | |
- # | |
- # Suppose we start at c:\Documents and Settings\james\dev\thor ... | |
- # | |
- # 1. c:\Documents and Settings\james\dev\thor | |
- # 2. c:\Documents and Settings\james\dev | |
- # 3. c:\Documents and Settings\james | |
- # 4. c:\Documents and Settings | |
- # 5. c:\ <-- no Thorfiles found! | |
- # | |
- def thorfiles(relevant_to=nil, skip_lookup=false) | |
- # TODO Remove this dealing with deprecated thor when :namespaces: is available as constants | |
- save_yaml(thor_yaml) if Thor::Util.convert_constants_to_namespaces(thor_yaml) | |
- | |
- thorfiles = [] | |
- | |
- unless skip_lookup | |
- Pathname.pwd.ascend do |path| | |
- thorfiles = Thor::Util.globs_for(path).map { |g| Dir[g] }.flatten | |
- break unless thorfiles.empty? | |
- end | |
- end | |
- | |
- files = (relevant_to ? thorfiles_relevant_to(relevant_to) : Thor::Util.thor_root_glob) | |
- files += thorfiles | |
- files -= ["#{thor_root}/thor.yml"] | |
- | |
- files.map! do |file| | |
- File.directory?(file) ? File.join(file, "main.thor") : file | |
- end | |
- end | |
- | |
- # Load thorfiles relevant to the given method. If you provide "foo:bar" it | |
- # will load all thor files in the thor.yaml that has "foo" e "foo:bar" | |
- # namespaces registered. | |
- # | |
- def thorfiles_relevant_to(meth) | |
- lookup = [ meth, meth.split(":")[0...-1].join(":") ] | |
- | |
- files = thor_yaml.select do |k, v| | |
- v[:namespaces] && !(v[:namespaces] & lookup).empty? | |
- end | |
- | |
- files.map { |k, v| File.join(thor_root, "#{v[:filename]}") } | |
- end | |
- | |
- # Display information about the given klasses. If with_module is given, | |
- # it shows a table with information extracted from the yaml file. | |
- # | |
- def display_klasses(with_modules=false, klasses=Thor.subclasses) | |
- klasses -= [Thor, Thor::Runner] unless with_modules | |
- raise Error, "No Thor tasks available" if klasses.empty? | |
- | |
- if with_modules && !thor_yaml.empty? | |
- info = [] | |
- labels = ["Modules", "Namespaces"] | |
- | |
- info << labels | |
- info << [ "-" * labels[0].size, "-" * labels[1].size ] | |
- | |
- thor_yaml.each do |name, hash| | |
- info << [ name, hash[:namespaces].join(", ") ] | |
- end | |
- | |
- print_table info | |
- say "" | |
- end | |
- | |
- unless klasses.empty? | |
- klasses.dup.each do |klass| | |
- klasses -= Thor::Util.thor_classes_in(klass) | |
- end | |
- | |
- klasses.each { |k| display_tasks(k) } | |
- else | |
- say "\033[1;34mNo Thor tasks available\033[0m" | |
- end | |
- end | |
- | |
- # Display tasks from the given Thor class. | |
- # | |
- def display_tasks(klass) | |
- unless klass.tasks.empty? | |
- base = klass.namespace | |
- | |
- color = base == "default" ? :magenta : :blue | |
- say shell.set_color(base, color, true) | |
- say "-" * base.length | |
- | |
- klass.help(shell, :short => true, :ident => 0, :namespace => true) | |
- end | |
- end | |
-end | |
diff --git a/railties/lib/rails/vendor/thor-0.11.8/lib/thor/shell.rb b/railties/lib/rails/vendor/thor-0.11.8/lib/thor/shell.rb | |
deleted file mode 100644 | |
index 1dc8f0e..0000000 | |
--- a/railties/lib/rails/vendor/thor-0.11.8/lib/thor/shell.rb | |
+++ /dev/null | |
@@ -1,78 +0,0 @@ | |
-require 'rbconfig' | |
-require 'thor/shell/color' | |
- | |
-class Thor | |
- module Base | |
- # Returns the shell used in all Thor classes. If you are in a Unix platform | |
- # it will use a colored log, otherwise it will use a basic one without color. | |
- # | |
- def self.shell | |
- @shell ||= if Config::CONFIG['host_os'] =~ /mswin|mingw/ | |
- Thor::Shell::Basic | |
- else | |
- Thor::Shell::Color | |
- end | |
- end | |
- | |
- # Sets the shell used in all Thor classes. | |
- # | |
- def self.shell=(klass) | |
- @shell = klass | |
- end | |
- end | |
- | |
- module Shell | |
- SHELL_DELEGATED_METHODS = [:ask, :yes?, :no?, :say, :say_status, :print_list, :print_table] | |
- | |
- # Add shell to initialize config values. | |
- # | |
- # ==== Configuration | |
- # shell<Object>:: An instance of the shell to be used. | |
- # | |
- # ==== Examples | |
- # | |
- # class MyScript < Thor | |
- # argument :first, :type => :numeric | |
- # end | |
- # | |
- # MyScript.new [1.0], { :foo => :bar }, :shell => Thor::Shell::Basic.new | |
- # | |
- def initialize(args=[], options={}, config={}) | |
- super | |
- self.shell = config[:shell] | |
- self.shell.base ||= self if self.shell.respond_to?(:base) | |
- end | |
- | |
- # Holds the shell for the given Thor instance. If no shell is given, | |
- # it gets a default shell from Thor::Base.shell. | |
- # | |
- def shell | |
- @shell ||= Thor::Base.shell.new | |
- end | |
- | |
- # Sets the shell for this thor class. | |
- # | |
- def shell=(shell) | |
- @shell = shell | |
- end | |
- | |
- # Common methods that are delegated to the shell. | |
- # | |
- SHELL_DELEGATED_METHODS.each do |method| | |
- module_eval <<-METHOD, __FILE__, __LINE__ | |
- def #{method}(*args) | |
- shell.#{method}(*args) | |
- end | |
- METHOD | |
- end | |
- | |
- protected | |
- | |
- # Allow shell to be shared between invocations. | |
- # | |
- def _shared_configuration #:nodoc: | |
- super.merge!(:shell => self.shell) | |
- end | |
- | |
- end | |
-end | |
diff --git a/railties/lib/rails/vendor/thor-0.11.8/lib/thor/shell/basic.rb b/railties/lib/rails/vendor/thor-0.11.8/lib/thor/shell/basic.rb | |
deleted file mode 100644 | |
index ea96653..0000000 | |
--- a/railties/lib/rails/vendor/thor-0.11.8/lib/thor/shell/basic.rb | |
+++ /dev/null | |
@@ -1,219 +0,0 @@ | |
-require 'tempfile' | |
- | |
-class Thor | |
- module Shell | |
- class Basic | |
- attr_accessor :base, :padding | |
- | |
- # Initialize base and padding to nil. | |
- # | |
- def initialize #:nodoc: | |
- @base, @padding = nil, 0 | |
- end | |
- | |
- # Sets the output padding, not allowing less than zero values. | |
- # | |
- def padding=(value) | |
- @padding = [0, value].max | |
- end | |
- | |
- # Ask something to the user and receives a response. | |
- # | |
- # ==== Example | |
- # ask("What is your name?") | |
- # | |
- def ask(statement, color=nil) | |
- say("#{statement} ", color) | |
- $stdin.gets.strip | |
- end | |
- | |
- # Say (print) something to the user. If the sentence ends with a whitespace | |
- # or tab character, a new line is not appended (print + flush). Otherwise | |
- # are passed straight to puts (behavior got from Highline). | |
- # | |
- # ==== Example | |
- # say("I know you knew that.") | |
- # | |
- def say(message="", color=nil, force_new_line=(message.to_s !~ /( |\t)$/)) | |
- message = message.to_s | |
- message = set_color(message, color) if color | |
- | |
- if force_new_line | |
- $stdout.puts(message) | |
- else | |
- $stdout.print(message) | |
- $stdout.flush | |
- end | |
- end | |
- | |
- # Say a status with the given color and appends the message. Since this | |
- # method is used frequently by actions, it allows nil or false to be given | |
- # in log_status, avoiding the message from being shown. If a Symbol is | |
- # given in log_status, it's used as the color. | |
- # | |
- def say_status(status, message, log_status=true) | |
- return if quiet? || log_status == false | |
- spaces = " " * (padding + 1) | |
- color = log_status.is_a?(Symbol) ? log_status : :green | |
- | |
- status = status.to_s.rjust(12) | |
- status = set_color status, color, true if color | |
- say "#{status}#{spaces}#{message}", nil, true | |
- end | |
- | |
- # Make a question the to user and returns true if the user replies "y" or | |
- # "yes". | |
- # | |
- def yes?(statement, color=nil) | |
- ask(statement, color) =~ is?(:yes) | |
- end | |
- | |
- # Make a question the to user and returns true if the user replies "n" or | |
- # "no". | |
- # | |
- def no?(statement, color=nil) | |
- !yes?(statement, color) | |
- end | |
- | |
- # Prints a list of items. | |
- # | |
- # ==== Parameters | |
- # list<Array[String, String, ...]> | |
- # | |
- # ==== Options | |
- # mode:: Can be :rows or :inline. Defaults to :rows. | |
- # ident:: Ident each item with the value given. | |
- # | |
- def print_list(list, options={}) | |
- return if list.empty? | |
- | |
- ident = " " * (options[:ident] || 0) | |
- content = case options[:mode] | |
- when :inline | |
- last = list.pop | |
- "#{list.join(", ")}, and #{last}" | |
- else # rows | |
- ident + list.join("\n#{ident}") | |
- end | |
- | |
- $stdout.puts content | |
- end | |
- | |
- # Prints a table. | |
- # | |
- # ==== Parameters | |
- # Array[Array[String, String, ...]] | |
- # | |
- # ==== Options | |
- # ident<Integer>:: Ident the first column by ident value. | |
- # | |
- def print_table(table, options={}) | |
- return if table.empty? | |
- | |
- formats = [] | |
- 0.upto(table.first.length - 2) do |i| | |
- maxima = table.max{ |a,b| a[i].size <=> b[i].size }[i].size | |
- formats << "%-#{maxima + 2}s" | |
- end | |
- | |
- formats[0] = formats[0].insert(0, " " * options[:ident]) if options[:ident] | |
- formats << "%s" | |
- | |
- table.each do |row| | |
- row.each_with_index do |column, i| | |
- $stdout.print formats[i] % column.to_s | |
- end | |
- $stdout.puts | |
- end | |
- end | |
- | |
- # Deals with file collision and returns true if the file should be | |
- # overwriten and false otherwise. If a block is given, it uses the block | |
- # response as the content for the diff. | |
- # | |
- # ==== Parameters | |
- # destination<String>:: the destination file to solve conflicts | |
- # block<Proc>:: an optional block that returns the value to be used in diff | |
- # | |
- def file_collision(destination) | |
- return true if @always_force | |
- options = block_given? ? "[Ynaqdh]" : "[Ynaqh]" | |
- | |
- while true | |
- answer = ask %[Overwrite #{destination}? (enter "h" for help) #{options}] | |
- | |
- case answer | |
- when is?(:yes), is?(:force) | |
- return true | |
- when is?(:no), is?(:skip) | |
- return false | |
- when is?(:always) | |
- return @always_force = true | |
- when is?(:quit) | |
- say 'Aborting...' | |
- raise SystemExit | |
- when is?(:diff) | |
- show_diff(destination, yield) if block_given? | |
- say 'Retrying...' | |
- else | |
- say file_collision_help | |
- end | |
- end | |
- end | |
- | |
- # Called if something goes wrong during the execution. This is used by Thor | |
- # internally and should not be used inside your scripts. If someone went | |
- # wrong, you can always raise an exception. If you raise a Thor::Error, it | |
- # will be rescued and wrapped in the method below. | |
- # | |
- def error(statement) | |
- $stderr.puts statement | |
- end | |
- | |
- # Apply color to the given string with optional bold. Disabled in the | |
- # Thor::Shell::Basic class. | |
- # | |
- def set_color(string, color, bold=false) #:nodoc: | |
- string | |
- end | |
- | |
- protected | |
- | |
- def is?(value) #:nodoc: | |
- value = value.to_s | |
- | |
- if value.size == 1 | |
- /\A#{value}\z/i | |
- else | |
- /\A(#{value}|#{value[0,1]})\z/i | |
- end | |
- end | |
- | |
- def file_collision_help #:nodoc: | |
-<<HELP | |
-Y - yes, overwrite | |
-n - no, do not overwrite | |
-a - all, overwrite this and all others | |
-q - quit, abort | |
-d - diff, show the differences between the old and the new | |
-h - help, show this help | |
-HELP | |
- end | |
- | |
- def show_diff(destination, content) #:nodoc: | |
- diff_cmd = ENV['THOR_DIFF'] || ENV['RAILS_DIFF'] || 'diff -u' | |
- | |
- Tempfile.open(File.basename(destination), File.dirname(destination)) do |temp| | |
- temp.write content | |
- temp.rewind | |
- system %(#{diff_cmd} "#{destination}" "#{temp.path}") | |
- end | |
- end | |
- | |
- def quiet? #:nodoc: | |
- base && base.options[:quiet] | |
- end | |
- | |
- end | |
- end | |
-end | |
diff --git a/railties/lib/rails/vendor/thor-0.11.8/lib/thor/shell/color.rb b/railties/lib/rails/vendor/thor-0.11.8/lib/thor/shell/color.rb | |
deleted file mode 100644 | |
index 24704f7..0000000 | |
--- a/railties/lib/rails/vendor/thor-0.11.8/lib/thor/shell/color.rb | |
+++ /dev/null | |
@@ -1,108 +0,0 @@ | |
-require 'thor/shell/basic' | |
- | |
-class Thor | |
- module Shell | |
- # Inherit from Thor::Shell::Basic and add set_color behavior. Check | |
- # Thor::Shell::Basic to see all available methods. | |
- # | |
- class Color < Basic | |
- # Embed in a String to clear all previous ANSI sequences. | |
- CLEAR = "\e[0m" | |
- # The start of an ANSI bold sequence. | |
- BOLD = "\e[1m" | |
- | |
- # Set the terminal's foreground ANSI color to black. | |
- BLACK = "\e[30m" | |
- # Set the terminal's foreground ANSI color to red. | |
- RED = "\e[31m" | |
- # Set the terminal's foreground ANSI color to green. | |
- GREEN = "\e[32m" | |
- # Set the terminal's foreground ANSI color to yellow. | |
- YELLOW = "\e[33m" | |
- # Set the terminal's foreground ANSI color to blue. | |
- BLUE = "\e[34m" | |
- # Set the terminal's foreground ANSI color to magenta. | |
- MAGENTA = "\e[35m" | |
- # Set the terminal's foreground ANSI color to cyan. | |
- CYAN = "\e[36m" | |
- # Set the terminal's foreground ANSI color to white. | |
- WHITE = "\e[37m" | |
- | |
- # Set the terminal's background ANSI color to black. | |
- ON_BLACK = "\e[40m" | |
- # Set the terminal's background ANSI color to red. | |
- ON_RED = "\e[41m" | |
- # Set the terminal's background ANSI color to green. | |
- ON_GREEN = "\e[42m" | |
- # Set the terminal's background ANSI color to yellow. | |
- ON_YELLOW = "\e[43m" | |
- # Set the terminal's background ANSI color to blue. | |
- ON_BLUE = "\e[44m" | |
- # Set the terminal's background ANSI color to magenta. | |
- ON_MAGENTA = "\e[45m" | |
- # Set the terminal's background ANSI color to cyan. | |
- ON_CYAN = "\e[46m" | |
- # Set the terminal's background ANSI color to white. | |
- ON_WHITE = "\e[47m" | |
- | |
- # Set color by using a string or one of the defined constants. If a third | |
- # option is set to true, it also adds bold to the string. This is based | |
- # on Highline implementation and it automatically appends CLEAR to the end | |
- # of the returned String. | |
- # | |
- def set_color(string, color, bold=false) | |
- color = self.class.const_get(color.to_s.upcase) if color.is_a?(Symbol) | |
- bold = bold ? BOLD : "" | |
- "#{bold}#{color}#{string}#{CLEAR}" | |
- end | |
- | |
- protected | |
- | |
- # Overwrite show_diff to show diff with colors if Diff::LCS is | |
- # available. | |
- # | |
- def show_diff(destination, content) #:nodoc: | |
- if diff_lcs_loaded? && ENV['THOR_DIFF'].nil? && ENV['RAILS_DIFF'].nil? | |
- actual = File.read(destination).to_s.split("\n") | |
- content = content.to_s.split("\n") | |
- | |
- Diff::LCS.sdiff(actual, content).each do |diff| | |
- output_diff_line(diff) | |
- end | |
- else | |
- super | |
- end | |
- end | |
- | |
- def output_diff_line(diff) #:nodoc: | |
- case diff.action | |
- when '-' | |
- say "- #{diff.old_element.chomp}", :red, true | |
- when '+' | |
- say "+ #{diff.new_element.chomp}", :green, true | |
- when '!' | |
- say "- #{diff.old_element.chomp}", :red, true | |
- say "+ #{diff.new_element.chomp}", :green, true | |
- else | |
- say " #{diff.old_element.chomp}", nil, true | |
- end | |
- end | |
- | |
- # Check if Diff::LCS is loaded. If it is, use it to create pretty output | |
- # for diff. | |
- # | |
- def diff_lcs_loaded? #:nodoc: | |
- return true if defined?(Diff::LCS) | |
- return @diff_lcs_loaded unless @diff_lcs_loaded.nil? | |
- | |
- @diff_lcs_loaded = begin | |
- require 'diff/lcs' | |
- true | |
- rescue LoadError | |
- false | |
- end | |
- end | |
- | |
- end | |
- end | |
-end | |
diff --git a/railties/lib/rails/vendor/thor-0.11.8/lib/thor/task.rb b/railties/lib/rails/vendor/thor-0.11.8/lib/thor/task.rb | |
deleted file mode 100644 | |
index 91c7564..0000000 | |
--- a/railties/lib/rails/vendor/thor-0.11.8/lib/thor/task.rb | |
+++ /dev/null | |
@@ -1,122 +0,0 @@ | |
-class Thor | |
- class Task < Struct.new(:name, :description, :usage, :options) | |
- | |
- # A dynamic task that handles method missing scenarios. | |
- # | |
- class Dynamic < Task | |
- def initialize(name) | |
- super(name.to_s, "A dynamically-generated task", name.to_s) | |
- end | |
- | |
- def run(instance, args=[]) | |
- unless (instance.methods & [name.to_s, name.to_sym]).empty? | |
- raise Error, "could not find Thor class or task '#{name}'" | |
- end | |
- super | |
- end | |
- end | |
- | |
- def initialize(name, description, usage, options=nil) | |
- super(name.to_s, description, usage, options || {}) | |
- end | |
- | |
- def initialize_copy(other) #:nodoc: | |
- super(other) | |
- self.options = other.options.dup if other.options | |
- end | |
- | |
- def short_description | |
- description.split("\n").first if description | |
- end | |
- | |
- # By default, a task invokes a method in the thor class. You can change this | |
- # implementation to create custom tasks. | |
- # | |
- def run(instance, args=[]) | |
- raise UndefinedTaskError, "the '#{name}' task of #{instance.class} is private" unless public_method?(instance) | |
- instance.send(name, *args) | |
- rescue ArgumentError => e | |
- parse_argument_error(instance, e, caller) | |
- rescue NoMethodError => e | |
- parse_no_method_error(instance, e) | |
- end | |
- | |
- # Returns the formatted usage. If a class is given, the class arguments are | |
- # injected in the usage. | |
- # | |
- def formatted_usage(klass=nil, namespace=false, show_options=true) | |
- formatted = if namespace.is_a?(String) | |
- "#{namespace}:" | |
- elsif klass && namespace | |
- "#{klass.namespace.gsub(/^default/,'')}:" | |
- else | |
- "" | |
- end | |
- | |
- formatted << formatted_arguments(klass) | |
- formatted << " #{formatted_options}" if show_options | |
- formatted.strip! | |
- formatted | |
- end | |
- | |
- # Injects the class arguments into the task usage. | |
- # | |
- def formatted_arguments(klass) | |
- if klass && !klass.arguments.empty? | |
- usage.to_s.gsub(/^#{name}/) do |match| | |
- match << " " << klass.arguments.map{ |a| a.usage }.join(' ') | |
- end | |
- else | |
- usage.to_s | |
- end | |
- end | |
- | |
- # Returns the options usage for this task. | |
- # | |
- def formatted_options | |
- @formatted_options ||= options.map{ |_, o| o.usage }.sort.join(" ") | |
- end | |
- | |
- protected | |
- | |
- # Given a target, checks if this class name is not a private/protected method. | |
- # | |
- def public_method?(instance) #:nodoc: | |
- collection = instance.private_methods + instance.protected_methods | |
- (collection & [name.to_s, name.to_sym]).empty? | |
- end | |
- | |
- # Clean everything that comes from the Thor gempath and remove the caller. | |
- # | |
- def sans_backtrace(backtrace, caller) #:nodoc: | |
- dirname = /^#{Regexp.escape(File.dirname(__FILE__))}/ | |
- saned = backtrace.reject { |frame| frame =~ dirname } | |
- saned -= caller | |
- end | |
- | |
- def parse_argument_error(instance, e, caller) #:nodoc: | |
- backtrace = sans_backtrace(e.backtrace, caller) | |
- | |
- if backtrace.empty? && e.message =~ /wrong number of arguments/ | |
- if instance.is_a?(Thor::Group) | |
- raise e, "'#{name}' was called incorrectly. Are you sure it has arity equals to 0?" | |
- else | |
- raise InvocationError, "'#{name}' was called incorrectly. Call as " << | |
- "'#{formatted_usage(instance.class, true)}'" | |
- end | |
- else | |
- raise e | |
- end | |
- end | |
- | |
- def parse_no_method_error(instance, e) #:nodoc: | |
- if e.message =~ /^undefined method `#{name}' for #{Regexp.escape(instance.to_s)}$/ | |
- raise UndefinedTaskError, "The #{instance.class.namespace} namespace " << | |
- "doesn't have a '#{name}' task" | |
- else | |
- raise e | |
- end | |
- end | |
- | |
- end | |
-end | |
diff --git a/railties/lib/rails/vendor/thor-0.11.8/lib/thor/util.rb b/railties/lib/rails/vendor/thor-0.11.8/lib/thor/util.rb | |
deleted file mode 100644 | |
index ebae0a3..0000000 | |
--- a/railties/lib/rails/vendor/thor-0.11.8/lib/thor/util.rb | |
+++ /dev/null | |
@@ -1,251 +0,0 @@ | |
-require 'rbconfig' | |
- | |
-class Thor | |
- module Sandbox #:nodoc: | |
- end | |
- | |
- # This module holds several utilities: | |
- # | |
- # 1) Methods to convert thor namespaces to constants and vice-versa. | |
- # | |
- # Thor::Utils.namespace_from_thor_class(Foo::Bar::Baz) #=> "foo:bar:baz" | |
- # | |
- # 2) Loading thor files and sandboxing: | |
- # | |
- # Thor::Utils.load_thorfile("~/.thor/foo") | |
- # | |
- module Util | |
- | |
- # Receives a namespace and search for it in the Thor::Base subclasses. | |
- # | |
- # ==== Parameters | |
- # namespace<String>:: The namespace to search for. | |
- # | |
- def self.find_by_namespace(namespace) | |
- namespace = "default#{namespace}" if namespace.empty? || namespace =~ /^:/ | |
- | |
- Thor::Base.subclasses.find do |klass| | |
- klass.namespace == namespace | |
- end | |
- end | |
- | |
- # Receives a constant and converts it to a Thor namespace. Since Thor tasks | |
- # can be added to a sandbox, this method is also responsable for removing | |
- # the sandbox namespace. | |
- # | |
- # This method should not be used in general because it's used to deal with | |
- # older versions of Thor. On current versions, if you need to get the | |
- # namespace from a class, just call namespace on it. | |
- # | |
- # ==== Parameters | |
- # constant<Object>:: The constant to be converted to the thor path. | |
- # | |
- # ==== Returns | |
- # String:: If we receive Foo::Bar::Baz it returns "foo:bar:baz" | |
- # | |
- def self.namespace_from_thor_class(constant, remove_default=true) | |
- constant = constant.to_s.gsub(/^Thor::Sandbox::/, "") | |
- constant = snake_case(constant).squeeze(":") | |
- constant.gsub!(/^default/, '') if remove_default | |
- constant | |
- end | |
- | |
- # Given the contents, evaluate it inside the sandbox and returns the | |
- # namespaces defined in the sandbox. | |
- # | |
- # ==== Parameters | |
- # contents<String> | |
- # | |
- # ==== Returns | |
- # Array[Object] | |
- # | |
- def self.namespaces_in_content(contents, file=__FILE__) | |
- old_constants = Thor::Base.subclasses.dup | |
- Thor::Base.subclasses.clear | |
- | |
- load_thorfile(file, contents) | |
- | |
- new_constants = Thor::Base.subclasses.dup | |
- Thor::Base.subclasses.replace(old_constants) | |
- | |
- new_constants.map!{ |c| c.namespace } | |
- new_constants.compact! | |
- new_constants | |
- end | |
- | |
- # Returns the thor classes declared inside the given class. | |
- # | |
- def self.thor_classes_in(klass) | |
- Thor::Base.subclasses.select do |subclass| | |
- klass.constants.include?(subclass.name.gsub("#{klass.name}::", '')) | |
- end | |
- end | |
- | |
- # Receives a string and convert it to snake case. SnakeCase returns snake_case. | |
- # | |
- # ==== Parameters | |
- # String | |
- # | |
- # ==== Returns | |
- # String | |
- # | |
- def self.snake_case(str) | |
- return str.downcase if str =~ /^[A-Z_]+$/ | |
- str.gsub(/\B[A-Z]/, '_\&').squeeze('_') =~ /_*(.*)/ | |
- return $+.downcase | |
- end | |
- | |
- # Receives a string and convert it to camel case. camel_case returns CamelCase. | |
- # | |
- # ==== Parameters | |
- # String | |
- # | |
- # ==== Returns | |
- # String | |
- # | |
- def self.camel_case(str) | |
- return str if str !~ /_/ && str =~ /[A-Z]+.*/ | |
- str.split('_').map { |i| i.capitalize }.join | |
- end | |
- | |
- # Receives a namespace and tries to retrieve a Thor or Thor::Group class | |
- # from it. It first searches for a class using the all the given namespace, | |
- # if it's not found, removes the highest entry and searches for the class | |
- # again. If found, returns the highest entry as the class name. | |
- # | |
- # ==== Examples | |
- # | |
- # class Foo::Bar < Thor | |
- # def baz | |
- # end | |
- # end | |
- # | |
- # class Baz::Foo < Thor::Group | |
- # end | |
- # | |
- # Thor::Util.namespace_to_thor_class("foo:bar") #=> Foo::Bar, nil # will invoke default task | |
- # Thor::Util.namespace_to_thor_class("baz:foo") #=> Baz::Foo, nil | |
- # Thor::Util.namespace_to_thor_class("foo:bar:baz") #=> Foo::Bar, "baz" | |
- # | |
- # ==== Parameters | |
- # namespace<String> | |
- # | |
- # ==== Errors | |
- # Thor::Error:: raised if the namespace cannot be found. | |
- # | |
- # Thor::Error:: raised if the namespace evals to a class which does not | |
- # inherit from Thor or Thor::Group. | |
- # | |
- def self.namespace_to_thor_class_and_task(namespace, raise_if_nil=true) | |
- if namespace.include?(?:) | |
- pieces = namespace.split(":") | |
- task = pieces.pop | |
- klass = Thor::Util.find_by_namespace(pieces.join(":")) | |
- end | |
- | |
- unless klass | |
- klass, task = Thor::Util.find_by_namespace(namespace), nil | |
- end | |
- | |
- raise Error, "could not find Thor class or task '#{namespace}'" if raise_if_nil && klass.nil? | |
- return klass, task | |
- end | |
- | |
- # Receives a path and load the thor file in the path. The file is evaluated | |
- # inside the sandbox to avoid namespacing conflicts. | |
- # | |
- def self.load_thorfile(path, content=nil) | |
- content ||= File.read(path) | |
- | |
- begin | |
- Thor::Sandbox.class_eval(content, path) | |
- rescue Exception => e | |
- $stderr.puts "WARNING: unable to load thorfile #{path.inspect}: #{e.message}" | |
- end | |
- end | |
- | |
- # Receives a yaml (hash) and updates all constants entries to namespace. | |
- # This was added to deal with deprecated versions of Thor. | |
- # | |
- # TODO Deprecate this method in the future. | |
- # | |
- # ==== Returns | |
- # TrueClass|FalseClass:: Returns true if any change to the yaml file was made. | |
- # | |
- def self.convert_constants_to_namespaces(yaml) | |
- yaml_changed = false | |
- | |
- yaml.each do |k, v| | |
- next unless v[:constants] && v[:namespaces].nil? | |
- yaml_changed = true | |
- yaml[k][:namespaces] = v[:constants].map{|c| Thor::Util.namespace_from_thor_class(c)} | |
- end | |
- | |
- yaml_changed | |
- end | |
- | |
- def self.user_home | |
- @@user_home ||= if ENV["HOME"] | |
- ENV["HOME"] | |
- elsif ENV["USERPROFILE"] | |
- ENV["USERPROFILE"] | |
- elsif ENV["HOMEDRIVE"] && ENV["HOMEPATH"] | |
- File.join(ENV["HOMEDRIVE"], ENV["HOMEPATH"]) | |
- elsif ENV["APPDATA"] | |
- ENV["APPDATA"] | |
- else | |
- begin | |
- File.expand_path("~") | |
- rescue | |
- if File::ALT_SEPARATOR | |
- "C:/" | |
- else | |
- "/" | |
- end | |
- end | |
- end | |
- end | |
- | |
- # Returns the root where thor files are located, dependending on the OS. | |
- # | |
- def self.thor_root | |
- File.join(user_home, ".thor").gsub(/\\/, '/') | |
- end | |
- | |
- # Returns the files in the thor root. On Windows thor_root will be something | |
- # like this: | |
- # | |
- # C:\Documents and Settings\james\.thor | |
- # | |
- # If we don't #gsub the \ character, Dir.glob will fail. | |
- # | |
- def self.thor_root_glob | |
- files = Dir["#{thor_root}/*"] | |
- | |
- files.map! do |file| | |
- File.directory?(file) ? File.join(file, "main.thor") : file | |
- end | |
- end | |
- | |
- # Where to look for Thor files. | |
- # | |
- def self.globs_for(path) | |
- ["#{path}/Thorfile", "#{path}/*.thor", "#{path}/tasks/*.thor", "#{path}/lib/tasks/*.thor"] | |
- end | |
- | |
- # Return the path to the ruby interpreter taking into account multiple | |
- # installations and windows extensions. | |
- # | |
- def self.ruby_command | |
- @ruby_command ||= begin | |
- ruby = File.join(Config::CONFIG['bindir'], Config::CONFIG['ruby_install_name']) | |
- ruby << Config::CONFIG['EXEEXT'] | |
- | |
- # escape string in case path to ruby executable contain spaces. | |
- ruby.sub!(/.*\s.*/m, '"\&"') | |
- ruby | |
- end | |
- end | |
- | |
- end | |
-end | |
diff --git a/railties/lib/rails/vendor/thor-0.11.8/lib/thor/version.rb b/railties/lib/rails/vendor/thor-0.11.8/lib/thor/version.rb | |
deleted file mode 100644 | |
index 885230f..0000000 | |
--- a/railties/lib/rails/vendor/thor-0.11.8/lib/thor/version.rb | |
+++ /dev/null | |
@@ -1,3 +0,0 @@ | |
-class Thor | |
- VERSION = "0.11.8".freeze | |
-end | |
diff --git a/railties/lib/rails/vendor/thor-0.12.0/CHANGELOG.rdoc b/railties/lib/rails/vendor/thor-0.12.0/CHANGELOG.rdoc | |
new file mode 100644 | |
index 0000000..adedfec | |
--- /dev/null | |
+++ b/railties/lib/rails/vendor/thor-0.12.0/CHANGELOG.rdoc | |
@@ -0,0 +1,82 @@ | |
+== TODO | |
+ | |
+* Improve spec coverage for Thor::Runner | |
+ | |
+== 0.12, released 2009-11-06 | |
+ | |
+* [#7] Do not force white color on status | |
+* [#8] Yield a block with the filename on directory | |
+ | |
+== 0.11, released 2009-07-01 | |
+ | |
+* Added a rake compatibility layer. It allows you to use spec and rdoc tasks on | |
+ Thor classes. | |
+ | |
+* BACKWARDS INCOMPATIBLE: aliases are not generated automatically anymore | |
+ since it wrong behavior to the invocation system. | |
+ | |
+* thor help now show information about any class/task. All those calls are | |
+ possible: | |
+ | |
+ thor help describe | |
+ thor help describe:amazing | |
+ | |
+ Or even with default namespaces: | |
+ | |
+ thor help :spec | |
+ | |
+* Thor::Runner now invokes the default task if none is supplied: | |
+ | |
+ thor describe # invokes the default task, usually help | |
+ | |
+* Thor::Runner now works with mappings: | |
+ | |
+ thor describe -h | |
+ | |
+* Added some documentation and code refactoring. | |
+ | |
+== 0.9.8, released 2008-10-20 | |
+ | |
+* Fixed some tiny issues that were introduced lately. | |
+ | |
+== 0.9.7, released 2008-10-13 | |
+ | |
+* Setting global method options on the initialize method works as expected: | |
+ All other tasks will accept these global options in addition to their own. | |
+* Added 'group' notion to Thor task sets (class Thor); by default all tasks | |
+ are in the 'standard' group. Running 'thor -T' will only show the standard | |
+ tasks - adding --all will show all tasks. You can also filter on a specific | |
+ group using the --group option: thor -T --group advanced | |
+ | |
+== 0.9.6, released 2008-09-13 | |
+ | |
+* Generic improvements | |
+ | |
+== 0.9.5, released 2008-08-27 | |
+ | |
+* Improve Windows compatibility | |
+* Update (incorrect) README and task.thor sample file | |
+* Options hash is now frozen (once returned) | |
+* Allow magic predicates on options object. For instance: `options.force?` | |
+* Add support for :numeric type | |
+* BACKWARDS INCOMPATIBLE: Refactor Thor::Options. You cannot access shorthand forms in options hash anymore (for instance, options[:f]) | |
+* Allow specifying optional args with default values: method_options(:user => "mislav") | |
+* Don't write options for nil or false values. This allows, for example, turning color off when running specs. | |
+* Exit with the status of the spec command to help CI stuff out some. | |
+ | |
+== 0.9.4, released 2008-08-13 | |
+ | |
+* Try to add Windows compatibility. | |
+* BACKWARDS INCOMPATIBLE: options hash is now accessed as a property in your class and is not passed as last argument anymore | |
+* Allow options at the beginning of the argument list as well as the end. | |
+* Make options available with symbol keys in addition to string keys. | |
+* Allow true to be passed to Thor#method_options to denote a boolean option. | |
+* If loading a thor file fails, don't give up, just print a warning and keep going. | |
+* Make sure that we re-raise errors if they happened further down the pipe than we care about. | |
+* Only delete the old file on updating when the installation of the new one is a success | |
+* Make it Ruby 1.8.5 compatible. | |
+* Don't raise an error if a boolean switch is defined multiple times. | |
+* Thor::Options now doesn't parse through things that look like options but aren't. | |
+* Add URI detection to install task, and make sure we don't append ".thor" to URIs | |
+* Add rake2thor to the gem binfiles. | |
+* Make sure local Thorfiles override system-wide ones. | |
diff --git a/railties/lib/rails/vendor/thor-0.12.0/LICENSE b/railties/lib/rails/vendor/thor-0.12.0/LICENSE | |
new file mode 100644 | |
index 0000000..98722da | |
--- /dev/null | |
+++ b/railties/lib/rails/vendor/thor-0.12.0/LICENSE | |
@@ -0,0 +1,20 @@ | |
+Copyright (c) 2008 Yehuda Katz | |
+ | |
+Permission is hereby granted, free of charge, to any person obtaining | |
+a copy of this software and associated documentation files (the | |
+"Software"), to deal in the Software without restriction, including | |
+without limitation the rights to use, copy, modify, merge, publish, | |
+distribute, sublicense, and/or sell copies of the Software, and to | |
+permit persons to whom the Software is furnished to do so, subject to | |
+the following conditions: | |
+ | |
+The above copyright notice and this permission notice shall be | |
+included in all copies or substantial portions of the Software. | |
+ | |
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | |
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | |
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | |
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE | |
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION | |
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | |
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |
\ No newline at end of file | |
diff --git a/railties/lib/rails/vendor/thor-0.12.0/README.rdoc b/railties/lib/rails/vendor/thor-0.12.0/README.rdoc | |
new file mode 100644 | |
index 0000000..f1106f0 | |
--- /dev/null | |
+++ b/railties/lib/rails/vendor/thor-0.12.0/README.rdoc | |
@@ -0,0 +1,234 @@ | |
+= thor | |
+ | |
+Map options to a class. Simply create a class with the appropriate annotations | |
+and have options automatically map to functions and parameters. | |
+ | |
+Example: | |
+ | |
+ class App < Thor # [1] | |
+ map "-L" => :list # [2] | |
+ | |
+ desc "install APP_NAME", "install one of the available apps" # [3] | |
+ method_options :force => :boolean, :alias => :string # [4] | |
+ def install(name) | |
+ user_alias = options[:alias] | |
+ if options.force? | |
+ # do something | |
+ end | |
+ # other code | |
+ end | |
+ | |
+ desc "list [SEARCH]", "list all of the available apps, limited by SEARCH" | |
+ def list(search="") | |
+ # list everything | |
+ end | |
+ end | |
+ | |
+Thor automatically maps commands as such: | |
+ | |
+ thor app:install myname --force | |
+ | |
+That gets converted to: | |
+ | |
+ App.new.install("myname") | |
+ # with {'force' => true} as options hash | |
+ | |
+1. Inherit from Thor to turn a class into an option mapper | |
+2. Map additional non-valid identifiers to specific methods. In this case, convert -L to :list | |
+3. Describe the method immediately below. The first parameter is the usage information, and the second parameter is the description | |
+4. Provide any additional options that will be available the instance method options. | |
+ | |
+== Types for <tt>method_options</tt> | |
+ | |
+* :boolean - is parsed as <tt>--option</tt> or <tt>--option=true</tt> | |
+* :string - is parsed as <tt>--option=VALUE</tt> | |
+* :numeric - is parsed as <tt>--option=N</tt> | |
+* :array - is parsed as <tt>--option=one two three</tt> | |
+* :hash - is parsed as <tt>--option=name:string age:integer</tt> | |
+ | |
+Besides, method_option allows a default value to be given, examples: | |
+ | |
+ method_options :force => false | |
+ #=> Creates a boolean option with default value false | |
+ | |
+ method_options :alias => "bar" | |
+ #=> Creates a string option with default value "bar" | |
+ | |
+ method_options :threshold => 3.0 | |
+ #=> Creates a numeric option with default value 3.0 | |
+ | |
+You can also supply <tt>:option => :required</tt> to mark an option as required. The | |
+type is assumed to be string. If you want a required hash with default values | |
+as option, you can use <tt>method_option</tt> which uses a more declarative style: | |
+ | |
+ method_option :attributes, :type => :hash, :default => {}, :required => true | |
+ | |
+All arguments can be set to nil (except required arguments), by suppling a no or | |
+skip variant. For example: | |
+ | |
+ thor app name --no-attributes | |
+ | |
+In previous versions, aliases for options were created automatically, but now | |
+they should be explicit. You can supply aliases in both short and declarative | |
+styles: | |
+ | |
+ method_options %w( force -f ) => :boolean | |
+ | |
+Or: | |
+ | |
+ method_option :force, :type => :boolean, :aliases => "-f" | |
+ | |
+You can supply as many aliases as you want. | |
+ | |
+NOTE: Type :optional available in Thor 0.9.0 was deprecated. Use :string or :boolean instead. | |
+ | |
+== Namespaces | |
+ | |
+By default, your Thor tasks are invoked using Ruby namespace. In the example | |
+above, tasks are invoked as: | |
+ | |
+ thor app:install name --force | |
+ | |
+However, you could namespace your class as: | |
+ | |
+ module Sinatra | |
+ class App < Thor | |
+ # tasks | |
+ end | |
+ end | |
+ | |
+And then you should invoke your tasks as: | |
+ | |
+ thor sinatra:app:install name --force | |
+ | |
+If desired, you can change the namespace: | |
+ | |
+ module Sinatra | |
+ class App < Thor | |
+ namespace :myapp | |
+ # tasks | |
+ end | |
+ end | |
+ | |
+And then your tasks hould be invoked as: | |
+ | |
+ thor myapp:install name --force | |
+ | |
+== Invocations | |
+ | |
+Thor comes with a invocation-dependency system as well which allows a task to be | |
+invoked only once. For example: | |
+ | |
+ class Counter < Thor | |
+ desc "one", "Prints 1, 2, 3" | |
+ def one | |
+ puts 1 | |
+ invoke :two | |
+ invoke :three | |
+ end | |
+ | |
+ desc "two", "Prints 2, 3" | |
+ def two | |
+ puts 2 | |
+ invoke :three | |
+ end | |
+ | |
+ desc "three", "Prints 3" | |
+ def three | |
+ puts 3 | |
+ end | |
+ end | |
+ | |
+When invoking the task one: | |
+ | |
+ thor counter:one | |
+ | |
+The output is "1 2 3", which means that the three task was invoked only once. | |
+You can even invoke tasks from another class, so be sure to check the | |
+documentation. | |
+ | |
+== Thor::Group | |
+ | |
+Thor has a special class called Thor::Group. The main difference to Thor class | |
+is that it invokes all tasks at once. The example above could be rewritten in | |
+Thor::Group as this: | |
+ | |
+ class Counter < Thor::Group | |
+ desc "Prints 1, 2, 3" | |
+ | |
+ def one | |
+ puts 1 | |
+ end | |
+ | |
+ def two | |
+ puts 2 | |
+ end | |
+ | |
+ def three | |
+ puts 3 | |
+ end | |
+ end | |
+ | |
+When invoked: | |
+ | |
+ thor counter | |
+ | |
+It prints "1 2 3" as well. Notice you should describe (using the method <tt>desc</tt>) | |
+only the class and not each task anymore. Thor::Group is a great tool to create | |
+generators, since you can define several steps which are invoked in the order they | |
+are defined (Thor::Group is the tool use in generators in Rails 3.0). | |
+ | |
+Besides, Thor::Group can parse arguments and options as Thor tasks: | |
+ | |
+ class Counter < Thor::Group | |
+ # number will be available as attr_accessor | |
+ argument :number, :type => :numeric, :desc => "The number to start counting" | |
+ desc "Prints the 'number' given upto 'number+2'" | |
+ | |
+ def one | |
+ puts number + 0 | |
+ end | |
+ | |
+ def two | |
+ puts number + 1 | |
+ end | |
+ | |
+ def three | |
+ puts number + 2 | |
+ end | |
+ end | |
+ | |
+The counter above expects one parameter and has the folling outputs: | |
+ | |
+ thor counter 5 | |
+ # Prints "5 6 7" | |
+ | |
+ thor counter 11 | |
+ # Prints "11 12 13" | |
+ | |
+You can also give options to Thor::Group, but instead of using <tt>method_option</tt> | |
+and <tt>method_options</tt>, you should use <tt>class_option</tt> and <tt>class_options</tt>. | |
+Both argument and class_options methods are available to Thor class as well. | |
+ | |
+== Actions | |
+ | |
+Thor comes with several actions which helps with script and generator tasks. You | |
+might be familiar with them since some came from Rails Templates. They are: | |
+<tt>say</tt>, <tt>ask</tt>, <tt>yes?</tt>, <tt>no?</tt>, <tt>add_file</tt>, | |
+<tt>remove_file</tt>, <tt>copy_file</tt>, <tt>template</tt>, <tt>directory</tt>, | |
+<tt>inside</tt>, <tt>run</tt>, <tt>inject_into_file</tt> and a couple more. | |
+ | |
+To use them, you just need to include Thor::Actions in your Thor classes: | |
+ | |
+ class App < Thor | |
+ include Thor::Actions | |
+ # tasks | |
+ end | |
+ | |
+Some actions like copy file requires that a class method called source_root is | |
+defined in your class. This is the directory where your templates should be | |
+placed. Be sure to check the documentation. | |
+ | |
+== License | |
+ | |
+See MIT LICENSE. | |
diff --git a/railties/lib/rails/vendor/thor-0.12.0/Thorfile b/railties/lib/rails/vendor/thor-0.12.0/Thorfile | |
new file mode 100644 | |
index 0000000..f71a1e5 | |
--- /dev/null | |
+++ b/railties/lib/rails/vendor/thor-0.12.0/Thorfile | |
@@ -0,0 +1,63 @@ | |
+# enconding: utf-8 | |
+ | |
+require File.join(File.dirname(__FILE__), "lib", "thor", "version") | |
+require 'thor/rake_compat' | |
+require 'spec/rake/spectask' | |
+require 'rdoc/task' | |
+ | |
+GEM_NAME = 'thor' | |
+EXTRA_RDOC_FILES = ["README.rdoc", "LICENSE", "CHANGELOG.rdoc", "VERSION", "Thorfile"] | |
+ | |
+class Default < Thor | |
+ include Thor::RakeCompat | |
+ | |
+ Spec::Rake::SpecTask.new(:spec) do |t| | |
+ t.libs << 'lib' | |
+ t.spec_opts = ['--options', "spec/spec.opts"] | |
+ t.spec_files = FileList['spec/**/*_spec.rb'] | |
+ end | |
+ | |
+ Spec::Rake::SpecTask.new(:rcov) do |t| | |
+ t.libs << 'lib' | |
+ t.spec_opts = ['--options', "spec/spec.opts"] | |
+ t.spec_files = FileList['spec/**/*_spec.rb'] | |
+ t.rcov = true | |
+ t.rcov_dir = "rcov" | |
+ end | |
+ | |
+ RDoc::Task.new do |rdoc| | |
+ rdoc.main = "README.rdoc" | |
+ rdoc.rdoc_dir = "rdoc" | |
+ rdoc.title = GEM_NAME | |
+ rdoc.rdoc_files.include(*EXTRA_RDOC_FILES) | |
+ rdoc.rdoc_files.include('lib/**/*.rb') | |
+ rdoc.options << '--line-numbers' << '--inline-source' | |
+ end | |
+ | |
+ begin | |
+ require 'jeweler' | |
+ Jeweler::Tasks.new do |s| | |
+ s.name = GEM_NAME | |
+ s.version = Thor::VERSION | |
+ s.rubyforge_project = "textmate" | |
+ s.platform = Gem::Platform::RUBY | |
+ s.summary = "A scripting framework that replaces rake, sake and rubigen" | |
+ s.email = "ruby-thor@googlegroups.com" | |
+ s.homepage = "http://yehudakatz.com" | |
+ s.description = "A scripting framework that replaces rake, sake and rubigen" | |
+ s.authors = ['Yehuda Katz', 'José Valim'] | |
+ s.has_rdoc = true | |
+ s.extra_rdoc_files = EXTRA_RDOC_FILES | |
+ s.require_path = 'lib' | |
+ s.bindir = "bin" | |
+ s.executables = %w( thor rake2thor ) | |
+ s.files = s.extra_rdoc_files + Dir.glob("{bin,lib}/**/*") | |
+ s.files.exclude 'spec/sandbox/**/*' | |
+ s.test_files.exclude 'spec/sandbox/**/*' | |
+ end | |
+ | |
+ Jeweler::RubyforgeTasks.new | |
+ rescue LoadError | |
+ puts "Jeweler, or one of its dependencies, is not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com" | |
+ end | |
+end | |
diff --git a/railties/lib/rails/vendor/thor-0.12.0/lib/thor.rb b/railties/lib/rails/vendor/thor-0.12.0/lib/thor.rb | |
new file mode 100644 | |
index 0000000..68944f1 | |
--- /dev/null | |
+++ b/railties/lib/rails/vendor/thor-0.12.0/lib/thor.rb | |
@@ -0,0 +1,242 @@ | |
+require 'thor/base' | |
+require 'thor/group' | |
+require 'thor/actions' | |
+ | |
+class Thor | |
+ class << self | |
+ # Sets the default task when thor is executed without an explicit task to be called. | |
+ # | |
+ # ==== Parameters | |
+ # meth<Symbol>:: name of the defaut task | |
+ # | |
+ def default_task(meth=nil) | |
+ case meth | |
+ when :none | |
+ @default_task = 'help' | |
+ when nil | |
+ @default_task ||= from_superclass(:default_task, 'help') | |
+ else | |
+ @default_task = meth.to_s | |
+ end | |
+ end | |
+ | |
+ # Defines the usage and the description of the next task. | |
+ # | |
+ # ==== Parameters | |
+ # usage<String> | |
+ # description<String> | |
+ # | |
+ def desc(usage, description, options={}) | |
+ if options[:for] | |
+ task = find_and_refresh_task(options[:for]) | |
+ task.usage = usage if usage | |
+ task.description = description if description | |
+ else | |
+ @usage, @desc = usage, description | |
+ end | |
+ end | |
+ | |
+ # Maps an input to a task. If you define: | |
+ # | |
+ # map "-T" => "list" | |
+ # | |
+ # Running: | |
+ # | |
+ # thor -T | |
+ # | |
+ # Will invoke the list task. | |
+ # | |
+ # ==== Parameters | |
+ # Hash[String|Array => Symbol]:: Maps the string or the strings in the array to the given task. | |
+ # | |
+ def map(mappings=nil) | |
+ @map ||= from_superclass(:map, {}) | |
+ | |
+ if mappings | |
+ mappings.each do |key, value| | |
+ if key.respond_to?(:each) | |
+ key.each {|subkey| @map[subkey] = value} | |
+ else | |
+ @map[key] = value | |
+ end | |
+ end | |
+ end | |
+ | |
+ @map | |
+ end | |
+ | |
+ # Declares the options for the next task to be declared. | |
+ # | |
+ # ==== Parameters | |
+ # Hash[Symbol => Object]:: The hash key is the name of the option and the value | |
+ # is the type of the option. Can be :string, :array, :hash, :boolean, :numeric | |
+ # or :required (string). If you give a value, the type of the value is used. | |
+ # | |
+ def method_options(options=nil) | |
+ @method_options ||= {} | |
+ build_options(options, @method_options) if options | |
+ @method_options | |
+ end | |
+ | |
+ # Adds an option to the set of class options. If :for is given as option, | |
+ # it allows you to change the options from a previous defined task. | |
+ # | |
+ # def previous_task | |
+ # # magic | |
+ # end | |
+ # | |
+ # method_options :foo => :bar, :for => :previous_task | |
+ # | |
+ # def next_task | |
+ # # magic | |
+ # end | |
+ # | |
+ # ==== Parameters | |
+ # name<Symbol>:: The name of the argument. | |
+ # options<Hash>:: Described below. | |
+ # | |
+ # ==== Options | |
+ # :desc - Description for the argument. | |
+ # :required - If the argument is required or not. | |
+ # :default - Default value for this argument. It cannot be required and have default values. | |
+ # :aliases - Aliases for this option. | |
+ # :type - The type of the argument, can be :string, :hash, :array, :numeric or :boolean. | |
+ # :group - The group for this options. Use by class options to output options in different levels. | |
+ # :banner - String to show on usage notes. | |
+ # | |
+ def method_option(name, options={}) | |
+ scope = if options[:for] | |
+ find_and_refresh_task(options[:for]).options | |
+ else | |
+ method_options | |
+ end | |
+ | |
+ build_option(name, options, scope) | |
+ end | |
+ | |
+ # Parses the task and options from the given args, instantiate the class | |
+ # and invoke the task. This method is used when the arguments must be parsed | |
+ # from an array. If you are inside Ruby and want to use a Thor class, you | |
+ # can simply initialize it: | |
+ # | |
+ # script = MyScript.new(args, options, config) | |
+ # script.invoke(:task, first_arg, second_arg, third_arg) | |
+ # | |
+ def start(given_args=ARGV, config={}) | |
+ super do | |
+ meth = normalize_task_name(given_args.shift) | |
+ task = all_tasks[meth] | |
+ | |
+ if task | |
+ args, opts = Thor::Options.split(given_args) | |
+ config.merge!(:task_options => task.options) | |
+ else | |
+ args, opts = given_args, {} | |
+ end | |
+ | |
+ task ||= Thor::Task::Dynamic.new(meth) | |
+ trailing = args[Range.new(arguments.size, -1)] | |
+ new(args, opts, config).invoke(task, trailing || []) | |
+ end | |
+ end | |
+ | |
+ # Prints help information. If a task name is given, it shows information | |
+ # only about the specific task. | |
+ # | |
+ # ==== Parameters | |
+ # meth<String>:: An optional task name to print usage information about. | |
+ # | |
+ # ==== Options | |
+ # namespace:: When true, shows the namespace in the output before the usage. | |
+ # skip_inherited:: When true, does not show tasks from superclass. | |
+ # | |
+ def help(shell, meth=nil, options={}) | |
+ meth, options = nil, meth if meth.is_a?(Hash) | |
+ | |
+ if meth | |
+ task = all_tasks[meth] | |
+ raise UndefinedTaskError, "task '#{meth}' could not be found in namespace '#{self.namespace}'" unless task | |
+ | |
+ shell.say "Usage:" | |
+ shell.say " #{banner(task, options[:namespace], false)}" | |
+ shell.say | |
+ class_options_help(shell, "Class", :Method => task.options.map { |_, o| o }) | |
+ shell.say task.description | |
+ else | |
+ list = (options[:short] ? tasks : all_tasks).map do |_, task| | |
+ item = [ banner(task, options[:namespace]) ] | |
+ item << "# #{task.short_description}" if task.short_description | |
+ item << " " | |
+ end | |
+ | |
+ options[:ident] ||= 2 | |
+ if options[:short] | |
+ shell.print_list(list, :ident => options[:ident]) | |
+ else | |
+ shell.say "Tasks:" | |
+ shell.print_list(list, :ident => options[:ident]) | |
+ end | |
+ | |
+ Thor::Util.thor_classes_in(self).each do |subclass| | |
+ namespace = options[:namespace] == true || subclass.namespace.gsub(/^#{self.namespace}:/, '') | |
+ subclass.help(shell, options.merge(:short => true, :namespace => namespace)) | |
+ end | |
+ | |
+ class_options_help(shell, "Class") unless options[:short] | |
+ end | |
+ end | |
+ | |
+ protected | |
+ | |
+ # The banner for this class. You can customize it if you are invoking the | |
+ # thor class by another ways which is not the Thor::Runner. It receives | |
+ # the task that is going to be invoked and a boolean which indicates if | |
+ # the namespace should be displayed as arguments. | |
+ # | |
+ def banner(task, namespace=true, show_options=true) | |
+ task.formatted_usage(self, namespace, show_options) | |
+ end | |
+ | |
+ def baseclass #:nodoc: | |
+ Thor | |
+ end | |
+ | |
+ def create_task(meth) #:nodoc: | |
+ if @usage && @desc | |
+ tasks[meth.to_s] = Thor::Task.new(meth, @desc, @usage, method_options) | |
+ @usage, @desc, @method_options = nil | |
+ true | |
+ elsif self.all_tasks[meth.to_s] || meth.to_sym == :method_missing | |
+ true | |
+ else | |
+ puts "[WARNING] Attempted to create task #{meth.inspect} without usage or description. " << | |
+ "Call desc if you want this method to be available as task or declare it inside a " << | |
+ "no_tasks{} block. Invoked from #{caller[1].inspect}." | |
+ false | |
+ end | |
+ end | |
+ | |
+ def initialize_added #:nodoc: | |
+ class_options.merge!(method_options) | |
+ @method_options = nil | |
+ end | |
+ | |
+ # Receives a task name (can be nil), and try to get a map from it. | |
+ # If a map can't be found use the sent name or the default task. | |
+ # | |
+ def normalize_task_name(meth) #:nodoc: | |
+ mapping = map[meth.to_s] | |
+ meth = mapping || meth || default_task | |
+ meth.to_s.gsub('-','_') # treat foo-bar > foo_bar | |
+ end | |
+ end | |
+ | |
+ include Thor::Base | |
+ | |
+ map HELP_MAPPINGS => :help | |
+ | |
+ desc "help [TASK]", "Describe available tasks or one specific task" | |
+ def help(task=nil) | |
+ self.class.help(shell, task, :namespace => task && task.include?(?:)) | |
+ end | |
+end | |
diff --git a/railties/lib/rails/vendor/thor-0.12.0/lib/thor/actions.rb b/railties/lib/rails/vendor/thor-0.12.0/lib/thor/actions.rb | |
new file mode 100644 | |
index 0000000..d561ccb | |
--- /dev/null | |
+++ b/railties/lib/rails/vendor/thor-0.12.0/lib/thor/actions.rb | |
@@ -0,0 +1,273 @@ | |
+require 'fileutils' | |
+ | |
+Dir[File.join(File.dirname(__FILE__), "actions", "*.rb")].each do |action| | |
+ require action | |
+end | |
+ | |
+class Thor | |
+ module Actions | |
+ attr_accessor :behavior | |
+ | |
+ def self.included(base) #:nodoc: | |
+ base.extend ClassMethods | |
+ end | |
+ | |
+ module ClassMethods | |
+ # Hold source paths for one Thor instance. source_paths_for_search is the | |
+ # method responsible to gather source_paths from this current class, | |
+ # inherited paths and the source root. | |
+ # | |
+ def source_paths | |
+ @source_paths ||= [] | |
+ end | |
+ | |
+ # 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.respond_to?(:source_root) | |
+ paths += from_superclass(:source_paths, []) | |
+ paths | |
+ end | |
+ | |
+ # Add runtime options that help actions execution. | |
+ # | |
+ def add_runtime_options! | |
+ class_option :pretend, :type => :boolean, :aliases => "-p", :group => :runtime, | |
+ :desc => "Run but do not make any changes" | |
+ | |
+ class_option :force, :type => :boolean, :aliases => "-f", :group => :runtime, | |
+ :desc => "Overwrite files that already exist" | |
+ | |
+ class_option :skip, :type => :boolean, :aliases => "-s", :group => :runtime, | |
+ :desc => "Skip files that already exist" | |
+ | |
+ class_option :quiet, :type => :boolean, :aliases => "-q", :group => :runtime, | |
+ :desc => "Supress status output" | |
+ end | |
+ end | |
+ | |
+ # Extends initializer to add more configuration options. | |
+ # | |
+ # ==== Configuration | |
+ # behavior<Symbol>:: The actions default behavior. Can be :invoke or :revoke. | |
+ # It also accepts :force, :skip and :pretend to set the behavior | |
+ # and the respective option. | |
+ # | |
+ # destination_root<String>:: The root directory needed for some actions. | |
+ # | |
+ def initialize(args=[], options={}, config={}) | |
+ self.behavior = case config[:behavior].to_s | |
+ when "force", "skip" | |
+ _cleanup_options_and_set(options, config[:behavior]) | |
+ :invoke | |
+ when "revoke" | |
+ :revoke | |
+ else | |
+ :invoke | |
+ end | |
+ | |
+ super | |
+ self.destination_root = config[:destination_root] | |
+ end | |
+ | |
+ # Wraps an action object and call it accordingly to the thor class behavior. | |
+ # | |
+ def action(instance) #:nodoc: | |
+ if behavior == :revoke | |
+ instance.revoke! | |
+ else | |
+ instance.invoke! | |
+ end | |
+ end | |
+ | |
+ # Returns the root for this thor class (also aliased as destination root). | |
+ # | |
+ def destination_root | |
+ @destination_stack.last | |
+ end | |
+ | |
+ # Sets the root for this thor class. Relatives path are added to the | |
+ # directory where the script was invoked and expanded. | |
+ # | |
+ def destination_root=(root) | |
+ @destination_stack ||= [] | |
+ @destination_stack[0] = File.expand_path(root || '') | |
+ end | |
+ | |
+ # Returns the given path relative to the absolute root (ie, root where | |
+ # the script started). | |
+ # | |
+ def relative_to_original_destination_root(path, remove_dot=true) | |
+ path = path.gsub(@destination_stack[0], '.') | |
+ remove_dot ? (path[2..-1] || '') : path | |
+ end | |
+ | |
+ # Holds source paths in instance so they can be manipulated. | |
+ # | |
+ def source_paths | |
+ @source_paths ||= self.class.source_paths_for_search | |
+ end | |
+ | |
+ # Receives a file or directory and search for it in the source paths. | |
+ # | |
+ def find_in_source_paths(file) | |
+ relative_root = relative_to_original_destination_root(destination_root, false) | |
+ | |
+ source_paths.each do |source| | |
+ source_file = File.expand_path(file, File.join(source, relative_root)) | |
+ return source_file if File.exists?(source_file) | |
+ end | |
+ | |
+ if source_paths.empty? | |
+ raise Error, "You don't have any source path defined for class #{self.class.name}. To fix this, " << | |
+ "you can define a source_root in your class." | |
+ else | |
+ raise Error, "Could not find #{file.inspect} in source paths." | |
+ end | |
+ end | |
+ | |
+ # Do something in the root or on a provided subfolder. If a relative path | |
+ # is given it's referenced from the current root. The full path is yielded | |
+ # to the block you provide. The path is set back to the previous path when | |
+ # the method exits. | |
+ # | |
+ # ==== Parameters | |
+ # dir<String>:: the directory to move to. | |
+ # config<Hash>:: give :verbose => true to log and use padding. | |
+ # | |
+ def inside(dir='', config={}, &block) | |
+ verbose = config.fetch(:verbose, false) | |
+ | |
+ say_status :inside, dir, verbose | |
+ shell.padding += 1 if verbose | |
+ @destination_stack.push File.expand_path(dir, destination_root) | |
+ | |
+ FileUtils.mkdir_p(destination_root) unless File.exist?(destination_root) | |
+ FileUtils.cd(destination_root) { block.arity == 1 ? yield(destination_root) : yield } | |
+ | |
+ @destination_stack.pop | |
+ shell.padding -= 1 if verbose | |
+ end | |
+ | |
+ # Goes to the root and execute the given block. | |
+ # | |
+ def in_root | |
+ inside(@destination_stack.first) { yield } | |
+ end | |
+ | |
+ # Loads an external file and execute it in the instance binding. | |
+ # | |
+ # ==== Parameters | |
+ # path<String>:: The path to the file to execute. Can be a web address or | |
+ # a relative path from the source root. | |
+ # | |
+ # ==== Examples | |
+ # | |
+ # apply "http://gist.github.com/103208" | |
+ # | |
+ # apply "recipes/jquery.rb" | |
+ # | |
+ def apply(path, config={}) | |
+ verbose = config.fetch(:verbose, true) | |
+ path = find_in_source_paths(path) unless path =~ /^http\:\/\// | |
+ | |
+ say_status :apply, path, verbose | |
+ shell.padding += 1 if verbose | |
+ instance_eval(open(path).read) | |
+ shell.padding -= 1 if verbose | |
+ end | |
+ | |
+ # Executes a command. | |
+ # | |
+ # ==== Parameters | |
+ # command<String>:: the command to be executed. | |
+ # config<Hash>:: give :verbose => false to not log the status. Specify :with | |
+ # to append an executable to command executation. | |
+ # | |
+ # ==== Example | |
+ # | |
+ # inside('vendor') do | |
+ # run('ln -s ~/edge rails') | |
+ # end | |
+ # | |
+ def run(command, config={}) | |
+ return unless behavior == :invoke | |
+ | |
+ destination = relative_to_original_destination_root(destination_root, false) | |
+ desc = "#{command} from #{destination.inspect}" | |
+ | |
+ if config[:with] | |
+ desc = "#{File.basename(config[:with].to_s)} #{desc}" | |
+ command = "#{config[:with]} #{command}" | |
+ end | |
+ | |
+ say_status :run, desc, config.fetch(:verbose, true) | |
+ system(command) unless options[:pretend] | |
+ end | |
+ | |
+ # Executes a ruby script (taking into account WIN32 platform quirks). | |
+ # | |
+ # ==== Parameters | |
+ # command<String>:: the command to be executed. | |
+ # config<Hash>:: give :verbose => false to not log the status. | |
+ # | |
+ def run_ruby_script(command, config={}) | |
+ return unless behavior == :invoke | |
+ run "#{command}", config.merge(:with => Thor::Util.ruby_command) | |
+ end | |
+ | |
+ # Run a thor command. A hash of options can be given and it's converted to | |
+ # switches. | |
+ # | |
+ # ==== Parameters | |
+ # task<String>:: the task to be invoked | |
+ # args<Array>:: arguments to the task | |
+ # config<Hash>:: give :verbose => false to not log the status. Other options | |
+ # are given as parameter to Thor. | |
+ # | |
+ # ==== Examples | |
+ # | |
+ # thor :install, "http://gist.github.com/103208" | |
+ # #=> thor install http://gist.github.com/103208 | |
+ # | |
+ # thor :list, :all => true, :substring => 'rails' | |
+ # #=> thor list --all --substring=rails | |
+ # | |
+ def thor(task, *args) | |
+ config = args.last.is_a?(Hash) ? args.pop : {} | |
+ verbose = config.key?(:verbose) ? config.delete(:verbose) : true | |
+ | |
+ args.unshift task | |
+ args.push Thor::Options.to_switches(config) | |
+ command = args.join(' ').strip | |
+ | |
+ run command, :with => :thor, :verbose => verbose | |
+ end | |
+ | |
+ protected | |
+ | |
+ # Allow current root to be shared between invocations. | |
+ # | |
+ def _shared_configuration #:nodoc: | |
+ super.merge!(:destination_root => self.destination_root) | |
+ end | |
+ | |
+ def _cleanup_options_and_set(options, key) #:nodoc: | |
+ case options | |
+ when Array | |
+ %w(--force -f --skip -s).each { |i| options.delete(i) } | |
+ options << "--#{key}" | |
+ when Hash | |
+ [:force, :skip, "force", "skip"].each { |i| options.delete(i) } | |
+ options.merge!(key => true) | |
+ end | |
+ end | |
+ | |
+ end | |
+end | |
diff --git a/railties/lib/rails/vendor/thor-0.12.0/lib/thor/actions/create_file.rb b/railties/lib/rails/vendor/thor-0.12.0/lib/thor/actions/create_file.rb | |
new file mode 100644 | |
index 0000000..a3d9296 | |
--- /dev/null | |
+++ b/railties/lib/rails/vendor/thor-0.12.0/lib/thor/actions/create_file.rb | |
@@ -0,0 +1,103 @@ | |
+require 'thor/actions/empty_directory' | |
+ | |
+class Thor | |
+ module Actions | |
+ | |
+ # Create a new file relative to the destination root with the given data, | |
+ # which is the return value of a block or a data string. | |
+ # | |
+ # ==== Parameters | |
+ # destination<String>:: the relative path to the destination root. | |
+ # data<String|NilClass>:: the data to append to the file. | |
+ # config<Hash>:: give :verbose => false to not log the status. | |
+ # | |
+ # ==== Examples | |
+ # | |
+ # create_file "lib/fun_party.rb" do | |
+ # hostname = ask("What is the virtual hostname I should use?") | |
+ # "vhost.name = #{hostname}" | |
+ # end | |
+ # | |
+ # create_file "config/apach.conf", "your apache config" | |
+ # | |
+ def create_file(destination, data=nil, config={}, &block) | |
+ action CreateFile.new(self, destination, block || data.to_s, config) | |
+ end | |
+ alias :add_file :create_file | |
+ | |
+ # AddFile is a subset of Template, which instead of rendering a file with | |
+ # ERB, it gets the content from the user. | |
+ # | |
+ class CreateFile < EmptyDirectory #:nodoc: | |
+ attr_reader :data | |
+ | |
+ def initialize(base, destination, data, config={}) | |
+ @data = data | |
+ super(base, destination, config) | |
+ end | |
+ | |
+ # Checks if the content of the file at the destination is identical to the rendered result. | |
+ # | |
+ # ==== Returns | |
+ # Boolean:: true if it is identical, false otherwise. | |
+ # | |
+ def identical? | |
+ exists? && File.read(destination) == render | |
+ end | |
+ | |
+ # Holds the content to be added to the file. | |
+ # | |
+ def render | |
+ @render ||= if data.is_a?(Proc) | |
+ data.call | |
+ else | |
+ data | |
+ end | |
+ end | |
+ | |
+ def invoke! | |
+ invoke_with_conflict_check do | |
+ FileUtils.mkdir_p(File.dirname(destination)) | |
+ File.open(destination, 'w'){ |f| f.write render } | |
+ end | |
+ given_destination | |
+ end | |
+ | |
+ protected | |
+ | |
+ # Now on conflict we check if the file is identical or not. | |
+ # | |
+ def on_conflict_behavior(&block) | |
+ if identical? | |
+ say_status :identical, :blue | |
+ else | |
+ options = base.options.merge(config) | |
+ force_or_skip_or_conflict(options[:force], options[:skip], &block) | |
+ end | |
+ end | |
+ | |
+ # If force is true, run the action, otherwise check if it's not being | |
+ # skipped. If both are false, show the file_collision menu, if the menu | |
+ # returns true, force it, otherwise skip. | |
+ # | |
+ def force_or_skip_or_conflict(force, skip, &block) | |
+ if force | |
+ say_status :force, :yellow | |
+ block.call unless pretend? | |
+ elsif skip | |
+ say_status :skip, :yellow | |
+ else | |
+ say_status :conflict, :red | |
+ force_or_skip_or_conflict(force_on_collision?, true, &block) | |
+ end | |
+ end | |
+ | |
+ # Shows the file collision menu to the user and gets the result. | |
+ # | |
+ def force_on_collision? | |
+ base.shell.file_collision(destination){ render } | |
+ end | |
+ | |
+ end | |
+ end | |
+end | |
diff --git a/railties/lib/rails/vendor/thor-0.12.0/lib/thor/actions/directory.rb b/railties/lib/rails/vendor/thor-0.12.0/lib/thor/actions/directory.rb | |
new file mode 100644 | |
index 0000000..467e637 | |
--- /dev/null | |
+++ b/railties/lib/rails/vendor/thor-0.12.0/lib/thor/actions/directory.rb | |
@@ -0,0 +1,93 @@ | |
+require 'thor/actions/empty_directory' | |
+ | |
+class Thor | |
+ module Actions | |
+ | |
+ # Copies recursively the files from source directory to root directory. | |
+ # If any of the files finishes with .tt, it's considered to be a template | |
+ # and is placed in the destination without the extension .tt. If any | |
+ # empty directory is found, it's copied and all .empty_directory files are | |
+ # ignored. Remember that file paths can also be encoded, let's suppose a doc | |
+ # directory with the following files: | |
+ # | |
+ # doc/ | |
+ # components/.empty_directory | |
+ # README | |
+ # rdoc.rb.tt | |
+ # %app_name%.rb | |
+ # | |
+ # When invoked as: | |
+ # | |
+ # directory "doc" | |
+ # | |
+ # It will create a doc directory in the destination with the following | |
+ # files (assuming that the app_name is "blog"): | |
+ # | |
+ # doc/ | |
+ # components/ | |
+ # README | |
+ # rdoc.rb | |
+ # blog.rb | |
+ # | |
+ # ==== Parameters | |
+ # source<String>:: the relative path to the source root. | |
+ # destination<String>:: the relative path to the destination root. | |
+ # config<Hash>:: give :verbose => false to not log the status. | |
+ # If :recursive => false, does not look for paths recursively. | |
+ # | |
+ # ==== Examples | |
+ # | |
+ # directory "doc" | |
+ # directory "doc", "docs", :recursive => false | |
+ # | |
+ def directory(source, destination=nil, config={}, &block) | |
+ action Directory.new(self, source, destination || source, config, &block) | |
+ end | |
+ | |
+ class Directory < EmptyDirectory #:nodoc: | |
+ attr_reader :source | |
+ | |
+ def initialize(base, source, destination=nil, config={}, &block) | |
+ @source = File.expand_path(base.find_in_source_paths(source.to_s)) | |
+ @block = block | |
+ super(base, destination, { :recursive => true }.merge(config)) | |
+ end | |
+ | |
+ def invoke! | |
+ base.empty_directory given_destination, config | |
+ execute! | |
+ end | |
+ | |
+ def revoke! | |
+ execute! | |
+ end | |
+ | |
+ protected | |
+ | |
+ def execute! | |
+ lookup = config[:recursive] ? File.join(source, '**') : source | |
+ lookup = File.join(lookup, '{*,.[a-z]*}') | |
+ | |
+ Dir[lookup].each do |file_source| | |
+ next if File.directory?(file_source) | |
+ file_destination = File.join(given_destination, file_source.gsub(source, '.')) | |
+ file_destination.gsub!('/./', '/') | |
+ | |
+ case file_source | |
+ when /\.empty_directory$/ | |
+ dirname = File.dirname(file_destination).gsub(/\/\.$/, '') | |
+ next if dirname == given_destination | |
+ base.empty_directory(dirname, config) | |
+ when /\.tt$/ | |
+ destination = base.template(file_source, file_destination[0..-4], config) | |
+ @block.call(destination) if @block | |
+ else | |
+ destination = base.copy_file(file_source, file_destination, config) | |
+ @block.call(destination) if @block | |
+ end | |
+ end | |
+ end | |
+ | |
+ end | |
+ end | |
+end | |
diff --git a/railties/lib/rails/vendor/thor-0.12.0/lib/thor/actions/empty_directory.rb b/railties/lib/rails/vendor/thor-0.12.0/lib/thor/actions/empty_directory.rb | |
new file mode 100644 | |
index 0000000..484cb82 | |
--- /dev/null | |
+++ b/railties/lib/rails/vendor/thor-0.12.0/lib/thor/actions/empty_directory.rb | |
@@ -0,0 +1,134 @@ | |
+class Thor | |
+ module Actions | |
+ | |
+ # Creates an empty directory. | |
+ # | |
+ # ==== Parameters | |
+ # destination<String>:: the relative path to the destination root. | |
+ # config<Hash>:: give :verbose => false to not log the status. | |
+ # | |
+ # ==== Examples | |
+ # | |
+ # empty_directory "doc" | |
+ # | |
+ def empty_directory(destination, config={}) | |
+ action EmptyDirectory.new(self, destination, config) | |
+ end | |
+ | |
+ # Class which holds create directory logic. This is the base class for | |
+ # other actions like create_file and directory. | |
+ # | |
+ # This implementation is based in Templater actions, created by Jonas Nicklas | |
+ # and Michael S. Klishin under MIT LICENSE. | |
+ # | |
+ class EmptyDirectory #:nodoc: | |
+ attr_reader :base, :destination, :given_destination, :relative_destination, :config | |
+ | |
+ # Initializes given the source and destination. | |
+ # | |
+ # ==== Parameters | |
+ # base<Thor::Base>:: A Thor::Base instance | |
+ # source<String>:: Relative path to the source of this file | |
+ # destination<String>:: Relative path to the destination of this file | |
+ # config<Hash>:: give :verbose => false to not log the status. | |
+ # | |
+ def initialize(base, destination, config={}) | |
+ @base, @config = base, { :verbose => true }.merge(config) | |
+ self.destination = destination | |
+ end | |
+ | |
+ # Checks if the destination file already exists. | |
+ # | |
+ # ==== Returns | |
+ # Boolean:: true if the file exists, false otherwise. | |
+ # | |
+ def exists? | |
+ ::File.exists?(destination) | |
+ end | |
+ | |
+ def invoke! | |
+ invoke_with_conflict_check do | |
+ ::FileUtils.mkdir_p(destination) | |
+ end | |
+ end | |
+ | |
+ def revoke! | |
+ say_status :remove, :red | |
+ ::FileUtils.rm_rf(destination) if !pretend? && exists? | |
+ given_destination | |
+ end | |
+ | |
+ protected | |
+ | |
+ # Shortcut for pretend. | |
+ # | |
+ def pretend? | |
+ base.options[:pretend] | |
+ end | |
+ | |
+ # Sets the absolute destination value from a relative destination value. | |
+ # It also stores the given and relative destination. Let's suppose our | |
+ # script is being executed on "dest", it sets the destination root to | |
+ # "dest". The destination, given_destination and relative_destination | |
+ # are related in the following way: | |
+ # | |
+ # inside "bar" do | |
+ # empty_directory "baz" | |
+ # end | |
+ # | |
+ # destination #=> dest/bar/baz | |
+ # relative_destination #=> bar/baz | |
+ # given_destination #=> baz | |
+ # | |
+ def destination=(destination) | |
+ if destination | |
+ @given_destination = convert_encoded_instructions(destination.to_s) | |
+ @destination = ::File.expand_path(@given_destination, base.destination_root) | |
+ @relative_destination = base.relative_to_original_destination_root(@destination) | |
+ end | |
+ end | |
+ | |
+ # Filenames in the encoded form are converted. If you have a file: | |
+ # | |
+ # %class_name%.rb | |
+ # | |
+ # It gets the class name from the base and replace it: | |
+ # | |
+ # user.rb | |
+ # | |
+ def convert_encoded_instructions(filename) | |
+ filename.gsub(/%(.*?)%/) do |string| | |
+ instruction = $1.strip | |
+ base.respond_to?(instruction) ? base.send(instruction) : string | |
+ end | |
+ end | |
+ | |
+ # Receives a hash of options and just execute the block if some | |
+ # conditions are met. | |
+ # | |
+ def invoke_with_conflict_check(&block) | |
+ if exists? | |
+ on_conflict_behavior(&block) | |
+ else | |
+ say_status :create, :green | |
+ block.call unless pretend? | |
+ end | |
+ | |
+ destination | |
+ end | |
+ | |
+ # What to do when the destination file already exists. | |
+ # | |
+ def on_conflict_behavior(&block) | |
+ say_status :exist, :blue | |
+ end | |
+ | |
+ # Shortcut to say_status shell method. | |
+ # | |
+ def say_status(status, color) | |
+ base.shell.say_status status, relative_destination, color if config[:verbose] | |
+ end | |
+ | |
+ end | |
+ end | |
+end | |
diff --git a/railties/lib/rails/vendor/thor-0.12.0/lib/thor/actions/file_manipulation.rb b/railties/lib/rails/vendor/thor-0.12.0/lib/thor/actions/file_manipulation.rb | |
new file mode 100644 | |
index 0000000..d77d90d | |
--- /dev/null | |
+++ b/railties/lib/rails/vendor/thor-0.12.0/lib/thor/actions/file_manipulation.rb | |
@@ -0,0 +1,219 @@ | |
+require 'erb' | |
+require 'open-uri' | |
+ | |
+class Thor | |
+ module Actions | |
+ | |
+ # Copies the file from the relative source to the relative destination. If | |
+ # the destination is not given it's assumed to be equal to the source. | |
+ # | |
+ # ==== Parameters | |
+ # source<String>:: the relative path to the source root. | |
+ # destination<String>:: the relative path to the destination root. | |
+ # config<Hash>:: give :verbose => false to not log the status. | |
+ # | |
+ # ==== Examples | |
+ # | |
+ # copy_file "README", "doc/README" | |
+ # | |
+ # copy_file "doc/README" | |
+ # | |
+ def copy_file(source, destination=nil, config={}) | |
+ destination ||= source | |
+ source = File.expand_path(find_in_source_paths(source.to_s)) | |
+ | |
+ create_file destination, nil, config do | |
+ File.read(source) | |
+ end | |
+ end | |
+ | |
+ # Gets the content at the given address and places it at the given relative | |
+ # destination. If a block is given instead of destination, the content of | |
+ # the url is yielded and used as location. | |
+ # | |
+ # ==== Parameters | |
+ # source<String>:: the address of the given content. | |
+ # destination<String>:: the relative path to the destination root. | |
+ # config<Hash>:: give :verbose => false to not log the status. | |
+ # | |
+ # ==== Examples | |
+ # | |
+ # get "http://gist.github.com/103208", "doc/README" | |
+ # | |
+ # get "http://gist.github.com/103208" do |content| | |
+ # content.split("\n").first | |
+ # end | |
+ # | |
+ def get(source, destination=nil, config={}, &block) | |
+ source = File.expand_path(find_in_source_paths(source.to_s)) unless source =~ /^http\:\/\// | |
+ render = open(source).read | |
+ | |
+ destination ||= if block_given? | |
+ block.arity == 1 ? block.call(render) : block.call | |
+ else | |
+ File.basename(source) | |
+ end | |
+ | |
+ create_file destination, render, config | |
+ end | |
+ | |
+ # Gets an ERB template at the relative source, executes it and makes a copy | |
+ # at the relative destination. If the destination is not given it's assumed | |
+ # to be equal to the source removing .tt from the filename. | |
+ # | |
+ # ==== Parameters | |
+ # source<String>:: the relative path to the source root. | |
+ # destination<String>:: the relative path to the destination root. | |
+ # config<Hash>:: give :verbose => false to not log the status. | |
+ # | |
+ # ==== Examples | |
+ # | |
+ # template "README", "doc/README" | |
+ # | |
+ # template "doc/README" | |
+ # | |
+ def template(source, destination=nil, config={}) | |
+ destination ||= source | |
+ source = File.expand_path(find_in_source_paths(source.to_s)) | |
+ context = instance_eval('binding') | |
+ | |
+ create_file destination, nil, config do | |
+ ERB.new(::File.read(source), nil, '-').result(context) | |
+ end | |
+ end | |
+ | |
+ # Changes the mode of the given file or directory. | |
+ # | |
+ # ==== Parameters | |
+ # mode<Integer>:: the file mode | |
+ # path<String>:: the name of the file to change mode | |
+ # config<Hash>:: give :verbose => false to not log the status. | |
+ # | |
+ # ==== Example | |
+ # | |
+ # chmod "script/*", 0755 | |
+ # | |
+ def chmod(path, mode, config={}) | |
+ return unless behavior == :invoke | |
+ path = File.expand_path(path, destination_root) | |
+ say_status :chmod, relative_to_original_destination_root(path), config.fetch(:verbose, true) | |
+ FileUtils.chmod_R(mode, path) unless options[:pretend] | |
+ end | |
+ | |
+ # Prepend text to a file. Since it depends on inject_into_file, it's reversible. | |
+ # | |
+ # ==== Parameters | |
+ # path<String>:: path of the file to be changed | |
+ # data<String>:: the data to prepend to the file, can be also given as a block. | |
+ # config<Hash>:: give :verbose => false to not log the status. | |
+ # | |
+ # ==== Example | |
+ # | |
+ # prepend_file 'config/environments/test.rb', 'config.gem "rspec"' | |
+ # | |
+ # prepend_file 'config/environments/test.rb' do | |
+ # 'config.gem "rspec"' | |
+ # end | |
+ # | |
+ def prepend_file(path, *args, &block) | |
+ config = args.last.is_a?(Hash) ? args.pop : {} | |
+ config.merge!(:after => /\A/) | |
+ inject_into_file(path, *(args << config), &block) | |
+ end | |
+ | |
+ # Append text to a file. Since it depends on inject_into_file, it's reversible. | |
+ # | |
+ # ==== Parameters | |
+ # path<String>:: path of the file to be changed | |
+ # data<String>:: the data to append to the file, can be also given as a block. | |
+ # config<Hash>:: give :verbose => false to not log the status. | |
+ # | |
+ # ==== Example | |
+ # | |
+ # append_file 'config/environments/test.rb', 'config.gem "rspec"' | |
+ # | |
+ # append_file 'config/environments/test.rb' do | |
+ # 'config.gem "rspec"' | |
+ # end | |
+ # | |
+ def append_file(path, *args, &block) | |
+ config = args.last.is_a?(Hash) ? args.pop : {} | |
+ config.merge!(:before => /\z/) | |
+ inject_into_file(path, *(args << config), &block) | |
+ end | |
+ | |
+ # Injects text right after the class definition. Since it depends on | |
+ # inject_into_file, it's reversible. | |
+ # | |
+ # ==== Parameters | |
+ # path<String>:: path of the file to be changed | |
+ # klass<String|Class>:: the class to be manipulated | |
+ # data<String>:: the data to append to the class, can be also given as a block. | |
+ # config<Hash>:: give :verbose => false to not log the status. | |
+ # | |
+ # ==== Examples | |
+ # | |
+ # inject_into_class "app/controllers/application_controller.rb", " filter_parameter :password\n" | |
+ # | |
+ # inject_into_class "app/controllers/application_controller.rb", ApplicationController do | |
+ # " filter_parameter :password\n" | |
+ # end | |
+ # | |
+ def inject_into_class(path, klass, *args, &block) | |
+ config = args.last.is_a?(Hash) ? args.pop : {} | |
+ config.merge!(:after => /class #{klass}\n|class #{klass} .*\n/) | |
+ inject_into_file(path, *(args << config), &block) | |
+ end | |
+ | |
+ # Run a regular expression replacement on a file. | |
+ # | |
+ # ==== Parameters | |
+ # path<String>:: path of the file to be changed | |
+ # flag<Regexp|String>:: the regexp or string to be replaced | |
+ # replacement<String>:: the replacement, can be also given as a block | |
+ # config<Hash>:: give :verbose => false to not log the status. | |
+ # | |
+ # ==== Example | |
+ # | |
+ # gsub_file 'app/controllers/application_controller.rb', /#\s*(filter_parameter_logging :password)/, '\1' | |
+ # | |
+ # gsub_file 'README', /rake/, :green do |match| | |
+ # match << " no more. Use thor!" | |
+ # end | |
+ # | |
+ def gsub_file(path, flag, *args, &block) | |
+ return unless behavior == :invoke | |
+ config = args.last.is_a?(Hash) ? args.pop : {} | |
+ | |
+ path = File.expand_path(path, destination_root) | |
+ say_status :gsub, relative_to_original_destination_root(path), config.fetch(:verbose, true) | |
+ | |
+ unless options[:pretend] | |
+ content = File.read(path) | |
+ content.gsub!(flag, *args, &block) | |
+ File.open(path, 'wb') { |file| file.write(content) } | |
+ end | |
+ end | |
+ | |
+ # Removes a file at the given location. | |
+ # | |
+ # ==== Parameters | |
+ # path<String>:: path of the file to be changed | |
+ # config<Hash>:: give :verbose => false to not log the status. | |
+ # | |
+ # ==== Example | |
+ # | |
+ # remove_file 'README' | |
+ # remove_file 'app/controllers/application_controller.rb' | |
+ # | |
+ def remove_file(path, config={}) | |
+ return unless behavior == :invoke | |
+ path = File.expand_path(path, destination_root) | |
+ | |
+ say_status :remove, relative_to_original_destination_root(path), config.fetch(:verbose, true) | |
+ ::FileUtils.rm_rf(path) if !options[:pretend] && File.exists?(path) | |
+ end | |
+ alias :remove_dir :remove_file | |
+ | |
+ end | |
+end | |
diff --git a/railties/lib/rails/vendor/thor-0.12.0/lib/thor/actions/inject_into_file.rb b/railties/lib/rails/vendor/thor-0.12.0/lib/thor/actions/inject_into_file.rb | |
new file mode 100644 | |
index 0000000..0636ec6 | |
--- /dev/null | |
+++ b/railties/lib/rails/vendor/thor-0.12.0/lib/thor/actions/inject_into_file.rb | |
@@ -0,0 +1,101 @@ | |
+require 'thor/actions/empty_directory' | |
+ | |
+class Thor | |
+ module Actions | |
+ | |
+ # Injects the given content into a file. Different from gsub_file, this | |
+ # method is reversible. | |
+ # | |
+ # ==== Parameters | |
+ # destination<String>:: Relative path to the destination root | |
+ # data<String>:: Data to add to the file. Can be given as a block. | |
+ # config<Hash>:: give :verbose => false to not log the status and the flag | |
+ # for injection (:after or :before). | |
+ # | |
+ # ==== Examples | |
+ # | |
+ # inject_into_file "config/environment.rb", "config.gem :thor", :after => "Rails::Initializer.run do |config|\n" | |
+ # | |
+ # inject_into_file "config/environment.rb", :after => "Rails::Initializer.run do |config|\n" do | |
+ # gems = ask "Which gems would you like to add?" | |
+ # gems.split(" ").map{ |gem| " config.gem :#{gem}" }.join("\n") | |
+ # end | |
+ # | |
+ def inject_into_file(destination, *args, &block) | |
+ if block_given? | |
+ data, config = block, args.shift | |
+ else | |
+ data, config = args.shift, args.shift | |
+ end | |
+ action InjectIntoFile.new(self, destination, data, config) | |
+ end | |
+ | |
+ class InjectIntoFile < EmptyDirectory #:nodoc: | |
+ attr_reader :replacement, :flag, :behavior | |
+ | |
+ def initialize(base, destination, data, config) | |
+ super(base, destination, { :verbose => true }.merge(config)) | |
+ | |
+ @behavior, @flag = if @config.key?(:after) | |
+ [:after, @config.delete(:after)] | |
+ else | |
+ [:before, @config.delete(:before)] | |
+ end | |
+ | |
+ @replacement = data.is_a?(Proc) ? data.call : data | |
+ @flag = Regexp.escape(@flag) unless @flag.is_a?(Regexp) | |
+ end | |
+ | |
+ def invoke! | |
+ say_status :invoke | |
+ | |
+ content = if @behavior == :after | |
+ '\0' + replacement | |
+ else | |
+ replacement + '\0' | |
+ end | |
+ | |
+ replace!(/#{flag}/, content) | |
+ end | |
+ | |
+ def revoke! | |
+ say_status :revoke | |
+ | |
+ regexp = if @behavior == :after | |
+ content = '\1\2' | |
+ /(#{flag})(.*)(#{Regexp.escape(replacement)})/m | |
+ else | |
+ content = '\2\3' | |
+ /(#{Regexp.escape(replacement)})(.*)(#{flag})/m | |
+ end | |
+ | |
+ replace!(regexp, content) | |
+ end | |
+ | |
+ protected | |
+ | |
+ def say_status(behavior) | |
+ status = if flag == /\A/ | |
+ behavior == :invoke ? :prepend : :unprepend | |
+ elsif flag == /\z/ | |
+ behavior == :invoke ? :append : :unappend | |
+ else | |
+ behavior == :invoke ? :inject : :deinject | |
+ end | |
+ | |
+ super(status, config[:verbose]) | |
+ end | |
+ | |
+ # Adds the content to the file. | |
+ # | |
+ def replace!(regexp, string) | |
+ unless base.options[:pretend] | |
+ content = File.read(destination) | |
+ content.gsub!(regexp, string) | |
+ File.open(destination, 'wb') { |file| file.write(content) } | |
+ end | |
+ end | |
+ | |
+ end | |
+ end | |
+end | |
diff --git a/railties/lib/rails/vendor/thor-0.12.0/lib/thor/base.rb b/railties/lib/rails/vendor/thor-0.12.0/lib/thor/base.rb | |
new file mode 100644 | |
index 0000000..700d794 | |
--- /dev/null | |
+++ b/railties/lib/rails/vendor/thor-0.12.0/lib/thor/base.rb | |
@@ -0,0 +1,517 @@ | |
+require 'thor/core_ext/hash_with_indifferent_access' | |
+require 'thor/core_ext/ordered_hash' | |
+require 'thor/error' | |
+require 'thor/shell' | |
+require 'thor/invocation' | |
+require 'thor/parser' | |
+require 'thor/task' | |
+require 'thor/util' | |
+ | |
+class Thor | |
+ # Shortcuts for help. | |
+ HELP_MAPPINGS = %w(-h -? --help -D) | |
+ | |
+ # Thor methods that should not be overwritten by the user. | |
+ THOR_RESERVED_WORDS = %w(invoke shell options behavior root destination_root relative_root | |
+ action add_file create_file in_root inside run run_ruby_script) | |
+ | |
+ module Base | |
+ attr_accessor :options | |
+ | |
+ # It receives arguments in an Array and two hashes, one for options and | |
+ # other for configuration. | |
+ # | |
+ # Notice that it does not check if all required arguments were supplied. | |
+ # It should be done by the parser. | |
+ # | |
+ # ==== Parameters | |
+ # args<Array[Object]>:: An array of objects. The objects are applied to their | |
+ # respective accessors declared with <tt>argument</tt>. | |
+ # | |
+ # options<Hash>:: An options hash that will be available as self.options. | |
+ # The hash given is converted to a hash with indifferent | |
+ # access, magic predicates (options.skip?) and then frozen. | |
+ # | |
+ # config<Hash>:: Configuration for this Thor class. | |
+ # | |
+ def initialize(args=[], options={}, config={}) | |
+ Thor::Arguments.parse(self.class.arguments, args).each do |key, value| | |
+ send("#{key}=", value) | |
+ end | |
+ | |
+ parse_options = self.class.class_options | |
+ | |
+ if options.is_a?(Array) | |
+ task_options = config.delete(:task_options) # hook for start | |
+ parse_options = parse_options.merge(task_options) if task_options | |
+ array_options, hash_options = options, {} | |
+ else | |
+ array_options, hash_options = [], options | |
+ end | |
+ | |
+ options = Thor::Options.parse(parse_options, array_options) | |
+ self.options = Thor::CoreExt::HashWithIndifferentAccess.new(options).merge!(hash_options) | |
+ self.options.freeze | |
+ end | |
+ | |
+ class << self | |
+ def included(base) #:nodoc: | |
+ base.send :extend, ClassMethods | |
+ base.send :include, Invocation | |
+ base.send :include, Shell | |
+ end | |
+ | |
+ # Returns the classes that inherits from Thor or Thor::Group. | |
+ # | |
+ # ==== Returns | |
+ # Array[Class] | |
+ # | |
+ def subclasses | |
+ @subclasses ||= [] | |
+ end | |
+ | |
+ # Returns the files where the subclasses are kept. | |
+ # | |
+ # ==== Returns | |
+ # Hash[path<String> => Class] | |
+ # | |
+ def subclass_files | |
+ @subclass_files ||= Hash.new{ |h,k| h[k] = [] } | |
+ end | |
+ | |
+ # Whenever a class inherits from Thor or Thor::Group, we should track the | |
+ # class and the file on Thor::Base. This is the method responsable for it. | |
+ # | |
+ def register_klass_file(klass) #:nodoc: | |
+ file = caller[1].match(/(.*):\d+/)[1] | |
+ Thor::Base.subclasses << klass unless Thor::Base.subclasses.include?(klass) | |
+ | |
+ file_subclasses = Thor::Base.subclass_files[File.expand_path(file)] | |
+ file_subclasses << klass unless file_subclasses.include?(klass) | |
+ end | |
+ end | |
+ | |
+ module ClassMethods | |
+ # Adds an argument to the class and creates an attr_accessor for it. | |
+ # | |
+ # Arguments are different from options in several aspects. The first one | |
+ # is how they are parsed from the command line, arguments are retrieved | |
+ # from position: | |
+ # | |
+ # thor task NAME | |
+ # | |
+ # Instead of: | |
+ # | |
+ # thor task --name=NAME | |
+ # | |
+ # Besides, arguments are used inside your code as an accessor (self.argument), | |
+ # while options are all kept in a hash (self.options). | |
+ # | |
+ # Finally, arguments cannot have type :default or :boolean but can be | |
+ # optional (supplying :optional => :true or :required => false), although | |
+ # you cannot have a required argument after a non-required argument. If you | |
+ # try it, an error is raised. | |
+ # | |
+ # ==== Parameters | |
+ # name<Symbol>:: The name of the argument. | |
+ # options<Hash>:: Described below. | |
+ # | |
+ # ==== Options | |
+ # :desc - Description for the argument. | |
+ # :required - If the argument is required or not. | |
+ # :optional - If the argument is optional or not. | |
+ # :type - The type of the argument, can be :string, :hash, :array, :numeric. | |
+ # :default - Default value for this argument. It cannot be required and have default values. | |
+ # :banner - String to show on usage notes. | |
+ # | |
+ # ==== Errors | |
+ # ArgumentError:: Raised if you supply a required argument after a non required one. | |
+ # | |
+ def argument(name, options={}) | |
+ is_thor_reserved_word?(name, :argument) | |
+ no_tasks { attr_accessor name } | |
+ | |
+ required = if options.key?(:optional) | |
+ !options[:optional] | |
+ elsif options.key?(:required) | |
+ options[:required] | |
+ else | |
+ options[:default].nil? | |
+ end | |
+ | |
+ remove_argument name | |
+ | |
+ arguments.each do |argument| | |
+ next if argument.required? | |
+ raise ArgumentError, "You cannot have #{name.to_s.inspect} as required argument after " << | |
+ "the non-required argument #{argument.human_name.inspect}." | |
+ end if required | |
+ | |
+ arguments << Thor::Argument.new(name, options[:desc], required, options[:type], | |
+ options[:default], options[:banner]) | |
+ end | |
+ | |
+ # Returns this class arguments, looking up in the ancestors chain. | |
+ # | |
+ # ==== Returns | |
+ # Array[Thor::Argument] | |
+ # | |
+ def arguments | |
+ @arguments ||= from_superclass(:arguments, []) | |
+ end | |
+ | |
+ # Adds a bunch of options to the set of class options. | |
+ # | |
+ # class_options :foo => false, :bar => :required, :baz => :string | |
+ # | |
+ # If you prefer more detailed declaration, check class_option. | |
+ # | |
+ # ==== Parameters | |
+ # Hash[Symbol => Object] | |
+ # | |
+ def class_options(options=nil) | |
+ @class_options ||= from_superclass(:class_options, {}) | |
+ build_options(options, @class_options) if options | |
+ @class_options | |
+ end | |
+ | |
+ # Adds an option to the set of class options | |
+ # | |
+ # ==== Parameters | |
+ # name<Symbol>:: The name of the argument. | |
+ # options<Hash>:: Described below. | |
+ # | |
+ # ==== Options | |
+ # :desc - Description for the argument. | |
+ # :required - If the argument is required or not. | |
+ # :default - Default value for this argument. | |
+ # :group - The group for this options. Use by class options to output options in different levels. | |
+ # :aliases - Aliases for this option. | |
+ # :type - The type of the argument, can be :string, :hash, :array, :numeric or :boolean. | |
+ # :banner - String to show on usage notes. | |
+ # | |
+ def class_option(name, options={}) | |
+ build_option(name, options, class_options) | |
+ end | |
+ | |
+ # Removes a previous defined argument. If :undefine is given, undefine | |
+ # accessors as well. | |
+ # | |
+ # ==== Paremeters | |
+ # names<Array>:: Arguments to be removed | |
+ # | |
+ # ==== Examples | |
+ # | |
+ # remove_argument :foo | |
+ # remove_argument :foo, :bar, :baz, :undefine => true | |
+ # | |
+ def remove_argument(*names) | |
+ options = names.last.is_a?(Hash) ? names.pop : {} | |
+ | |
+ names.each do |name| | |
+ arguments.delete_if { |a| a.name == name.to_s } | |
+ undef_method name, "#{name}=" if options[:undefine] | |
+ end | |
+ end | |
+ | |
+ # Removes a previous defined class option. | |
+ # | |
+ # ==== Paremeters | |
+ # names<Array>:: Class options to be removed | |
+ # | |
+ # ==== Examples | |
+ # | |
+ # remove_class_option :foo | |
+ # remove_class_option :foo, :bar, :baz | |
+ # | |
+ def remove_class_option(*names) | |
+ names.each do |name| | |
+ class_options.delete(name) | |
+ end | |
+ end | |
+ | |
+ # Defines the group. This is used when thor list is invoked so you can specify | |
+ # that only tasks from a pre-defined group will be shown. Defaults to standard. | |
+ # | |
+ # ==== Parameters | |
+ # name<String|Symbol> | |
+ # | |
+ def group(name=nil) | |
+ case name | |
+ when nil | |
+ @group ||= from_superclass(:group, 'standard') | |
+ else | |
+ @group = name.to_s | |
+ end | |
+ end | |
+ | |
+ # Returns the tasks for this Thor class. | |
+ # | |
+ # ==== Returns | |
+ # OrderedHash:: An ordered hash with tasks names as keys and Thor::Task | |
+ # objects as values. | |
+ # | |
+ def tasks | |
+ @tasks ||= Thor::CoreExt::OrderedHash.new | |
+ end | |
+ | |
+ # Returns the tasks for this Thor class and all subclasses. | |
+ # | |
+ # ==== Returns | |
+ # OrderedHash:: An ordered hash with tasks names as keys and Thor::Task | |
+ # objects as values. | |
+ # | |
+ def all_tasks | |
+ @all_tasks ||= from_superclass(:all_tasks, Thor::CoreExt::OrderedHash.new) | |
+ @all_tasks.merge(tasks) | |
+ end | |
+ | |
+ # Removes a given task from this Thor class. This is usually done if you | |
+ # are inheriting from another class and don't want it to be available | |
+ # anymore. | |
+ # | |
+ # By default it only remove the mapping to the task. But you can supply | |
+ # :undefine => true to undefine the method from the class as well. | |
+ # | |
+ # ==== Parameters | |
+ # name<Symbol|String>:: The name of the task to be removed | |
+ # options<Hash>:: You can give :undefine => true if you want tasks the method | |
+ # to be undefined from the class as well. | |
+ # | |
+ def remove_task(*names) | |
+ options = names.last.is_a?(Hash) ? names.pop : {} | |
+ | |
+ names.each do |name| | |
+ tasks.delete(name.to_s) | |
+ all_tasks.delete(name.to_s) | |
+ undef_method name if options[:undefine] | |
+ end | |
+ end | |
+ | |
+ # All methods defined inside the given block are not added as tasks. | |
+ # | |
+ # So you can do: | |
+ # | |
+ # class MyScript < Thor | |
+ # no_tasks do | |
+ # def this_is_not_a_task | |
+ # end | |
+ # end | |
+ # end | |
+ # | |
+ # You can also add the method and remove it from the task list: | |
+ # | |
+ # class MyScript < Thor | |
+ # def this_is_not_a_task | |
+ # end | |
+ # remove_task :this_is_not_a_task | |
+ # end | |
+ # | |
+ def no_tasks | |
+ @no_tasks = true | |
+ yield | |
+ @no_tasks = false | |
+ end | |
+ | |
+ # Sets the namespace for the Thor or Thor::Group class. By default the | |
+ # namespace is retrieved from the class name. If your Thor class is named | |
+ # Scripts::MyScript, the help method, for example, will be called as: | |
+ # | |
+ # thor scripts:my_script -h | |
+ # | |
+ # If you change the namespace: | |
+ # | |
+ # namespace :my_scripts | |
+ # | |
+ # You change how your tasks are invoked: | |
+ # | |
+ # thor my_scripts -h | |
+ # | |
+ # Finally, if you change your namespace to default: | |
+ # | |
+ # namespace :default | |
+ # | |
+ # Your tasks can be invoked with a shortcut. Instead of: | |
+ # | |
+ # thor :my_task | |
+ # | |
+ def namespace(name=nil) | |
+ case name | |
+ when nil | |
+ @namespace ||= Thor::Util.namespace_from_thor_class(self, false) | |
+ else | |
+ @namespace = name.to_s | |
+ end | |
+ end | |
+ | |
+ # Default way to start generators from the command line. | |
+ # | |
+ def start(given_args=ARGV, config={}) | |
+ config[:shell] ||= Thor::Base.shell.new | |
+ yield | |
+ rescue Thor::Error => e | |
+ if given_args.include?("--debug") | |
+ raise e | |
+ else | |
+ config[:shell].error e.message | |
+ end | |
+ exit(1) if exit_on_failure? | |
+ end | |
+ | |
+ protected | |
+ | |
+ # Prints the class options per group. If an option does not belong to | |
+ # any group, it uses the ungrouped name value. This method provide to | |
+ # hooks to add extra options, one of them if the third argument called | |
+ # extra_group that should be a hash in the format :group => Array[Options]. | |
+ # | |
+ # The second is by returning a lambda used to print values. The lambda | |
+ # requires two options: the group name and the array of options. | |
+ # | |
+ def class_options_help(shell, ungrouped_name=nil, extra_group=nil) #:nodoc: | |
+ groups = {} | |
+ | |
+ class_options.each do |_, value| | |
+ groups[value.group] ||= [] | |
+ groups[value.group] << value | |
+ end | |
+ | |
+ printer = proc do |group_name, options| | |
+ list = [] | |
+ padding = options.collect{ |o| o.aliases.size }.max.to_i * 4 | |
+ | |
+ options.each do |option| | |
+ item = [ option.usage(padding) ] | |
+ item.push(option.description ? "# #{option.description}" : "") | |
+ | |
+ list << item | |
+ list << [ "", "# Default: #{option.default}" ] if option.show_default? | |
+ end | |
+ | |
+ unless list.empty? | |
+ shell.say(group_name ? "#{group_name} options:" : "Options:") | |
+ shell.print_table(list, :ident => 2) | |
+ shell.say "" | |
+ end | |
+ end | |
+ | |
+ # Deal with default group | |
+ global_options = groups.delete(nil) || [] | |
+ printer.call(ungrouped_name, global_options) if global_options | |
+ | |
+ # Print all others | |
+ groups = extra_group.merge(groups) if extra_group | |
+ groups.each(&printer) | |
+ printer | |
+ end | |
+ | |
+ # Raises an error if the word given is a Thor reserved word. | |
+ # | |
+ def is_thor_reserved_word?(word, type) #:nodoc: | |
+ return false unless THOR_RESERVED_WORDS.include?(word.to_s) | |
+ raise "#{word.inspect} is a Thor reserved word and cannot be defined as #{type}" | |
+ end | |
+ | |
+ # Build an option and adds it to the given scope. | |
+ # | |
+ # ==== Parameters | |
+ # name<Symbol>:: The name of the argument. | |
+ # options<Hash>:: Described in both class_option and method_option. | |
+ # | |
+ def build_option(name, options, scope) #:nodoc: | |
+ scope[name] = Thor::Option.new(name, options[:desc], options[:required], | |
+ options[:type], options[:default], options[:banner], | |
+ options[:group], options[:aliases]) | |
+ end | |
+ | |
+ # Receives a hash of options, parse them and add to the scope. This is a | |
+ # fast way to set a bunch of options: | |
+ # | |
+ # build_options :foo => true, :bar => :required, :baz => :string | |
+ # | |
+ # ==== Parameters | |
+ # Hash[Symbol => Object] | |
+ # | |
+ def build_options(options, scope) #:nodoc: | |
+ options.each do |key, value| | |
+ scope[key] = Thor::Option.parse(key, value) | |
+ end | |
+ end | |
+ | |
+ # Finds a task with the given name. If the task belongs to the current | |
+ # class, just return it, otherwise dup it and add the fresh copy to the | |
+ # current task hash. | |
+ # | |
+ def find_and_refresh_task(name) #:nodoc: | |
+ task = if task = tasks[name.to_s] | |
+ task | |
+ elsif task = all_tasks[name.to_s] | |
+ tasks[name.to_s] = task.clone | |
+ else | |
+ raise ArgumentError, "You supplied :for => #{name.inspect}, but the task #{name.inspect} could not be found." | |
+ end | |
+ end | |
+ | |
+ # Everytime someone inherits from a Thor class, register the klass | |
+ # and file into baseclass. | |
+ # | |
+ def inherited(klass) | |
+ Thor::Base.register_klass_file(klass) | |
+ end | |
+ | |
+ # Fire this callback whenever a method is added. Added methods are | |
+ # tracked as tasks by invoking the create_task method. | |
+ # | |
+ def method_added(meth) | |
+ meth = meth.to_s | |
+ | |
+ if meth == "initialize" | |
+ initialize_added | |
+ return | |
+ end | |
+ | |
+ # Return if it's not a public instance method | |
+ return unless public_instance_methods.include?(meth) || | |
+ public_instance_methods.include?(meth.to_sym) | |
+ | |
+ return if @no_tasks || !create_task(meth) | |
+ | |
+ is_thor_reserved_word?(meth, :task) | |
+ Thor::Base.register_klass_file(self) | |
+ end | |
+ | |
+ # Retrieves a value from superclass. If it reaches the baseclass, | |
+ # returns default. | |
+ # | |
+ def from_superclass(method, default=nil) | |
+ if self == baseclass || !superclass.respond_to?(method, true) | |
+ default | |
+ else | |
+ value = superclass.send(method) | |
+ value.dup if value | |
+ end | |
+ end | |
+ | |
+ # A flag that makes the process exit with status 1 if any error happens. | |
+ # | |
+ def exit_on_failure? | |
+ false | |
+ end | |
+ | |
+ # SIGNATURE: Sets the baseclass. This is where the superclass lookup | |
+ # finishes. | |
+ def baseclass #:nodoc: | |
+ end | |
+ | |
+ # SIGNATURE: Creates a new task if valid_task? is true. This method is | |
+ # called when a new method is added to the class. | |
+ def create_task(meth) #:nodoc: | |
+ end | |
+ | |
+ # SIGNATURE: Defines behavior when the initialize method is added to the | |
+ # class. | |
+ def initialize_added #:nodoc: | |
+ end | |
+ end | |
+ end | |
+end | |
diff --git a/railties/lib/rails/vendor/thor-0.12.0/lib/thor/core_ext/hash_with_indifferent_access.rb b/railties/lib/rails/vendor/thor-0.12.0/lib/thor/core_ext/hash_with_indifferent_access.rb | |
new file mode 100644 | |
index 0000000..78bc5cf | |
--- /dev/null | |
+++ b/railties/lib/rails/vendor/thor-0.12.0/lib/thor/core_ext/hash_with_indifferent_access.rb | |
@@ -0,0 +1,75 @@ | |
+class Thor | |
+ module CoreExt #:nodoc: | |
+ | |
+ # A hash with indifferent access and magic predicates. | |
+ # | |
+ # hash = Thor::CoreExt::HashWithIndifferentAccess.new 'foo' => 'bar', 'baz' => 'bee', 'force' => true | |
+ # | |
+ # hash[:foo] #=> 'bar' | |
+ # hash['foo'] #=> 'bar' | |
+ # hash.foo? #=> true | |
+ # | |
+ class HashWithIndifferentAccess < ::Hash #:nodoc: | |
+ | |
+ def initialize(hash={}) | |
+ super() | |
+ hash.each do |key, value| | |
+ self[convert_key(key)] = value | |
+ end | |
+ end | |
+ | |
+ def [](key) | |
+ super(convert_key(key)) | |
+ end | |
+ | |
+ def []=(key, value) | |
+ super(convert_key(key), value) | |
+ end | |
+ | |
+ def delete(key) | |
+ super(convert_key(key)) | |
+ end | |
+ | |
+ def values_at(*indices) | |
+ indices.collect { |key| self[convert_key(key)] } | |
+ end | |
+ | |
+ def merge(other) | |
+ dup.merge!(other) | |
+ end | |
+ | |
+ def merge!(other) | |
+ other.each do |key, value| | |
+ self[convert_key(key)] = value | |
+ end | |
+ self | |
+ end | |
+ | |
+ protected | |
+ | |
+ def convert_key(key) | |
+ key.is_a?(Symbol) ? key.to_s : key | |
+ end | |
+ | |
+ # Magic predicates. For instance: | |
+ # | |
+ # options.force? # => !!options['force'] | |
+ # options.shebang # => "/usr/lib/local/ruby" | |
+ # options.test_framework?(:rspec) # => options[:test_framework] == :rspec | |
+ # | |
+ def method_missing(method, *args, &block) | |
+ method = method.to_s | |
+ if method =~ /^(\w+)\?$/ | |
+ if args.empty? | |
+ !!self[$1] | |
+ else | |
+ self[$1] == args.first | |
+ end | |
+ else | |
+ self[method] | |
+ end | |
+ end | |
+ | |
+ end | |
+ end | |
+end | |
diff --git a/railties/lib/rails/vendor/thor-0.12.0/lib/thor/core_ext/ordered_hash.rb b/railties/lib/rails/vendor/thor-0.12.0/lib/thor/core_ext/ordered_hash.rb | |
new file mode 100644 | |
index 0000000..27fea5b | |
--- /dev/null | |
+++ b/railties/lib/rails/vendor/thor-0.12.0/lib/thor/core_ext/ordered_hash.rb | |
@@ -0,0 +1,100 @@ | |
+class Thor | |
+ module CoreExt #:nodoc: | |
+ | |
+ if RUBY_VERSION >= '1.9' | |
+ class OrderedHash < ::Hash | |
+ end | |
+ else | |
+ # This class is based on the Ruby 1.9 ordered hashes. | |
+ # | |
+ # It keeps the semantics and most of the efficiency of normal hashes | |
+ # while also keeping track of the order in which elements were set. | |
+ # | |
+ class OrderedHash #:nodoc: | |
+ include Enumerable | |
+ | |
+ Node = Struct.new(:key, :value, :next, :prev) | |
+ | |
+ def initialize | |
+ @hash = {} | |
+ end | |
+ | |
+ def [](key) | |
+ @hash[key] && @hash[key].value | |
+ end | |
+ | |
+ def []=(key, value) | |
+ if node = @hash[key] | |
+ node.value = value | |
+ else | |
+ node = Node.new(key, value) | |
+ | |
+ if @first.nil? | |
+ @first = @last = node | |
+ else | |
+ node.prev = @last | |
+ @last.next = node | |
+ @last = node | |
+ end | |
+ end | |
+ | |
+ @hash[key] = node | |
+ value | |
+ end | |
+ | |
+ def delete(key) | |
+ if node = @hash[key] | |
+ prev_node = node.prev | |
+ next_node = node.next | |
+ | |
+ next_node.prev = prev_node if next_node | |
+ prev_node.next = next_node if prev_node | |
+ | |
+ @first = next_node if @first == node | |
+ @last = prev_node if @last == node | |
+ | |
+ value = node.value | |
+ end | |
+ | |
+ @hash.delete(key) | |
+ value | |
+ end | |
+ | |
+ def keys | |
+ self.map { |k, v| k } | |
+ end | |
+ | |
+ def values | |
+ self.map { |k, v| v } | |
+ end | |
+ | |
+ def each | |
+ return unless @first | |
+ yield [@first.key, @first.value] | |
+ node = @first | |
+ yield [node.key, node.value] while node = node.next | |
+ self | |
+ end | |
+ | |
+ def merge(other) | |
+ hash = self.class.new | |
+ | |
+ self.each do |key, value| | |
+ hash[key] = value | |
+ end | |
+ | |
+ other.each do |key, value| | |
+ hash[key] = value | |
+ end | |
+ | |
+ hash | |
+ end | |
+ | |
+ def empty? | |
+ @hash.empty? | |
+ end | |
+ end | |
+ end | |
+ | |
+ end | |
+end | |
diff --git a/railties/lib/rails/vendor/thor-0.12.0/lib/thor/error.rb b/railties/lib/rails/vendor/thor-0.12.0/lib/thor/error.rb | |
new file mode 100644 | |
index 0000000..f9b31a3 | |
--- /dev/null | |
+++ b/railties/lib/rails/vendor/thor-0.12.0/lib/thor/error.rb | |
@@ -0,0 +1,27 @@ | |
+class Thor | |
+ # Thor::Error is raised when it's caused by wrong usage of thor classes. Those | |
+ # errors have their backtrace supressed and are nicely shown to the user. | |
+ # | |
+ # Errors that are caused by the developer, like declaring a method which | |
+ # overwrites a thor keyword, it SHOULD NOT raise a Thor::Error. This way, we | |
+ # ensure that developer errors are shown with full backtrace. | |
+ # | |
+ class Error < StandardError | |
+ end | |
+ | |
+ # Raised when a task was not found. | |
+ # | |
+ class UndefinedTaskError < Error | |
+ end | |
+ | |
+ # Raised when a task was found, but not invoked properly. | |
+ # | |
+ class InvocationError < Error | |
+ end | |
+ | |
+ class RequiredArgumentMissingError < InvocationError | |
+ end | |
+ | |
+ class MalformattedArgumentError < InvocationError | |
+ end | |
+end | |
diff --git a/railties/lib/rails/vendor/thor-0.12.0/lib/thor/group.rb b/railties/lib/rails/vendor/thor-0.12.0/lib/thor/group.rb | |
new file mode 100644 | |
index 0000000..0964a96 | |
--- /dev/null | |
+++ b/railties/lib/rails/vendor/thor-0.12.0/lib/thor/group.rb | |
@@ -0,0 +1,263 @@ | |
+# Thor has a special class called Thor::Group. The main difference to Thor class | |
+# is that it invokes all tasks at once. It also include some methods that allows | |
+# invocations to be done at the class method, which are not available to Thor | |
+# tasks. | |
+# | |
+class Thor::Group | |
+ class << self | |
+ # The descrition for this Thor::Group. If none is provided, but a source root | |
+ # exists, tries to find the USAGE one folder above it, otherwise searches | |
+ # in the superclass. | |
+ # | |
+ # ==== Parameters | |
+ # description<String>:: The description for this Thor::Group. | |
+ # | |
+ def desc(description=nil) | |
+ case description | |
+ when nil | |
+ @desc ||= from_superclass(:desc, nil) | |
+ else | |
+ @desc = description | |
+ end | |
+ end | |
+ | |
+ # Start works differently in Thor::Group, it simply invokes all tasks | |
+ # inside the class. | |
+ # | |
+ def start(given_args=ARGV, config={}) | |
+ super do | |
+ if Thor::HELP_MAPPINGS.include?(given_args.first) | |
+ help(config[:shell]) | |
+ return | |
+ end | |
+ | |
+ args, opts = Thor::Options.split(given_args) | |
+ new(args, opts, config).invoke | |
+ end | |
+ end | |
+ | |
+ # Prints help information. | |
+ # | |
+ # ==== Options | |
+ # short:: When true, shows only usage. | |
+ # | |
+ def help(shell, options={}) | |
+ if options[:short] | |
+ shell.say banner | |
+ else | |
+ shell.say "Usage:" | |
+ shell.say " #{banner}" | |
+ shell.say | |
+ class_options_help(shell) | |
+ shell.say self.desc if self.desc | |
+ end | |
+ end | |
+ | |
+ # Stores invocations for this class merging with superclass values. | |
+ # | |
+ def invocations #:nodoc: | |
+ @invocations ||= from_superclass(:invocations, {}) | |
+ end | |
+ | |
+ # Stores invocation blocks used on invoke_from_option. | |
+ # | |
+ def invocation_blocks #:nodoc: | |
+ @invocation_blocks ||= from_superclass(:invocation_blocks, {}) | |
+ end | |
+ | |
+ # Invoke the given namespace or class given. It adds an instance | |
+ # method that will invoke the klass and task. You can give a block to | |
+ # configure how it will be invoked. | |
+ # | |
+ # The namespace/class given will have its options showed on the help | |
+ # usage. Check invoke_from_option for more information. | |
+ # | |
+ def invoke(*names, &block) | |
+ options = names.last.is_a?(Hash) ? names.pop : {} | |
+ verbose = options.fetch(:verbose, true) | |
+ | |
+ names.each do |name| | |
+ invocations[name] = false | |
+ invocation_blocks[name] = block if block_given? | |
+ | |
+ class_eval <<-METHOD, __FILE__, __LINE__ | |
+ def _invoke_#{name.to_s.gsub(/\W/, '_')} | |
+ klass, task = self.class.prepare_for_invocation(nil, #{name.inspect}) | |
+ | |
+ if klass | |
+ say_status :invoke, #{name.inspect}, #{verbose.inspect} | |
+ block = self.class.invocation_blocks[#{name.inspect}] | |
+ _invoke_for_class_method klass, task, &block | |
+ else | |
+ say_status :error, %(#{name.inspect} [not found]), :red | |
+ end | |
+ end | |
+ METHOD | |
+ end | |
+ end | |
+ | |
+ # Invoke a thor class based on the value supplied by the user to the | |
+ # given option named "name". A class option must be created before this | |
+ # method is invoked for each name given. | |
+ # | |
+ # ==== Examples | |
+ # | |
+ # class GemGenerator < Thor::Group | |
+ # class_option :test_framework, :type => :string | |
+ # invoke_from_option :test_framework | |
+ # end | |
+ # | |
+ # ==== Boolean options | |
+ # | |
+ # In some cases, you want to invoke a thor class if some option is true or | |
+ # false. This is automatically handled by invoke_from_option. Then the | |
+ # option name is used to invoke the generator. | |
+ # | |
+ # ==== Preparing for invocation | |
+ # | |
+ # In some cases you want to customize how a specified hook is going to be | |
+ # invoked. You can do that by overwriting the class method | |
+ # prepare_for_invocation. The class method must necessarily return a klass | |
+ # and an optional task. | |
+ # | |
+ # ==== Custom invocations | |
+ # | |
+ # You can also supply a block to customize how the option is giong to be | |
+ # invoked. The block receives two parameters, an instance of the current | |
+ # class and the klass to be invoked. | |
+ # | |
+ def invoke_from_option(*names, &block) | |
+ options = names.last.is_a?(Hash) ? names.pop : {} | |
+ verbose = options.fetch(:verbose, :white) | |
+ | |
+ names.each do |name| | |
+ unless class_options.key?(name) | |
+ raise ArgumentError, "You have to define the option #{name.inspect} " << | |
+ "before setting invoke_from_option." | |
+ end | |
+ | |
+ invocations[name] = true | |
+ invocation_blocks[name] = block if block_given? | |
+ | |
+ class_eval <<-METHOD, __FILE__, __LINE__ | |
+ def _invoke_from_option_#{name.to_s.gsub(/\W/, '_')} | |
+ return unless options[#{name.inspect}] | |
+ | |
+ value = options[#{name.inspect}] | |
+ value = #{name.inspect} if TrueClass === value | |
+ klass, task = self.class.prepare_for_invocation(#{name.inspect}, value) | |
+ | |
+ if klass | |
+ say_status :invoke, value, #{verbose.inspect} | |
+ block = self.class.invocation_blocks[#{name.inspect}] | |
+ _invoke_for_class_method klass, task, &block | |
+ else | |
+ say_status :error, %(\#{value} [not found]), :red | |
+ end | |
+ end | |
+ METHOD | |
+ end | |
+ end | |
+ | |
+ # Remove a previously added invocation. | |
+ # | |
+ # ==== Examples | |
+ # | |
+ # remove_invocation :test_framework | |
+ # | |
+ def remove_invocation(*names) | |
+ names.each do |name| | |
+ remove_task(name) | |
+ remove_class_option(name) | |
+ invocations.delete(name) | |
+ invocation_blocks.delete(name) | |
+ end | |
+ end | |
+ | |
+ # Overwrite class options help to allow invoked generators options to be | |
+ # shown recursively when invoking a generator. | |
+ # | |
+ def class_options_help(shell, ungrouped_name=nil, extra_group=nil) #:nodoc: | |
+ group_options = {} | |
+ | |
+ get_options_from_invocations(group_options, class_options) do |klass| | |
+ klass.send(:get_options_from_invocations, group_options, class_options) | |
+ end | |
+ | |
+ group_options.merge!(extra_group) if extra_group | |
+ super(shell, ungrouped_name, group_options) | |
+ end | |
+ | |
+ # Get invocations array and merge options from invocations. Those | |
+ # options are added to group_options hash. Options that already exists | |
+ # in base_options are not added twice. | |
+ # | |
+ def get_options_from_invocations(group_options, base_options) #:nodoc: | |
+ invocations.each do |name, from_option| | |
+ value = if from_option | |
+ option = class_options[name] | |
+ option.type == :boolean ? name : option.default | |
+ else | |
+ name | |
+ end | |
+ next unless value | |
+ | |
+ klass, task = prepare_for_invocation(name, value) | |
+ next unless klass && klass.respond_to?(:class_options) | |
+ | |
+ value = value.to_s | |
+ human_name = value.respond_to?(:classify) ? value.classify : value | |
+ | |
+ group_options[human_name] ||= [] | |
+ group_options[human_name] += klass.class_options.values.select do |option| | |
+ base_options[option.name.to_sym].nil? && option.group.nil? && | |
+ !group_options.values.flatten.any? { |i| i.name == option.name } | |
+ end | |
+ | |
+ yield klass if block_given? | |
+ end | |
+ end | |
+ | |
+ protected | |
+ | |
+ # The banner for this class. You can customize it if you are invoking the | |
+ # thor class by another ways which is not the Thor::Runner. | |
+ # | |
+ def banner | |
+ "#{self.namespace} #{self.arguments.map {|a| a.usage }.join(' ')}" | |
+ end | |
+ | |
+ def baseclass #:nodoc: | |
+ Thor::Group | |
+ end | |
+ | |
+ def create_task(meth) #:nodoc: | |
+ tasks[meth.to_s] = Thor::Task.new(meth, nil, nil, nil) | |
+ true | |
+ end | |
+ end | |
+ | |
+ include Thor::Base | |
+ | |
+ protected | |
+ | |
+ # Shortcut to invoke with padding and block handling. Use internally by | |
+ # invoke and invoke_from_option class methods. | |
+ # | |
+ def _invoke_for_class_method(klass, task=nil, *args, &block) #:nodoc: | |
+ shell.padding += 1 | |
+ | |
+ result = if block_given? | |
+ if block.arity == 2 | |
+ block.call(self, klass) | |
+ else | |
+ block.call(self, klass, task) | |
+ end | |
+ else | |
+ invoke klass, task, *args | |
+ end | |
+ | |
+ shell.padding -= 1 | |
+ result | |
+ end | |
+end | |
diff --git a/railties/lib/rails/vendor/thor-0.12.0/lib/thor/invocation.rb b/railties/lib/rails/vendor/thor-0.12.0/lib/thor/invocation.rb | |
new file mode 100644 | |
index 0000000..32e6a72 | |
--- /dev/null | |
+++ b/railties/lib/rails/vendor/thor-0.12.0/lib/thor/invocation.rb | |
@@ -0,0 +1,178 @@ | |
+class Thor | |
+ module Invocation | |
+ def self.included(base) #:nodoc: | |
+ base.extend ClassMethods | |
+ end | |
+ | |
+ module ClassMethods | |
+ # Prepare for class methods invocations. This method must return a klass to | |
+ # have the invoked class options showed in help messages in generators. | |
+ # | |
+ def prepare_for_invocation(key, name) #:nodoc: | |
+ case name | |
+ when Symbol, String | |
+ Thor::Util.namespace_to_thor_class_and_task(name.to_s, false) | |
+ else | |
+ name | |
+ end | |
+ end | |
+ end | |
+ | |
+ # Make initializer aware of invocations and the initializer proc. | |
+ # | |
+ def initialize(args=[], options={}, config={}, &block) #:nodoc: | |
+ @_invocations = config[:invocations] || Hash.new { |h,k| h[k] = [] } | |
+ @_initializer = [ args, options, config ] | |
+ super | |
+ end | |
+ | |
+ # Receives a name and invokes it. The name can be a string (either "task" or | |
+ # "namespace:task"), a Thor::Task, a Class or a Thor instance. If the task | |
+ # cannot be guessed by name, it can also be supplied as second argument. | |
+ # | |
+ # You can also supply the arguments, options and configuration values for | |
+ # the task to be invoked, if none is given, the same values used to | |
+ # initialize the invoker are used to initialize the invoked. | |
+ # | |
+ # ==== Examples | |
+ # | |
+ # class A < Thor | |
+ # def foo | |
+ # invoke :bar | |
+ # invoke "b:hello", ["José"] | |
+ # end | |
+ # | |
+ # def bar | |
+ # invoke "b:hello", ["José"] | |
+ # end | |
+ # end | |
+ # | |
+ # class B < Thor | |
+ # def hello(name) | |
+ # puts "hello #{name}" | |
+ # end | |
+ # end | |
+ # | |
+ # You can notice that the method "foo" above invokes two tasks: "bar", | |
+ # which belongs to the same class and "hello" which belongs to the class B. | |
+ # | |
+ # By using an invocation system you ensure that a task is invoked only once. | |
+ # In the example above, invoking "foo" will invoke "b:hello" just once, even | |
+ # if it's invoked later by "bar" method. | |
+ # | |
+ # When class A invokes class B, all arguments used on A initialization are | |
+ # supplied to B. This allows lazy parse of options. Let's suppose you have | |
+ # some rspec tasks: | |
+ # | |
+ # class Rspec < Thor::Group | |
+ # class_option :mock_framework, :type => :string, :default => :rr | |
+ # | |
+ # def invoke_mock_framework | |
+ # invoke "rspec:#{options[:mock_framework]}" | |
+ # end | |
+ # end | |
+ # | |
+ # As you noticed, it invokes the given mock framework, which might have its | |
+ # own options: | |
+ # | |
+ # class Rspec::RR < Thor::Group | |
+ # class_option :style, :type => :string, :default => :mock | |
+ # end | |
+ # | |
+ # Since it's not rspec concern to parse mock framework options, when RR | |
+ # is invoked all options are parsed again, so RR can extract only the options | |
+ # that it's going to use. | |
+ # | |
+ # If you want Rspec::RR to be initialized with its own set of options, you | |
+ # have to do that explicitely: | |
+ # | |
+ # invoke "rspec:rr", [], :style => :foo | |
+ # | |
+ # Besides giving an instance, you can also give a class to invoke: | |
+ # | |
+ # invoke Rspec::RR, [], :style => :foo | |
+ # | |
+ def invoke(name=nil, task=nil, args=nil, opts=nil, config=nil) | |
+ task, args, opts, config = nil, task, args, opts if task.nil? || task.is_a?(Array) | |
+ args, opts, config = nil, args, opts if args.is_a?(Hash) | |
+ | |
+ object, task = _prepare_for_invocation(name, task) | |
+ klass, instance = _initialize_klass_with_initializer(object, args, opts, config) | |
+ | |
+ method_args = [] | |
+ current = @_invocations[klass] | |
+ | |
+ iterator = proc do |_, task| | |
+ unless current.include?(task.name) | |
+ current << task.name | |
+ task.run(instance, method_args) | |
+ end | |
+ end | |
+ | |
+ if task | |
+ args ||= [] | |
+ method_args = args[Range.new(klass.arguments.size, -1)] || [] | |
+ iterator.call(nil, task) | |
+ else | |
+ klass.all_tasks.map(&iterator) | |
+ end | |
+ end | |
+ | |
+ protected | |
+ | |
+ # Configuration values that are shared between invocations. | |
+ # | |
+ def _shared_configuration #:nodoc: | |
+ { :invocations => @_invocations } | |
+ end | |
+ | |
+ # Prepare for invocation in the instance level. In this case, we have to | |
+ # take into account that a just a task name from the current class was | |
+ # given or even a Thor::Task object. | |
+ # | |
+ def _prepare_for_invocation(name, sent_task=nil) #:nodoc: | |
+ if name.is_a?(Thor::Task) | |
+ task = name | |
+ elsif task = self.class.all_tasks[name.to_s] | |
+ object = self | |
+ else | |
+ object, task = self.class.prepare_for_invocation(nil, name) | |
+ task ||= sent_task | |
+ end | |
+ | |
+ # If the object was not set, use self and use the name as task. | |
+ object, task = self, name unless object | |
+ return object, _validate_task(object, task) | |
+ end | |
+ | |
+ # Check if the object given is a Thor class object and get a task object | |
+ # for it. | |
+ # | |
+ def _validate_task(object, task) #:nodoc: | |
+ klass = object.is_a?(Class) ? object : object.class | |
+ raise "Expected Thor class, got #{klass}" unless klass <= Thor::Base | |
+ | |
+ task ||= klass.default_task if klass <= Thor | |
+ task = klass.all_tasks[task.to_s] || Thor::Task::Dynamic.new(task) if task && !task.is_a?(Thor::Task) | |
+ task | |
+ end | |
+ | |
+ # Initialize klass using values stored in the @_initializer. | |
+ # | |
+ def _initialize_klass_with_initializer(object, args, opts, config) #:nodoc: | |
+ if object.is_a?(Class) | |
+ klass = object | |
+ | |
+ stored_args, stored_opts, stored_config = @_initializer | |
+ args ||= stored_args.dup | |
+ opts ||= stored_opts.dup | |
+ | |
+ config ||= {} | |
+ config = stored_config.merge(_shared_configuration).merge!(config) | |
+ [ klass, klass.new(args, opts, config) ] | |
+ else | |
+ [ object.class, object ] | |
+ end | |
+ end | |
+ end | |
+end | |
diff --git a/railties/lib/rails/vendor/thor-0.12.0/lib/thor/parser.rb b/railties/lib/rails/vendor/thor-0.12.0/lib/thor/parser.rb | |
new file mode 100644 | |
index 0000000..57a3f6e | |
--- /dev/null | |
+++ b/railties/lib/rails/vendor/thor-0.12.0/lib/thor/parser.rb | |
@@ -0,0 +1,4 @@ | |
+require 'thor/parser/argument' | |
+require 'thor/parser/arguments' | |
+require 'thor/parser/option' | |
+require 'thor/parser/options' | |
diff --git a/railties/lib/rails/vendor/thor-0.12.0/lib/thor/parser/argument.rb b/railties/lib/rails/vendor/thor-0.12.0/lib/thor/parser/argument.rb | |
new file mode 100644 | |
index 0000000..aa8ace4 | |
--- /dev/null | |
+++ b/railties/lib/rails/vendor/thor-0.12.0/lib/thor/parser/argument.rb | |
@@ -0,0 +1,67 @@ | |
+class Thor | |
+ class Argument #:nodoc: | |
+ VALID_TYPES = [ :numeric, :hash, :array, :string ] | |
+ | |
+ attr_reader :name, :description, :required, :type, :default, :banner | |
+ alias :human_name :name | |
+ | |
+ def initialize(name, description=nil, required=true, type=:string, default=nil, banner=nil) | |
+ class_name = self.class.name.split("::").last | |
+ | |
+ raise ArgumentError, "#{class_name} name can't be nil." if name.nil? | |
+ raise ArgumentError, "Type :#{type} is not valid for #{class_name.downcase}s." if type && !valid_type?(type) | |
+ | |
+ @name = name.to_s | |
+ @description = description | |
+ @required = required || false | |
+ @type = (type || :string).to_sym | |
+ @default = default | |
+ @banner = banner || default_banner | |
+ | |
+ validate! # Trigger specific validations | |
+ end | |
+ | |
+ def usage | |
+ required? ? banner : "[#{banner}]" | |
+ end | |
+ | |
+ def required? | |
+ required | |
+ end | |
+ | |
+ def show_default? | |
+ case default | |
+ when Array, String, Hash | |
+ !default.empty? | |
+ else | |
+ default | |
+ end | |
+ end | |
+ | |
+ protected | |
+ | |
+ def validate! | |
+ raise ArgumentError, "An argument cannot be required and have default value." if required? && !default.nil? | |
+ end | |
+ | |
+ def valid_type?(type) | |
+ VALID_TYPES.include?(type.to_sym) | |
+ end | |
+ | |
+ def default_banner | |
+ case type | |
+ when :boolean | |
+ nil | |
+ when :string, :default | |
+ human_name.upcase | |
+ when :numeric | |
+ "N" | |
+ when :hash | |
+ "key:value" | |
+ when :array | |
+ "one two three" | |
+ end | |
+ end | |
+ | |
+ end | |
+end | |
diff --git a/railties/lib/rails/vendor/thor-0.12.0/lib/thor/parser/arguments.rb b/railties/lib/rails/vendor/thor-0.12.0/lib/thor/parser/arguments.rb | |
new file mode 100644 | |
index 0000000..fb5d965 | |
--- /dev/null | |
+++ b/railties/lib/rails/vendor/thor-0.12.0/lib/thor/parser/arguments.rb | |
@@ -0,0 +1,145 @@ | |
+class Thor | |
+ class Arguments #:nodoc: | |
+ NUMERIC = /(\d*\.\d+|\d+)/ | |
+ | |
+ # Receives an array of args and returns two arrays, one with arguments | |
+ # and one with switches. | |
+ # | |
+ def self.split(args) | |
+ arguments = [] | |
+ | |
+ args.each do |item| | |
+ break if item =~ /^-/ | |
+ arguments << item | |
+ end | |
+ | |
+ return arguments, args[Range.new(arguments.size, -1)] | |
+ end | |
+ | |
+ def self.parse(base, args) | |
+ new(base).parse(args) | |
+ end | |
+ | |
+ # Takes an array of Thor::Argument objects. | |
+ # | |
+ def initialize(arguments=[]) | |
+ @assigns, @non_assigned_required = {}, [] | |
+ @switches = arguments | |
+ | |
+ arguments.each do |argument| | |
+ if argument.default | |
+ @assigns[argument.human_name] = argument.default | |
+ elsif argument.required? | |
+ @non_assigned_required << argument | |
+ end | |
+ end | |
+ end | |
+ | |
+ def parse(args) | |
+ @pile = args.dup | |
+ | |
+ @switches.each do |argument| | |
+ break unless peek | |
+ @non_assigned_required.delete(argument) | |
+ @assigns[argument.human_name] = send(:"parse_#{argument.type}", argument.human_name) | |
+ end | |
+ | |
+ check_requirement! | |
+ @assigns | |
+ end | |
+ | |
+ private | |
+ | |
+ def peek | |
+ @pile.first | |
+ end | |
+ | |
+ def shift | |
+ @pile.shift | |
+ end | |
+ | |
+ def unshift(arg) | |
+ unless arg.kind_of?(Array) | |
+ @pile.unshift(arg) | |
+ else | |
+ @pile = arg + @pile | |
+ end | |
+ end | |
+ | |
+ def current_is_value? | |
+ peek && peek.to_s !~ /^-/ | |
+ end | |
+ | |
+ # Runs through the argument array getting strings that contains ":" and | |
+ # mark it as a hash: | |
+ # | |
+ # [ "name:string", "age:integer" ] | |
+ # | |
+ # Becomes: | |
+ # | |
+ # { "name" => "string", "age" => "integer" } | |
+ # | |
+ def parse_hash(name) | |
+ return shift if peek.is_a?(Hash) | |
+ hash = {} | |
+ | |
+ while current_is_value? && peek.include?(?:) | |
+ key, value = shift.split(':') | |
+ hash[key] = value | |
+ end | |
+ hash | |
+ end | |
+ | |
+ # Runs through the argument array getting all strings until no string is | |
+ # found or a switch is found. | |
+ # | |
+ # ["a", "b", "c"] | |
+ # | |
+ # And returns it as an array: | |
+ # | |
+ # ["a", "b", "c"] | |
+ # | |
+ def parse_array(name) | |
+ return shift if peek.is_a?(Array) | |
+ array = [] | |
+ | |
+ while current_is_value? | |
+ array << shift | |
+ end | |
+ array | |
+ end | |
+ | |
+ # Check if the peel is numeric ofrmat and return a Float or Integer. | |
+ # Otherwise raises an error. | |
+ # | |
+ def parse_numeric(name) | |
+ return shift if peek.is_a?(Numeric) | |
+ | |
+ unless peek =~ NUMERIC && $& == peek | |
+ raise MalformattedArgumentError, "expected numeric value for '#{name}'; got #{peek.inspect}" | |
+ end | |
+ | |
+ $&.index('.') ? shift.to_f : shift.to_i | |
+ end | |
+ | |
+ # Parse string, i.e., just return the current value in the pile. | |
+ # | |
+ def parse_string(name) | |
+ shift | |
+ end | |
+ | |
+ # Raises an error if @non_assigned_required array is not empty. | |
+ # | |
+ def check_requirement! | |
+ unless @non_assigned_required.empty? | |
+ names = @non_assigned_required.map do |o| | |
+ o.respond_to?(:switch_name) ? o.switch_name : o.human_name | |
+ end.join("', '") | |
+ | |
+ class_name = self.class.name.split('::').last.downcase | |
+ raise RequiredArgumentMissingError, "no value provided for required #{class_name} '#{names}'" | |
+ end | |
+ end | |
+ | |
+ end | |
+end | |
diff --git a/railties/lib/rails/vendor/thor-0.12.0/lib/thor/parser/option.rb b/railties/lib/rails/vendor/thor-0.12.0/lib/thor/parser/option.rb | |
new file mode 100644 | |
index 0000000..9e40ec7 | |
--- /dev/null | |
+++ b/railties/lib/rails/vendor/thor-0.12.0/lib/thor/parser/option.rb | |
@@ -0,0 +1,132 @@ | |
+class Thor | |
+ class Option < Argument #:nodoc: | |
+ attr_reader :aliases, :group | |
+ | |
+ VALID_TYPES = [:boolean, :numeric, :hash, :array, :string] | |
+ | |
+ def initialize(name, description=nil, required=nil, type=nil, default=nil, banner=nil, group=nil, aliases=nil) | |
+ super(name, description, required, type, default, banner) | |
+ @aliases = [*aliases].compact | |
+ @group = group.to_s.capitalize if group | |
+ end | |
+ | |
+ # This parse quick options given as method_options. It makes several | |
+ # assumptions, but you can be more specific using the option method. | |
+ # | |
+ # parse :foo => "bar" | |
+ # #=> Option foo with default value bar | |
+ # | |
+ # parse [:foo, :baz] => "bar" | |
+ # #=> Option foo with default value bar and alias :baz | |
+ # | |
+ # parse :foo => :required | |
+ # #=> Required option foo without default value | |
+ # | |
+ # parse :foo => 2 | |
+ # #=> Option foo with default value 2 and type numeric | |
+ # | |
+ # parse :foo => :numeric | |
+ # #=> Option foo without default value and type numeric | |
+ # | |
+ # parse :foo => true | |
+ # #=> Option foo with default value true and type boolean | |
+ # | |
+ # The valid types are :boolean, :numeric, :hash, :array and :string. If none | |
+ # is given a default type is assumed. This default type accepts arguments as | |
+ # string (--foo=value) or booleans (just --foo). | |
+ # | |
+ # By default all options are optional, unless :required is given. | |
+ # | |
+ def self.parse(key, value) | |
+ if key.is_a?(Array) | |
+ name, *aliases = key | |
+ else | |
+ name, aliases = key, [] | |
+ end | |
+ | |
+ name = name.to_s | |
+ default = value | |
+ | |
+ type = case value | |
+ when Symbol | |
+ default = nil | |
+ | |
+ if VALID_TYPES.include?(value) | |
+ value | |
+ elsif required = (value == :required) | |
+ :string | |
+ elsif value == :optional | |
+ # TODO Remove this warning in the future. | |
+ warn "Optional type is deprecated. Choose :boolean or :string instead. Assumed to be :boolean." | |
+ :boolean | |
+ end | |
+ when TrueClass, FalseClass | |
+ :boolean | |
+ when Numeric | |
+ :numeric | |
+ when Hash, Array, String | |
+ value.class.name.downcase.to_sym | |
+ end | |
+ | |
+ self.new(name.to_s, nil, required, type, default, nil, nil, aliases) | |
+ end | |
+ | |
+ def switch_name | |
+ @switch_name ||= dasherized? ? name : dasherize(name) | |
+ end | |
+ | |
+ def human_name | |
+ @human_name ||= dasherized? ? undasherize(name) : name | |
+ end | |
+ | |
+ def usage(padding=0) | |
+ sample = if banner && !banner.to_s.empty? | |
+ "#{switch_name}=#{banner}" | |
+ else | |
+ switch_name | |
+ end | |
+ | |
+ sample = "[#{sample}]" unless required? | |
+ | |
+ if aliases.empty? | |
+ (" " * padding) << sample | |
+ else | |
+ "#{aliases.join(', ')}, #{sample}" | |
+ end | |
+ end | |
+ | |
+ # Allow some type predicates as: boolean?, string? and etc. | |
+ # | |
+ def method_missing(method, *args, &block) | |
+ given = method.to_s.sub(/\?$/, '').to_sym | |
+ if valid_type?(given) | |
+ self.type == given | |
+ else | |
+ super | |
+ end | |
+ end | |
+ | |
+ protected | |
+ | |
+ def validate! | |
+ raise ArgumentError, "An option cannot be boolean and required." if boolean? && required? | |
+ end | |
+ | |
+ def valid_type?(type) | |
+ VALID_TYPES.include?(type.to_sym) | |
+ end | |
+ | |
+ def dasherized? | |
+ name.index('-') == 0 | |
+ end | |
+ | |
+ def undasherize(str) | |
+ str.sub(/^-{1,2}/, '') | |
+ end | |
+ | |
+ def dasherize(str) | |
+ (str.length > 1 ? "--" : "-") + str.gsub('_', '-') | |
+ end | |
+ | |
+ end | |
+end | |
diff --git a/railties/lib/rails/vendor/thor-0.12.0/lib/thor/parser/options.rb b/railties/lib/rails/vendor/thor-0.12.0/lib/thor/parser/options.rb | |
new file mode 100644 | |
index 0000000..7509230 | |
--- /dev/null | |
+++ b/railties/lib/rails/vendor/thor-0.12.0/lib/thor/parser/options.rb | |
@@ -0,0 +1,142 @@ | |
+class Thor | |
+ # This is a modified version of Daniel Berger's Getopt::Long class, licensed | |
+ # under Ruby's license. | |
+ # | |
+ class Options < Arguments #:nodoc: | |
+ LONG_RE = /^(--\w+[-\w+]*)$/ | |
+ SHORT_RE = /^(-[a-z])$/i | |
+ EQ_RE = /^(--\w+[-\w+]*|-[a-z])=(.*)$/i | |
+ SHORT_SQ_RE = /^-([a-z]{2,})$/i # Allow either -x -v or -xv style for single char args | |
+ SHORT_NUM = /^(-[a-z])#{NUMERIC}$/i | |
+ | |
+ # Receives a hash and makes it switches. | |
+ # | |
+ def self.to_switches(options) | |
+ options.map do |key, value| | |
+ case value | |
+ when true | |
+ "--#{key}" | |
+ when Array | |
+ "--#{key} #{value.map{ |v| v.inspect }.join(' ')}" | |
+ when Hash | |
+ "--#{key} #{value.map{ |k,v| "#{k}:#{v}" }.join(' ')}" | |
+ when nil, false | |
+ "" | |
+ else | |
+ "--#{key} #{value.inspect}" | |
+ end | |
+ end.join(" ") | |
+ end | |
+ | |
+ # Takes a hash of Thor::Option objects. | |
+ # | |
+ def initialize(options={}) | |
+ options = options.values | |
+ super(options) | |
+ @shorts, @switches = {}, {} | |
+ | |
+ options.each do |option| | |
+ @switches[option.switch_name] = option | |
+ | |
+ option.aliases.each do |short| | |
+ @shorts[short.to_s] ||= option.switch_name | |
+ end | |
+ end | |
+ end | |
+ | |
+ def parse(args) | |
+ @pile = args.dup | |
+ | |
+ while peek | |
+ if current_is_switch? | |
+ case shift | |
+ when SHORT_SQ_RE | |
+ unshift($1.split('').map { |f| "-#{f}" }) | |
+ next | |
+ when EQ_RE, SHORT_NUM | |
+ unshift($2) | |
+ switch = $1 | |
+ when LONG_RE, SHORT_RE | |
+ switch = $1 | |
+ end | |
+ | |
+ switch = normalize_switch(switch) | |
+ next unless option = switch_option(switch) | |
+ | |
+ @assigns[option.human_name] = parse_peek(switch, option) | |
+ else | |
+ shift | |
+ end | |
+ end | |
+ | |
+ check_requirement! | |
+ @assigns | |
+ end | |
+ | |
+ protected | |
+ | |
+ # Returns true if the current value in peek is a registered switch. | |
+ # | |
+ def current_is_switch? | |
+ case peek | |
+ when LONG_RE, SHORT_RE, EQ_RE, SHORT_NUM | |
+ switch?($1) | |
+ when SHORT_SQ_RE | |
+ $1.split('').any? { |f| switch?("-#{f}") } | |
+ end | |
+ end | |
+ | |
+ def switch?(arg) | |
+ switch_option(arg) || @shorts.key?(arg) | |
+ end | |
+ | |
+ def switch_option(arg) | |
+ if match = no_or_skip?(arg) | |
+ @switches[arg] || @switches["--#{match}"] | |
+ else | |
+ @switches[arg] | |
+ end | |
+ end | |
+ | |
+ def no_or_skip?(arg) | |
+ arg =~ /^--(no|skip)-([-\w]+)$/ | |
+ $2 | |
+ end | |
+ | |
+ # Check if the given argument is actually a shortcut. | |
+ # | |
+ def normalize_switch(arg) | |
+ @shorts.key?(arg) ? @shorts[arg] : arg | |
+ end | |
+ | |
+ # Parse boolean values which can be given as --foo=true, --foo or --no-foo. | |
+ # | |
+ def parse_boolean(switch) | |
+ if current_is_value? | |
+ ["true", "TRUE", "t", "T", true].include?(shift) | |
+ else | |
+ @switches.key?(switch) || !no_or_skip?(switch) | |
+ end | |
+ end | |
+ | |
+ # Parse the value at the peek analyzing if it requires an input or not. | |
+ # | |
+ def parse_peek(switch, option) | |
+ unless current_is_value? | |
+ if option.boolean? | |
+ # No problem for boolean types | |
+ elsif no_or_skip?(switch) | |
+ return nil # User set value to nil | |
+ elsif option.string? && !option.required? | |
+ return option.human_name # Return the option name | |
+ else | |
+ raise MalformattedArgumentError, "no value provided for option '#{switch}'" | |
+ end | |
+ end | |
+ | |
+ @non_assigned_required.delete(option) | |
+ send(:"parse_#{option.type}", switch) | |
+ end | |
+ | |
+ end | |
+end | |
diff --git a/railties/lib/rails/vendor/thor-0.12.0/lib/thor/rake_compat.rb b/railties/lib/rails/vendor/thor-0.12.0/lib/thor/rake_compat.rb | |
new file mode 100644 | |
index 0000000..0d0757f | |
--- /dev/null | |
+++ b/railties/lib/rails/vendor/thor-0.12.0/lib/thor/rake_compat.rb | |
@@ -0,0 +1,66 @@ | |
+require 'rake' | |
+ | |
+class Thor | |
+ # Adds a compatibility layer to your Thor classes which allows you to use | |
+ # rake package tasks. For example, to use rspec rake tasks, one can do: | |
+ # | |
+ # require 'thor/rake_compat' | |
+ # | |
+ # class Default < Thor | |
+ # include Thor::RakeCompat | |
+ # | |
+ # Spec::Rake::SpecTask.new(:spec) do |t| | |
+ # t.spec_opts = ['--options', "spec/spec.opts"] | |
+ # t.spec_files = FileList['spec/**/*_spec.rb'] | |
+ # end | |
+ # end | |
+ # | |
+ module RakeCompat | |
+ def self.rake_classes | |
+ @rake_classes ||= [] | |
+ end | |
+ | |
+ def self.included(base) | |
+ # Hack. Make rakefile point to invoker, so rdoc task is generated properly. | |
+ rakefile = File.basename(caller[0].match(/(.*):\d+/)[1]) | |
+ Rake.application.instance_variable_set(:@rakefile, rakefile) | |
+ self.rake_classes << base | |
+ end | |
+ end | |
+end | |
+ | |
+class Object #:nodoc: | |
+ alias :rake_task :task | |
+ alias :rake_namespace :namespace | |
+ | |
+ def task(*args, &block) | |
+ task = rake_task(*args, &block) | |
+ | |
+ if klass = Thor::RakeCompat.rake_classes.last | |
+ non_namespaced_name = task.name.split(':').last | |
+ | |
+ description = non_namespaced_name | |
+ description << task.arg_names.map{ |n| n.to_s.upcase }.join(' ') | |
+ description.strip! | |
+ | |
+ klass.desc description, task.comment || non_namespaced_name | |
+ klass.send :define_method, non_namespaced_name do |*args| | |
+ Rake::Task[task.name.to_sym].invoke(*args) | |
+ end | |
+ end | |
+ | |
+ task | |
+ end | |
+ | |
+ def namespace(name, &block) | |
+ if klass = Thor::RakeCompat.rake_classes.last | |
+ const_name = Thor::Util.camel_case(name.to_s).to_sym | |
+ klass.const_set(const_name, Class.new(Thor)) | |
+ new_klass = klass.const_get(const_name) | |
+ Thor::RakeCompat.rake_classes << new_klass | |
+ end | |
+ | |
+ rake_namespace(name, &block) | |
+ Thor::RakeCompat.rake_classes.pop | |
+ end | |
+end | |
diff --git a/railties/lib/rails/vendor/thor-0.12.0/lib/thor/runner.rb b/railties/lib/rails/vendor/thor-0.12.0/lib/thor/runner.rb | |
new file mode 100644 | |
index 0000000..9dc70ea | |
--- /dev/null | |
+++ b/railties/lib/rails/vendor/thor-0.12.0/lib/thor/runner.rb | |
@@ -0,0 +1,299 @@ | |
+require 'fileutils' | |
+require 'open-uri' | |
+require 'yaml' | |
+require 'digest/md5' | |
+require 'pathname' | |
+ | |
+class Thor::Runner < Thor #:nodoc: | |
+ map "-T" => :list, "-i" => :install, "-u" => :update | |
+ | |
+ # Override Thor#help so it can give information about any class and any method. | |
+ # | |
+ def help(meth=nil) | |
+ if meth && !self.respond_to?(meth) | |
+ initialize_thorfiles(meth) | |
+ klass, task = Thor::Util.namespace_to_thor_class_and_task(meth) | |
+ # Send mapping -h because it works with Thor::Group too | |
+ klass.start(["-h", task].compact, :shell => self.shell) | |
+ else | |
+ super | |
+ end | |
+ end | |
+ | |
+ # If a task is not found on Thor::Runner, method missing is invoked and | |
+ # Thor::Runner is then responsable for finding the task in all classes. | |
+ # | |
+ def method_missing(meth, *args) | |
+ meth = meth.to_s | |
+ initialize_thorfiles(meth) | |
+ klass, task = Thor::Util.namespace_to_thor_class_and_task(meth) | |
+ args.unshift(task) if task | |
+ klass.start(args, :shell => shell) | |
+ end | |
+ | |
+ desc "install NAME", "Install an optionally named Thor file into your system tasks" | |
+ method_options :as => :string, :relative => :boolean | |
+ def install(name) | |
+ initialize_thorfiles | |
+ | |
+ # If a directory name is provided as the argument, look for a 'main.thor' | |
+ # task in said directory. | |
+ begin | |
+ if File.directory?(File.expand_path(name)) | |
+ base, package = File.join(name, "main.thor"), :directory | |
+ contents = open(base).read | |
+ else | |
+ base, package = name, :file | |
+ contents = open(name).read | |
+ end | |
+ rescue OpenURI::HTTPError | |
+ raise Error, "Error opening URI '#{name}'" | |
+ rescue Errno::ENOENT | |
+ raise Error, "Error opening file '#{name}'" | |
+ end | |
+ | |
+ say "Your Thorfile contains:" | |
+ say contents | |
+ | |
+ return false if no?("Do you wish to continue [y/N]?") | |
+ | |
+ as = options["as"] || begin | |
+ first_line = contents.split("\n")[0] | |
+ (match = first_line.match(/\s*#\s*module:\s*([^\n]*)/)) ? match[1].strip : nil | |
+ end | |
+ | |
+ unless as | |
+ basename = File.basename(name) | |
+ as = ask("Please specify a name for #{name} in the system repository [#{basename}]:") | |
+ as = basename if as.empty? | |
+ end | |
+ | |
+ location = if options[:relative] || name =~ /^http:\/\// | |
+ name | |
+ else | |
+ File.expand_path(name) | |
+ end | |
+ | |
+ thor_yaml[as] = { | |
+ :filename => Digest::MD5.hexdigest(name + as), | |
+ :location => location, | |
+ :namespaces => Thor::Util.namespaces_in_content(contents, base) | |
+ } | |
+ | |
+ save_yaml(thor_yaml) | |
+ say "Storing thor file in your system repository" | |
+ destination = File.join(thor_root, thor_yaml[as][:filename]) | |
+ | |
+ if package == :file | |
+ File.open(destination, "w") { |f| f.puts contents } | |
+ else | |
+ FileUtils.cp_r(name, destination) | |
+ end | |
+ | |
+ thor_yaml[as][:filename] # Indicate success | |
+ end | |
+ | |
+ desc "uninstall NAME", "Uninstall a named Thor module" | |
+ def uninstall(name) | |
+ raise Error, "Can't find module '#{name}'" unless thor_yaml[name] | |
+ say "Uninstalling #{name}." | |
+ FileUtils.rm_rf(File.join(thor_root, "#{thor_yaml[name][:filename]}")) | |
+ | |
+ thor_yaml.delete(name) | |
+ save_yaml(thor_yaml) | |
+ | |
+ puts "Done." | |
+ end | |
+ | |
+ desc "update NAME", "Update a Thor file from its original location" | |
+ def update(name) | |
+ raise Error, "Can't find module '#{name}'" if !thor_yaml[name] || !thor_yaml[name][:location] | |
+ | |
+ say "Updating '#{name}' from #{thor_yaml[name][:location]}" | |
+ | |
+ old_filename = thor_yaml[name][:filename] | |
+ self.options = self.options.merge("as" => name) | |
+ filename = install(thor_yaml[name][:location]) | |
+ | |
+ unless filename == old_filename | |
+ File.delete(File.join(thor_root, old_filename)) | |
+ end | |
+ end | |
+ | |
+ desc "installed", "List the installed Thor modules and tasks" | |
+ method_options :internal => :boolean | |
+ def installed | |
+ initialize_thorfiles(nil, true) | |
+ | |
+ klasses = Thor::Base.subclasses | |
+ klasses -= [Thor, Thor::Runner] unless options["internal"] | |
+ | |
+ display_klasses(true, klasses) | |
+ end | |
+ | |
+ desc "list [SEARCH]", "List the available thor tasks (--substring means .*SEARCH)" | |
+ method_options :substring => :boolean, :group => :string, :all => :boolean | |
+ def list(search="") | |
+ initialize_thorfiles | |
+ | |
+ search = ".*#{search}" if options["substring"] | |
+ search = /^#{search}.*/i | |
+ group = options[:group] || "standard" | |
+ | |
+ klasses = Thor::Base.subclasses.select do |k| | |
+ (options[:all] || k.group == group) && k.namespace =~ search | |
+ end | |
+ | |
+ display_klasses(false, klasses) | |
+ end | |
+ | |
+ private | |
+ | |
+ def thor_root | |
+ Thor::Util.thor_root | |
+ end | |
+ | |
+ def thor_yaml | |
+ @thor_yaml ||= begin | |
+ yaml_file = File.join(thor_root, "thor.yml") | |
+ yaml = YAML.load_file(yaml_file) if File.exists?(yaml_file) | |
+ yaml || {} | |
+ end | |
+ end | |
+ | |
+ # Save the yaml file. If none exists in thor root, creates one. | |
+ # | |
+ def save_yaml(yaml) | |
+ yaml_file = File.join(thor_root, "thor.yml") | |
+ | |
+ unless File.exists?(yaml_file) | |
+ FileUtils.mkdir_p(thor_root) | |
+ yaml_file = File.join(thor_root, "thor.yml") | |
+ FileUtils.touch(yaml_file) | |
+ end | |
+ | |
+ File.open(yaml_file, "w") { |f| f.puts yaml.to_yaml } | |
+ end | |
+ | |
+ def self.exit_on_failure? | |
+ true | |
+ end | |
+ | |
+ # Load the thorfiles. If relevant_to is supplied, looks for specific files | |
+ # in the thor_root instead of loading them all. | |
+ # | |
+ # By default, it also traverses the current path until find Thor files, as | |
+ # described in thorfiles. This look up can be skipped by suppliying | |
+ # skip_lookup true. | |
+ # | |
+ def initialize_thorfiles(relevant_to=nil, skip_lookup=false) | |
+ thorfiles(relevant_to, skip_lookup).each do |f| | |
+ Thor::Util.load_thorfile(f) unless Thor::Base.subclass_files.keys.include?(File.expand_path(f)) | |
+ end | |
+ end | |
+ | |
+ # Finds Thorfiles by traversing from your current directory down to the root | |
+ # directory of your system. If at any time we find a Thor file, we stop. | |
+ # | |
+ # We also ensure that system-wide Thorfiles are loaded first, so local | |
+ # Thorfiles can override them. | |
+ # | |
+ # ==== Example | |
+ # | |
+ # If we start at /Users/wycats/dev/thor ... | |
+ # | |
+ # 1. /Users/wycats/dev/thor | |
+ # 2. /Users/wycats/dev | |
+ # 3. /Users/wycats <-- we find a Thorfile here, so we stop | |
+ # | |
+ # Suppose we start at c:\Documents and Settings\james\dev\thor ... | |
+ # | |
+ # 1. c:\Documents and Settings\james\dev\thor | |
+ # 2. c:\Documents and Settings\james\dev | |
+ # 3. c:\Documents and Settings\james | |
+ # 4. c:\Documents and Settings | |
+ # 5. c:\ <-- no Thorfiles found! | |
+ # | |
+ def thorfiles(relevant_to=nil, skip_lookup=false) | |
+ # TODO Remove this dealing with deprecated thor when :namespaces: is available as constants | |
+ save_yaml(thor_yaml) if Thor::Util.convert_constants_to_namespaces(thor_yaml) | |
+ | |
+ thorfiles = [] | |
+ | |
+ unless skip_lookup | |
+ Pathname.pwd.ascend do |path| | |
+ thorfiles = Thor::Util.globs_for(path).map { |g| Dir[g] }.flatten | |
+ break unless thorfiles.empty? | |
+ end | |
+ end | |
+ | |
+ files = (relevant_to ? thorfiles_relevant_to(relevant_to) : Thor::Util.thor_root_glob) | |
+ files += thorfiles | |
+ files -= ["#{thor_root}/thor.yml"] | |
+ | |
+ files.map! do |file| | |
+ File.directory?(file) ? File.join(file, "main.thor") : file | |
+ end | |
+ end | |
+ | |
+ # Load thorfiles relevant to the given method. If you provide "foo:bar" it | |
+ # will load all thor files in the thor.yaml that has "foo" e "foo:bar" | |
+ # namespaces registered. | |
+ # | |
+ def thorfiles_relevant_to(meth) | |
+ lookup = [ meth, meth.split(":")[0...-1].join(":") ] | |
+ | |
+ files = thor_yaml.select do |k, v| | |
+ v[:namespaces] && !(v[:namespaces] & lookup).empty? | |
+ end | |
+ | |
+ files.map { |k, v| File.join(thor_root, "#{v[:filename]}") } | |
+ end | |
+ | |
+ # Display information about the given klasses. If with_module is given, | |
+ # it shows a table with information extracted from the yaml file. | |
+ # | |
+ def display_klasses(with_modules=false, klasses=Thor.subclasses) | |
+ klasses -= [Thor, Thor::Runner] unless with_modules | |
+ raise Error, "No Thor tasks available" if klasses.empty? | |
+ | |
+ if with_modules && !thor_yaml.empty? | |
+ info = [] | |
+ labels = ["Modules", "Namespaces"] | |
+ | |
+ info << labels | |
+ info << [ "-" * labels[0].size, "-" * labels[1].size ] | |
+ | |
+ thor_yaml.each do |name, hash| | |
+ info << [ name, hash[:namespaces].join(", ") ] | |
+ end | |
+ | |
+ print_table info | |
+ say "" | |
+ end | |
+ | |
+ unless klasses.empty? | |
+ klasses.dup.each do |klass| | |
+ klasses -= Thor::Util.thor_classes_in(klass) | |
+ end | |
+ | |
+ klasses.each { |k| display_tasks(k) } | |
+ else | |
+ say "\033[1;34mNo Thor tasks available\033[0m" | |
+ end | |
+ end | |
+ | |
+ # Display tasks from the given Thor class. | |
+ # | |
+ def display_tasks(klass) | |
+ unless klass.tasks.empty? | |
+ base = klass.namespace | |
+ | |
+ color = base == "default" ? :magenta : :blue | |
+ say shell.set_color(base, color, true) | |
+ say "-" * base.length | |
+ | |
+ klass.help(shell, :short => true, :ident => 0, :namespace => true) | |
+ end | |
+ end | |
+end | |
diff --git a/railties/lib/rails/vendor/thor-0.12.0/lib/thor/shell.rb b/railties/lib/rails/vendor/thor-0.12.0/lib/thor/shell.rb | |
new file mode 100644 | |
index 0000000..1dc8f0e | |
--- /dev/null | |
+++ b/railties/lib/rails/vendor/thor-0.12.0/lib/thor/shell.rb | |
@@ -0,0 +1,78 @@ | |
+require 'rbconfig' | |
+require 'thor/shell/color' | |
+ | |
+class Thor | |
+ module Base | |
+ # Returns the shell used in all Thor classes. If you are in a Unix platform | |
+ # it will use a colored log, otherwise it will use a basic one without color. | |
+ # | |
+ def self.shell | |
+ @shell ||= if Config::CONFIG['host_os'] =~ /mswin|mingw/ | |
+ Thor::Shell::Basic | |
+ else | |
+ Thor::Shell::Color | |
+ end | |
+ end | |
+ | |
+ # Sets the shell used in all Thor classes. | |
+ # | |
+ def self.shell=(klass) | |
+ @shell = klass | |
+ end | |
+ end | |
+ | |
+ module Shell | |
+ SHELL_DELEGATED_METHODS = [:ask, :yes?, :no?, :say, :say_status, :print_list, :print_table] | |
+ | |
+ # Add shell to initialize config values. | |
+ # | |
+ # ==== Configuration | |
+ # shell<Object>:: An instance of the shell to be used. | |
+ # | |
+ # ==== Examples | |
+ # | |
+ # class MyScript < Thor | |
+ # argument :first, :type => :numeric | |
+ # end | |
+ # | |
+ # MyScript.new [1.0], { :foo => :bar }, :shell => Thor::Shell::Basic.new | |
+ # | |
+ def initialize(args=[], options={}, config={}) | |
+ super | |
+ self.shell = config[:shell] | |
+ self.shell.base ||= self if self.shell.respond_to?(:base) | |
+ end | |
+ | |
+ # Holds the shell for the given Thor instance. If no shell is given, | |
+ # it gets a default shell from Thor::Base.shell. | |
+ # | |
+ def shell | |
+ @shell ||= Thor::Base.shell.new | |
+ end | |
+ | |
+ # Sets the shell for this thor class. | |
+ # | |
+ def shell=(shell) | |
+ @shell = shell | |
+ end | |
+ | |
+ # Common methods that are delegated to the shell. | |
+ # | |
+ SHELL_DELEGATED_METHODS.each do |method| | |
+ module_eval <<-METHOD, __FILE__, __LINE__ | |
+ def #{method}(*args) | |
+ shell.#{method}(*args) | |
+ end | |
+ METHOD | |
+ end | |
+ | |
+ protected | |
+ | |
+ # Allow shell to be shared between invocations. | |
+ # | |
+ def _shared_configuration #:nodoc: | |
+ super.merge!(:shell => self.shell) | |
+ end | |
+ | |
+ end | |
+end | |
diff --git a/railties/lib/rails/vendor/thor-0.12.0/lib/thor/shell/basic.rb b/railties/lib/rails/vendor/thor-0.12.0/lib/thor/shell/basic.rb | |
new file mode 100644 | |
index 0000000..ea96653 | |
--- /dev/null | |
+++ b/railties/lib/rails/vendor/thor-0.12.0/lib/thor/shell/basic.rb | |
@@ -0,0 +1,219 @@ | |
+require 'tempfile' | |
+ | |
+class Thor | |
+ module Shell | |
+ class Basic | |
+ attr_accessor :base, :padding | |
+ | |
+ # Initialize base and padding to nil. | |
+ # | |
+ def initialize #:nodoc: | |
+ @base, @padding = nil, 0 | |
+ end | |
+ | |
+ # Sets the output padding, not allowing less than zero values. | |
+ # | |
+ def padding=(value) | |
+ @padding = [0, value].max | |
+ end | |
+ | |
+ # Ask something to the user and receives a response. | |
+ # | |
+ # ==== Example | |
+ # ask("What is your name?") | |
+ # | |
+ def ask(statement, color=nil) | |
+ say("#{statement} ", color) | |
+ $stdin.gets.strip | |
+ end | |
+ | |
+ # Say (print) something to the user. If the sentence ends with a whitespace | |
+ # or tab character, a new line is not appended (print + flush). Otherwise | |
+ # are passed straight to puts (behavior got from Highline). | |
+ # | |
+ # ==== Example | |
+ # say("I know you knew that.") | |
+ # | |
+ def say(message="", color=nil, force_new_line=(message.to_s !~ /( |\t)$/)) | |
+ message = message.to_s | |
+ message = set_color(message, color) if color | |
+ | |
+ if force_new_line | |
+ $stdout.puts(message) | |
+ else | |
+ $stdout.print(message) | |
+ $stdout.flush | |
+ end | |
+ end | |
+ | |
+ # Say a status with the given color and appends the message. Since this | |
+ # method is used frequently by actions, it allows nil or false to be given | |
+ # in log_status, avoiding the message from being shown. If a Symbol is | |
+ # given in log_status, it's used as the color. | |
+ # | |
+ def say_status(status, message, log_status=true) | |
+ return if quiet? || log_status == false | |
+ spaces = " " * (padding + 1) | |
+ color = log_status.is_a?(Symbol) ? log_status : :green | |
+ | |
+ status = status.to_s.rjust(12) | |
+ status = set_color status, color, true if color | |
+ say "#{status}#{spaces}#{message}", nil, true | |
+ end | |
+ | |
+ # Make a question the to user and returns true if the user replies "y" or | |
+ # "yes". | |
+ # | |
+ def yes?(statement, color=nil) | |
+ ask(statement, color) =~ is?(:yes) | |
+ end | |
+ | |
+ # Make a question the to user and returns true if the user replies "n" or | |
+ # "no". | |
+ # | |
+ def no?(statement, color=nil) | |
+ !yes?(statement, color) | |
+ end | |
+ | |
+ # Prints a list of items. | |
+ # | |
+ # ==== Parameters | |
+ # list<Array[String, String, ...]> | |
+ # | |
+ # ==== Options | |
+ # mode:: Can be :rows or :inline. Defaults to :rows. | |
+ # ident:: Ident each item with the value given. | |
+ # | |
+ def print_list(list, options={}) | |
+ return if list.empty? | |
+ | |
+ ident = " " * (options[:ident] || 0) | |
+ content = case options[:mode] | |
+ when :inline | |
+ last = list.pop | |
+ "#{list.join(", ")}, and #{last}" | |
+ else # rows | |
+ ident + list.join("\n#{ident}") | |
+ end | |
+ | |
+ $stdout.puts content | |
+ end | |
+ | |
+ # Prints a table. | |
+ # | |
+ # ==== Parameters | |
+ # Array[Array[String, String, ...]] | |
+ # | |
+ # ==== Options | |
+ # ident<Integer>:: Ident the first column by ident value. | |
+ # | |
+ def print_table(table, options={}) | |
+ return if table.empty? | |
+ | |
+ formats = [] | |
+ 0.upto(table.first.length - 2) do |i| | |
+ maxima = table.max{ |a,b| a[i].size <=> b[i].size }[i].size | |
+ formats << "%-#{maxima + 2}s" | |
+ end | |
+ | |
+ formats[0] = formats[0].insert(0, " " * options[:ident]) if options[:ident] | |
+ formats << "%s" | |
+ | |
+ table.each do |row| | |
+ row.each_with_index do |column, i| | |
+ $stdout.print formats[i] % column.to_s | |
+ end | |
+ $stdout.puts | |
+ end | |
+ end | |
+ | |
+ # Deals with file collision and returns true if the file should be | |
+ # overwriten and false otherwise. If a block is given, it uses the block | |
+ # response as the content for the diff. | |
+ # | |
+ # ==== Parameters | |
+ # destination<String>:: the destination file to solve conflicts | |
+ # block<Proc>:: an optional block that returns the value to be used in diff | |
+ # | |
+ def file_collision(destination) | |
+ return true if @always_force | |
+ options = block_given? ? "[Ynaqdh]" : "[Ynaqh]" | |
+ | |
+ while true | |
+ answer = ask %[Overwrite #{destination}? (enter "h" for help) #{options}] | |
+ | |
+ case answer | |
+ when is?(:yes), is?(:force) | |
+ return true | |
+ when is?(:no), is?(:skip) | |
+ return false | |
+ when is?(:always) | |
+ return @always_force = true | |
+ when is?(:quit) | |
+ say 'Aborting...' | |
+ raise SystemExit | |
+ when is?(:diff) | |
+ show_diff(destination, yield) if block_given? | |
+ say 'Retrying...' | |
+ else | |
+ say file_collision_help | |
+ end | |
+ end | |
+ end | |
+ | |
+ # Called if something goes wrong during the execution. This is used by Thor | |
+ # internally and should not be used inside your scripts. If someone went | |
+ # wrong, you can always raise an exception. If you raise a Thor::Error, it | |
+ # will be rescued and wrapped in the method below. | |
+ # | |
+ def error(statement) | |
+ $stderr.puts statement | |
+ end | |
+ | |
+ # Apply color to the given string with optional bold. Disabled in the | |
+ # Thor::Shell::Basic class. | |
+ # | |
+ def set_color(string, color, bold=false) #:nodoc: | |
+ string | |
+ end | |
+ | |
+ protected | |
+ | |
+ def is?(value) #:nodoc: | |
+ value = value.to_s | |
+ | |
+ if value.size == 1 | |
+ /\A#{value}\z/i | |
+ else | |
+ /\A(#{value}|#{value[0,1]})\z/i | |
+ end | |
+ end | |
+ | |
+ def file_collision_help #:nodoc: | |
+<<HELP | |
+Y - yes, overwrite | |
+n - no, do not overwrite | |
+a - all, overwrite this and all others | |
+q - quit, abort | |
+d - diff, show the differences between the old and the new | |
+h - help, show this help | |
+HELP | |
+ end | |
+ | |
+ def show_diff(destination, content) #:nodoc: | |
+ diff_cmd = ENV['THOR_DIFF'] || ENV['RAILS_DIFF'] || 'diff -u' | |
+ | |
+ Tempfile.open(File.basename(destination), File.dirname(destination)) do |temp| | |
+ temp.write content | |
+ temp.rewind | |
+ system %(#{diff_cmd} "#{destination}" "#{temp.path}") | |
+ end | |
+ end | |
+ | |
+ def quiet? #:nodoc: | |
+ base && base.options[:quiet] | |
+ end | |
+ | |
+ end | |
+ end | |
+end | |
diff --git a/railties/lib/rails/vendor/thor-0.12.0/lib/thor/shell/color.rb b/railties/lib/rails/vendor/thor-0.12.0/lib/thor/shell/color.rb | |
new file mode 100644 | |
index 0000000..24704f7 | |
--- /dev/null | |
+++ b/railties/lib/rails/vendor/thor-0.12.0/lib/thor/shell/color.rb | |
@@ -0,0 +1,108 @@ | |
+require 'thor/shell/basic' | |
+ | |
+class Thor | |
+ module Shell | |
+ # Inherit from Thor::Shell::Basic and add set_color behavior. Check | |
+ # Thor::Shell::Basic to see all available methods. | |
+ # | |
+ class Color < Basic | |
+ # Embed in a String to clear all previous ANSI sequences. | |
+ CLEAR = "\e[0m" | |
+ # The start of an ANSI bold sequence. | |
+ BOLD = "\e[1m" | |
+ | |
+ # Set the terminal's foreground ANSI color to black. | |
+ BLACK = "\e[30m" | |
+ # Set the terminal's foreground ANSI color to red. | |
+ RED = "\e[31m" | |
+ # Set the terminal's foreground ANSI color to green. | |
+ GREEN = "\e[32m" | |
+ # Set the terminal's foreground ANSI color to yellow. | |
+ YELLOW = "\e[33m" | |
+ # Set the terminal's foreground ANSI color to blue. | |
+ BLUE = "\e[34m" | |
+ # Set the terminal's foreground ANSI color to magenta. | |
+ MAGENTA = "\e[35m" | |
+ # Set the terminal's foreground ANSI color to cyan. | |
+ CYAN = "\e[36m" | |
+ # Set the terminal's foreground ANSI color to white. | |
+ WHITE = "\e[37m" | |
+ | |
+ # Set the terminal's background ANSI color to black. | |
+ ON_BLACK = "\e[40m" | |
+ # Set the terminal's background ANSI color to red. | |
+ ON_RED = "\e[41m" | |
+ # Set the terminal's background ANSI color to green. | |
+ ON_GREEN = "\e[42m" | |
+ # Set the terminal's background ANSI color to yellow. | |
+ ON_YELLOW = "\e[43m" | |
+ # Set the terminal's background ANSI color to blue. | |
+ ON_BLUE = "\e[44m" | |
+ # Set the terminal's background ANSI color to magenta. | |
+ ON_MAGENTA = "\e[45m" | |
+ # Set the terminal's background ANSI color to cyan. | |
+ ON_CYAN = "\e[46m" | |
+ # Set the terminal's background ANSI color to white. | |
+ ON_WHITE = "\e[47m" | |
+ | |
+ # Set color by using a string or one of the defined constants. If a third | |
+ # option is set to true, it also adds bold to the string. This is based | |
+ # on Highline implementation and it automatically appends CLEAR to the end | |
+ # of the returned String. | |
+ # | |
+ def set_color(string, color, bold=false) | |
+ color = self.class.const_get(color.to_s.upcase) if color.is_a?(Symbol) | |
+ bold = bold ? BOLD : "" | |
+ "#{bold}#{color}#{string}#{CLEAR}" | |
+ end | |
+ | |
+ protected | |
+ | |
+ # Overwrite show_diff to show diff with colors if Diff::LCS is | |
+ # available. | |
+ # | |
+ def show_diff(destination, content) #:nodoc: | |
+ if diff_lcs_loaded? && ENV['THOR_DIFF'].nil? && ENV['RAILS_DIFF'].nil? | |
+ actual = File.read(destination).to_s.split("\n") | |
+ content = content.to_s.split("\n") | |
+ | |
+ Diff::LCS.sdiff(actual, content).each do |diff| | |
+ output_diff_line(diff) | |
+ end | |
+ else | |
+ super | |
+ end | |
+ end | |
+ | |
+ def output_diff_line(diff) #:nodoc: | |
+ case diff.action | |
+ when '-' | |
+ say "- #{diff.old_element.chomp}", :red, true | |
+ when '+' | |
+ say "+ #{diff.new_element.chomp}", :green, true | |
+ when '!' | |
+ say "- #{diff.old_element.chomp}", :red, true | |
+ say "+ #{diff.new_element.chomp}", :green, true | |
+ else | |
+ say " #{diff.old_element.chomp}", nil, true | |
+ end | |
+ end | |
+ | |
+ # Check if Diff::LCS is loaded. If it is, use it to create pretty output | |
+ # for diff. | |
+ # | |
+ def diff_lcs_loaded? #:nodoc: | |
+ return true if defined?(Diff::LCS) | |
+ return @diff_lcs_loaded unless @diff_lcs_loaded.nil? | |
+ | |
+ @diff_lcs_loaded = begin | |
+ require 'diff/lcs' | |
+ true | |
+ rescue LoadError | |
+ false | |
+ end | |
+ end | |
+ | |
+ end | |
+ end | |
+end | |
diff --git a/railties/lib/rails/vendor/thor-0.12.0/lib/thor/task.rb b/railties/lib/rails/vendor/thor-0.12.0/lib/thor/task.rb | |
new file mode 100644 | |
index 0000000..91c7564 | |
--- /dev/null | |
+++ b/railties/lib/rails/vendor/thor-0.12.0/lib/thor/task.rb | |
@@ -0,0 +1,122 @@ | |
+class Thor | |
+ class Task < Struct.new(:name, :description, :usage, :options) | |
+ | |
+ # A dynamic task that handles method missing scenarios. | |
+ # | |
+ class Dynamic < Task | |
+ def initialize(name) | |
+ super(name.to_s, "A dynamically-generated task", name.to_s) | |
+ end | |
+ | |
+ def run(instance, args=[]) | |
+ unless (instance.methods & [name.to_s, name.to_sym]).empty? | |
+ raise Error, "could not find Thor class or task '#{name}'" | |
+ end | |
+ super | |
+ end | |
+ end | |
+ | |
+ def initialize(name, description, usage, options=nil) | |
+ super(name.to_s, description, usage, options || {}) | |
+ end | |
+ | |
+ def initialize_copy(other) #:nodoc: | |
+ super(other) | |
+ self.options = other.options.dup if other.options | |
+ end | |
+ | |
+ def short_description | |
+ description.split("\n").first if description | |
+ end | |
+ | |
+ # By default, a task invokes a method in the thor class. You can change this | |
+ # implementation to create custom tasks. | |
+ # | |
+ def run(instance, args=[]) | |
+ raise UndefinedTaskError, "the '#{name}' task of #{instance.class} is private" unless public_method?(instance) | |
+ instance.send(name, *args) | |
+ rescue ArgumentError => e | |
+ parse_argument_error(instance, e, caller) | |
+ rescue NoMethodError => e | |
+ parse_no_method_error(instance, e) | |
+ end | |
+ | |
+ # Returns the formatted usage. If a class is given, the class arguments are | |
+ # injected in the usage. | |
+ # | |
+ def formatted_usage(klass=nil, namespace=false, show_options=true) | |
+ formatted = if namespace.is_a?(String) | |
+ "#{namespace}:" | |
+ elsif klass && namespace | |
+ "#{klass.namespace.gsub(/^default/,'')}:" | |
+ else | |
+ "" | |
+ end | |
+ | |
+ formatted << formatted_arguments(klass) | |
+ formatted << " #{formatted_options}" if show_options | |
+ formatted.strip! | |
+ formatted | |
+ end | |
+ | |
+ # Injects the class arguments into the task usage. | |
+ # | |
+ def formatted_arguments(klass) | |
+ if klass && !klass.arguments.empty? | |
+ usage.to_s.gsub(/^#{name}/) do |match| | |
+ match << " " << klass.arguments.map{ |a| a.usage }.join(' ') | |
+ end | |
+ else | |
+ usage.to_s | |
+ end | |
+ end | |
+ | |
+ # Returns the options usage for this task. | |
+ # | |
+ def formatted_options | |
+ @formatted_options ||= options.map{ |_, o| o.usage }.sort.join(" ") | |
+ end | |
+ | |
+ protected | |
+ | |
+ # Given a target, checks if this class name is not a private/protected method. | |
+ # | |
+ def public_method?(instance) #:nodoc: | |
+ collection = instance.private_methods + instance.protected_methods | |
+ (collection & [name.to_s, name.to_sym]).empty? | |
+ end | |
+ | |
+ # Clean everything that comes from the Thor gempath and remove the caller. | |
+ # | |
+ def sans_backtrace(backtrace, caller) #:nodoc: | |
+ dirname = /^#{Regexp.escape(File.dirname(__FILE__))}/ | |
+ saned = backtrace.reject { |frame| frame =~ dirname } | |
+ saned -= caller | |
+ end | |
+ | |
+ def parse_argument_error(instance, e, caller) #:nodoc: | |
+ backtrace = sans_backtrace(e.backtrace, caller) | |
+ | |
+ if backtrace.empty? && e.message =~ /wrong number of arguments/ | |
+ if instance.is_a?(Thor::Group) | |
+ raise e, "'#{name}' was called incorrectly. Are you sure it has arity equals to 0?" | |
+ else | |
+ raise InvocationError, "'#{name}' was called incorrectly. Call as " << | |
+ "'#{formatted_usage(instance.class, true)}'" | |
+ end | |
+ else | |
+ raise e | |
+ end | |
+ end | |
+ | |
+ def parse_no_method_error(instance, e) #:nodoc: | |
+ if e.message =~ /^undefined method `#{name}' for #{Regexp.escape(instance.to_s)}$/ | |
+ raise UndefinedTaskError, "The #{instance.class.namespace} namespace " << | |
+ "doesn't have a '#{name}' task" | |
+ else | |
+ raise e | |
+ end | |
+ end | |
+ | |
+ end | |
+end | |
diff --git a/railties/lib/rails/vendor/thor-0.12.0/lib/thor/util.rb b/railties/lib/rails/vendor/thor-0.12.0/lib/thor/util.rb | |
new file mode 100644 | |
index 0000000..ebae0a3 | |
--- /dev/null | |
+++ b/railties/lib/rails/vendor/thor-0.12.0/lib/thor/util.rb | |
@@ -0,0 +1,251 @@ | |
+require 'rbconfig' | |
+ | |
+class Thor | |
+ module Sandbox #:nodoc: | |
+ end | |
+ | |
+ # This module holds several utilities: | |
+ # | |
+ # 1) Methods to convert thor namespaces to constants and vice-versa. | |
+ # | |
+ # Thor::Utils.namespace_from_thor_class(Foo::Bar::Baz) #=> "foo:bar:baz" | |
+ # | |
+ # 2) Loading thor files and sandboxing: | |
+ # | |
+ # Thor::Utils.load_thorfile("~/.thor/foo") | |
+ # | |
+ module Util | |
+ | |
+ # Receives a namespace and search for it in the Thor::Base subclasses. | |
+ # | |
+ # ==== Parameters | |
+ # namespace<String>:: The namespace to search for. | |
+ # | |
+ def self.find_by_namespace(namespace) | |
+ namespace = "default#{namespace}" if namespace.empty? || namespace =~ /^:/ | |
+ | |
+ Thor::Base.subclasses.find do |klass| | |
+ klass.namespace == namespace | |
+ end | |
+ end | |
+ | |
+ # Receives a constant and converts it to a Thor namespace. Since Thor tasks | |
+ # can be added to a sandbox, this method is also responsable for removing | |
+ # the sandbox namespace. | |
+ # | |
+ # This method should not be used in general because it's used to deal with | |
+ # older versions of Thor. On current versions, if you need to get the | |
+ # namespace from a class, just call namespace on it. | |
+ # | |
+ # ==== Parameters | |
+ # constant<Object>:: The constant to be converted to the thor path. | |
+ # | |
+ # ==== Returns | |
+ # String:: If we receive Foo::Bar::Baz it returns "foo:bar:baz" | |
+ # | |
+ def self.namespace_from_thor_class(constant, remove_default=true) | |
+ constant = constant.to_s.gsub(/^Thor::Sandbox::/, "") | |
+ constant = snake_case(constant).squeeze(":") | |
+ constant.gsub!(/^default/, '') if remove_default | |
+ constant | |
+ end | |
+ | |
+ # Given the contents, evaluate it inside the sandbox and returns the | |
+ # namespaces defined in the sandbox. | |
+ # | |
+ # ==== Parameters | |
+ # contents<String> | |
+ # | |
+ # ==== Returns | |
+ # Array[Object] | |
+ # | |
+ def self.namespaces_in_content(contents, file=__FILE__) | |
+ old_constants = Thor::Base.subclasses.dup | |
+ Thor::Base.subclasses.clear | |
+ | |
+ load_thorfile(file, contents) | |
+ | |
+ new_constants = Thor::Base.subclasses.dup | |
+ Thor::Base.subclasses.replace(old_constants) | |
+ | |
+ new_constants.map!{ |c| c.namespace } | |
+ new_constants.compact! | |
+ new_constants | |
+ end | |
+ | |
+ # Returns the thor classes declared inside the given class. | |
+ # | |
+ def self.thor_classes_in(klass) | |
+ Thor::Base.subclasses.select do |subclass| | |
+ klass.constants.include?(subclass.name.gsub("#{klass.name}::", '')) | |
+ end | |
+ end | |
+ | |
+ # Receives a string and convert it to snake case. SnakeCase returns snake_case. | |
+ # | |
+ # ==== Parameters | |
+ # String | |
+ # | |
+ # ==== Returns | |
+ # String | |
+ # | |
+ def self.snake_case(str) | |
+ return str.downcase if str =~ /^[A-Z_]+$/ | |
+ str.gsub(/\B[A-Z]/, '_\&').squeeze('_') =~ /_*(.*)/ | |
+ return $+.downcase | |
+ end | |
+ | |
+ # Receives a string and convert it to camel case. camel_case returns CamelCase. | |
+ # | |
+ # ==== Parameters | |
+ # String | |
+ # | |
+ # ==== Returns | |
+ # String | |
+ # | |
+ def self.camel_case(str) | |
+ return str if str !~ /_/ && str =~ /[A-Z]+.*/ | |
+ str.split('_').map { |i| i.capitalize }.join | |
+ end | |
+ | |
+ # Receives a namespace and tries to retrieve a Thor or Thor::Group class | |
+ # from it. It first searches for a class using the all the given namespace, | |
+ # if it's not found, removes the highest entry and searches for the class | |
+ # again. If found, returns the highest entry as the class name. | |
+ # | |
+ # ==== Examples | |
+ # | |
+ # class Foo::Bar < Thor | |
+ # def baz | |
+ # end | |
+ # end | |
+ # | |
+ # class Baz::Foo < Thor::Group | |
+ # end | |
+ # | |
+ # Thor::Util.namespace_to_thor_class("foo:bar") #=> Foo::Bar, nil # will invoke default task | |
+ # Thor::Util.namespace_to_thor_class("baz:foo") #=> Baz::Foo, nil | |
+ # Thor::Util.namespace_to_thor_class("foo:bar:baz") #=> Foo::Bar, "baz" | |
+ # | |
+ # ==== Parameters | |
+ # namespace<String> | |
+ # | |
+ # ==== Errors | |
+ # Thor::Error:: raised if the namespace cannot be found. | |
+ # | |
+ # Thor::Error:: raised if the namespace evals to a class which does not | |
+ # inherit from Thor or Thor::Group. | |
+ # | |
+ def self.namespace_to_thor_class_and_task(namespace, raise_if_nil=true) | |
+ if namespace.include?(?:) | |
+ pieces = namespace.split(":") | |
+ task = pieces.pop | |
+ klass = Thor::Util.find_by_namespace(pieces.join(":")) | |
+ end | |
+ | |
+ unless klass | |
+ klass, task = Thor::Util.find_by_namespace(namespace), nil | |
+ end | |
+ | |
+ raise Error, "could not find Thor class or task '#{namespace}'" if raise_if_nil && klass.nil? | |
+ return klass, task | |
+ end | |
+ | |
+ # Receives a path and load the thor file in the path. The file is evaluated | |
+ # inside the sandbox to avoid namespacing conflicts. | |
+ # | |
+ def self.load_thorfile(path, content=nil) | |
+ content ||= File.read(path) | |
+ | |
+ begin | |
+ Thor::Sandbox.class_eval(content, path) | |
+ rescue Exception => e | |
+ $stderr.puts "WARNING: unable to load thorfile #{path.inspect}: #{e.message}" | |
+ end | |
+ end | |
+ | |
+ # Receives a yaml (hash) and updates all constants entries to namespace. | |
+ # This was added to deal with deprecated versions of Thor. | |
+ # | |
+ # TODO Deprecate this method in the future. | |
+ # | |
+ # ==== Returns | |
+ # TrueClass|FalseClass:: Returns true if any change to the yaml file was made. | |
+ # | |
+ def self.convert_constants_to_namespaces(yaml) | |
+ yaml_changed = false | |
+ | |
+ yaml.each do |k, v| | |
+ next unless v[:constants] && v[:namespaces].nil? | |
+ yaml_changed = true | |
+ yaml[k][:namespaces] = v[:constants].map{|c| Thor::Util.namespace_from_thor_class(c)} | |
+ end | |
+ | |
+ yaml_changed | |
+ end | |
+ | |
+ def self.user_home | |
+ @@user_home ||= if ENV["HOME"] | |
+ ENV["HOME"] | |
+ elsif ENV["USERPROFILE"] | |
+ ENV["USERPROFILE"] | |
+ elsif ENV["HOMEDRIVE"] && ENV["HOMEPATH"] | |
+ File.join(ENV["HOMEDRIVE"], ENV["HOMEPATH"]) | |
+ elsif ENV["APPDATA"] | |
+ ENV["APPDATA"] | |
+ else | |
+ begin | |
+ File.expand_path("~") | |
+ rescue | |
+ if File::ALT_SEPARATOR | |
+ "C:/" | |
+ else | |
+ "/" | |
+ end | |
+ end | |
+ end | |
+ end | |
+ | |
+ # Returns the root where thor files are located, dependending on the OS. | |
+ # | |
+ def self.thor_root | |
+ File.join(user_home, ".thor").gsub(/\\/, '/') | |
+ end | |
+ | |
+ # Returns the files in the thor root. On Windows thor_root will be something | |
+ # like this: | |
+ # | |
+ # C:\Documents and Settings\james\.thor | |
+ # | |
+ # If we don't #gsub the \ character, Dir.glob will fail. | |
+ # | |
+ def self.thor_root_glob | |
+ files = Dir["#{thor_root}/*"] | |
+ | |
+ files.map! do |file| | |
+ File.directory?(file) ? File.join(file, "main.thor") : file | |
+ end | |
+ end | |
+ | |
+ # Where to look for Thor files. | |
+ # | |
+ def self.globs_for(path) | |
+ ["#{path}/Thorfile", "#{path}/*.thor", "#{path}/tasks/*.thor", "#{path}/lib/tasks/*.thor"] | |
+ end | |
+ | |
+ # Return the path to the ruby interpreter taking into account multiple | |
+ # installations and windows extensions. | |
+ # | |
+ def self.ruby_command | |
+ @ruby_command ||= begin | |
+ ruby = File.join(Config::CONFIG['bindir'], Config::CONFIG['ruby_install_name']) | |
+ ruby << Config::CONFIG['EXEEXT'] | |
+ | |
+ # escape string in case path to ruby executable contain spaces. | |
+ ruby.sub!(/.*\s.*/m, '"\&"') | |
+ ruby | |
+ end | |
+ end | |
+ | |
+ end | |
+end | |
diff --git a/railties/lib/rails/vendor/thor-0.12.0/lib/thor/version.rb b/railties/lib/rails/vendor/thor-0.12.0/lib/thor/version.rb | |
new file mode 100644 | |
index 0000000..885230f | |
--- /dev/null | |
+++ b/railties/lib/rails/vendor/thor-0.12.0/lib/thor/version.rb | |
@@ -0,0 +1,3 @@ | |
+class Thor | |
+ VERSION = "0.11.8".freeze | |
+end | |
-- | |
1.5.4.3 | |
From 351df784f10545e12955ac34769298d9e5494d1a Mon Sep 17 00:00:00 2001 | |
From: =?utf-8?q?Jos=C3=A9=20Valim?= <jose.valim@gmail.com> | |
Date: Fri, 6 Nov 2009 23:40:18 -0200 | |
Subject: [PATCH] Refactor generators a little bit. | |
--- | |
railties/lib/rails/commands/destroy.rb | 3 +++ | |
railties/lib/rails/commands/generate.rb | 3 +++ | |
.../rails/generators/rails/app/app_generator.rb | 6 ++++-- | |
.../generators/rails/app/templates/script/about | 3 +++ | |
.../generators/rails/app/templates/script/about.tt | 4 ---- | |
.../generators/rails/app/templates/script/console | 2 ++ | |
.../rails/app/templates/script/console.tt | 3 --- | |
.../rails/app/templates/script/dbconsole | 2 ++ | |
.../rails/app/templates/script/dbconsole.tt | 3 --- | |
.../generators/rails/app/templates/script/destroy | 2 ++ | |
.../rails/app/templates/script/destroy.tt | 5 ----- | |
.../generators/rails/app/templates/script/generate | 2 ++ | |
.../rails/app/templates/script/generate.tt | 5 ----- | |
.../app/templates/script/performance/benchmarker | 2 ++ | |
.../templates/script/performance/benchmarker.tt | 3 --- | |
.../app/templates/script/performance/profiler | 2 ++ | |
.../app/templates/script/performance/profiler.tt | 3 --- | |
.../generators/rails/app/templates/script/plugin | 2 ++ | |
.../rails/app/templates/script/plugin.tt | 3 --- | |
.../generators/rails/app/templates/script/runner | 2 ++ | |
.../rails/app/templates/script/runner.tt | 3 --- | |
.../generators/rails/app/templates/script/server | 2 ++ | |
.../rails/app/templates/script/server.tt | 3 --- | |
23 files changed, 31 insertions(+), 37 deletions(-) | |
create mode 100755 railties/lib/rails/generators/rails/app/templates/script/about | |
delete mode 100755 railties/lib/rails/generators/rails/app/templates/script/about.tt | |
create mode 100755 railties/lib/rails/generators/rails/app/templates/script/console | |
delete mode 100755 railties/lib/rails/generators/rails/app/templates/script/console.tt | |
create mode 100755 railties/lib/rails/generators/rails/app/templates/script/dbconsole | |
delete mode 100755 railties/lib/rails/generators/rails/app/templates/script/dbconsole.tt | |
create mode 100755 railties/lib/rails/generators/rails/app/templates/script/destroy | |
delete mode 100755 railties/lib/rails/generators/rails/app/templates/script/destroy.tt | |
create mode 100755 railties/lib/rails/generators/rails/app/templates/script/generate | |
delete mode 100755 railties/lib/rails/generators/rails/app/templates/script/generate.tt | |
create mode 100755 railties/lib/rails/generators/rails/app/templates/script/performance/benchmarker | |
delete mode 100755 railties/lib/rails/generators/rails/app/templates/script/performance/benchmarker.tt | |
create mode 100755 railties/lib/rails/generators/rails/app/templates/script/performance/profiler | |
delete mode 100755 railties/lib/rails/generators/rails/app/templates/script/performance/profiler.tt | |
create mode 100755 railties/lib/rails/generators/rails/app/templates/script/plugin | |
delete mode 100755 railties/lib/rails/generators/rails/app/templates/script/plugin.tt | |
create mode 100755 railties/lib/rails/generators/rails/app/templates/script/runner | |
delete mode 100755 railties/lib/rails/generators/rails/app/templates/script/runner.tt | |
create mode 100755 railties/lib/rails/generators/rails/app/templates/script/server | |
delete mode 100755 railties/lib/rails/generators/rails/app/templates/script/server.tt | |
diff --git a/railties/lib/rails/commands/destroy.rb b/railties/lib/rails/commands/destroy.rb | |
index 15ff90f..f85c17b 100644 | |
--- a/railties/lib/rails/commands/destroy.rb | |
+++ b/railties/lib/rails/commands/destroy.rb | |
@@ -1,3 +1,6 @@ | |
+require 'rails/generators' | |
+Rails::Generators.configure! | |
+ | |
if ARGV.size == 0 | |
Rails::Generators.help | |
exit | |
diff --git a/railties/lib/rails/commands/generate.rb b/railties/lib/rails/commands/generate.rb | |
index 82a658e..c5e3ae3 100755 | |
--- a/railties/lib/rails/commands/generate.rb | |
+++ b/railties/lib/rails/commands/generate.rb | |
@@ -1,3 +1,6 @@ | |
+require 'rails/generators' | |
+Rails::Generators.configure! | |
+ | |
if ARGV.size == 0 | |
Rails::Generators.help | |
exit | |
diff --git a/railties/lib/rails/generators/rails/app/app_generator.rb b/railties/lib/rails/generators/rails/app/app_generator.rb | |
index e552cc4..2bcea4b 100644 | |
--- a/railties/lib/rails/generators/rails/app/app_generator.rb | |
+++ b/railties/lib/rails/generators/rails/app/app_generator.rb | |
@@ -123,8 +123,10 @@ module Rails::Generators | |
end | |
def create_script_files | |
- directory "script" | |
- chmod "script", 0755, :verbose => false | |
+ directory "script" do |file| | |
+ prepend_file file, "#{shebang}\n", :verbose => false | |
+ chmod file, 0755, :verbose => false | |
+ end | |
end | |
def create_test_files | |
diff --git a/railties/lib/rails/generators/rails/app/templates/script/about b/railties/lib/rails/generators/rails/app/templates/script/about | |
new file mode 100755 | |
index 0000000..93fd007 | |
--- /dev/null | |
+++ b/railties/lib/rails/generators/rails/app/templates/script/about | |
@@ -0,0 +1,3 @@ | |
+require File.expand_path('../../config/environment', __FILE__) | |
+$LOAD_PATH.unshift "#{RAILTIES_PATH}/builtin/rails_info" | |
+require 'rails/commands/about' | |
diff --git a/railties/lib/rails/generators/rails/app/templates/script/about.tt b/railties/lib/rails/generators/rails/app/templates/script/about.tt | |
deleted file mode 100755 | |
index 7639d40..0000000 | |
--- a/railties/lib/rails/generators/rails/app/templates/script/about.tt | |
+++ /dev/null | |
@@ -1,4 +0,0 @@ | |
-<%= shebang %> | |
-require File.expand_path('../../config/environment', __FILE__) | |
-$LOAD_PATH.unshift "#{RAILTIES_PATH}/builtin/rails_info" | |
-require 'rails/commands/about' | |
diff --git a/railties/lib/rails/generators/rails/app/templates/script/console b/railties/lib/rails/generators/rails/app/templates/script/console | |
new file mode 100755 | |
index 0000000..20aa799 | |
--- /dev/null | |
+++ b/railties/lib/rails/generators/rails/app/templates/script/console | |
@@ -0,0 +1,2 @@ | |
+require File.expand_path('../../config/application', __FILE__) | |
+require 'rails/commands/console' | |
diff --git a/railties/lib/rails/generators/rails/app/templates/script/console.tt b/railties/lib/rails/generators/rails/app/templates/script/console.tt | |
deleted file mode 100755 | |
index 1cd2eb8..0000000 | |
--- a/railties/lib/rails/generators/rails/app/templates/script/console.tt | |
+++ /dev/null | |
@@ -1,3 +0,0 @@ | |
-<%= shebang %> | |
-require File.expand_path('../../config/application', __FILE__) | |
-require 'rails/commands/console' | |
diff --git a/railties/lib/rails/generators/rails/app/templates/script/dbconsole b/railties/lib/rails/generators/rails/app/templates/script/dbconsole | |
new file mode 100755 | |
index 0000000..e6a1c59 | |
--- /dev/null | |
+++ b/railties/lib/rails/generators/rails/app/templates/script/dbconsole | |
@@ -0,0 +1,2 @@ | |
+require File.expand_path('../../config/application', __FILE__) | |
+require 'rails/commands/dbconsole' | |
diff --git a/railties/lib/rails/generators/rails/app/templates/script/dbconsole.tt b/railties/lib/rails/generators/rails/app/templates/script/dbconsole.tt | |
deleted file mode 100755 | |
index 94beb13..0000000 | |
--- a/railties/lib/rails/generators/rails/app/templates/script/dbconsole.tt | |
+++ /dev/null | |
@@ -1,3 +0,0 @@ | |
-<%= shebang %> | |
-require File.expand_path('../../config/application', __FILE__) | |
-require 'rails/commands/dbconsole' | |
diff --git a/railties/lib/rails/generators/rails/app/templates/script/destroy b/railties/lib/rails/generators/rails/app/templates/script/destroy | |
new file mode 100755 | |
index 0000000..adfa8e8 | |
--- /dev/null | |
+++ b/railties/lib/rails/generators/rails/app/templates/script/destroy | |
@@ -0,0 +1,2 @@ | |
+require File.expand_path('../../config/environment', __FILE__) | |
+require 'rails/commands/destroy' | |
diff --git a/railties/lib/rails/generators/rails/app/templates/script/destroy.tt b/railties/lib/rails/generators/rails/app/templates/script/destroy.tt | |
deleted file mode 100755 | |
index 6adc90b..0000000 | |
--- a/railties/lib/rails/generators/rails/app/templates/script/destroy.tt | |
+++ /dev/null | |
@@ -1,5 +0,0 @@ | |
-<%= shebang %> | |
-require File.expand_path('../../config/environment', __FILE__) | |
-require 'rails/generators' | |
-Rails::Generators.configure! | |
-require 'rails/commands/destroy' | |
diff --git a/railties/lib/rails/generators/rails/app/templates/script/generate b/railties/lib/rails/generators/rails/app/templates/script/generate | |
new file mode 100755 | |
index 0000000..6fb8ad0 | |
--- /dev/null | |
+++ b/railties/lib/rails/generators/rails/app/templates/script/generate | |
@@ -0,0 +1,2 @@ | |
+require File.expand_path('../../config/environment', __FILE__) | |
+require 'rails/commands/generate' | |
diff --git a/railties/lib/rails/generators/rails/app/templates/script/generate.tt b/railties/lib/rails/generators/rails/app/templates/script/generate.tt | |
deleted file mode 100755 | |
index 71d47de..0000000 | |
--- a/railties/lib/rails/generators/rails/app/templates/script/generate.tt | |
+++ /dev/null | |
@@ -1,5 +0,0 @@ | |
-<%= shebang %> | |
-require File.expand_path('../../config/environment', __FILE__) | |
-require 'rails/generators' | |
-Rails::Generators.configure! | |
-require 'rails/commands/generate' | |
diff --git a/railties/lib/rails/generators/rails/app/templates/script/performance/benchmarker b/railties/lib/rails/generators/rails/app/templates/script/performance/benchmarker | |
new file mode 100755 | |
index 0000000..9647d8f | |
--- /dev/null | |
+++ b/railties/lib/rails/generators/rails/app/templates/script/performance/benchmarker | |
@@ -0,0 +1,2 @@ | |
+require File.expand_path('../../../config/environment', __FILE__) | |
+require 'rails/commands/performance/benchmarker' | |
diff --git a/railties/lib/rails/generators/rails/app/templates/script/performance/benchmarker.tt b/railties/lib/rails/generators/rails/app/templates/script/performance/benchmarker.tt | |
deleted file mode 100755 | |
index 9ebc4c9..0000000 | |
--- a/railties/lib/rails/generators/rails/app/templates/script/performance/benchmarker.tt | |
+++ /dev/null | |
@@ -1,3 +0,0 @@ | |
-<%= shebang %> | |
-require File.expand_path('../../../config/environment', __FILE__) | |
-require 'rails/commands/performance/benchmarker' | |
diff --git a/railties/lib/rails/generators/rails/app/templates/script/performance/profiler b/railties/lib/rails/generators/rails/app/templates/script/performance/profiler | |
new file mode 100755 | |
index 0000000..a582204 | |
--- /dev/null | |
+++ b/railties/lib/rails/generators/rails/app/templates/script/performance/profiler | |
@@ -0,0 +1,2 @@ | |
+require File.expand_path('../../../config/environment', __FILE__) | |
+require 'rails/commands/performance/profiler' | |
diff --git a/railties/lib/rails/generators/rails/app/templates/script/performance/profiler.tt b/railties/lib/rails/generators/rails/app/templates/script/performance/profiler.tt | |
deleted file mode 100755 | |
index 5f4c763..0000000 | |
--- a/railties/lib/rails/generators/rails/app/templates/script/performance/profiler.tt | |
+++ /dev/null | |
@@ -1,3 +0,0 @@ | |
-<%= shebang %> | |
-require File.expand_path('../../../config/environment', __FILE__) | |
-require 'rails/commands/performance/profiler' | |
diff --git a/railties/lib/rails/generators/rails/app/templates/script/plugin b/railties/lib/rails/generators/rails/app/templates/script/plugin | |
new file mode 100755 | |
index 0000000..1f1af6c | |
--- /dev/null | |
+++ b/railties/lib/rails/generators/rails/app/templates/script/plugin | |
@@ -0,0 +1,2 @@ | |
+require File.expand_path('../../config/application', __FILE__) | |
+require 'rails/commands/plugin' | |
diff --git a/railties/lib/rails/generators/rails/app/templates/script/plugin.tt b/railties/lib/rails/generators/rails/app/templates/script/plugin.tt | |
deleted file mode 100755 | |
index 4a335ee..0000000 | |
--- a/railties/lib/rails/generators/rails/app/templates/script/plugin.tt | |
+++ /dev/null | |
@@ -1,3 +0,0 @@ | |
-<%= shebang %> | |
-require File.expand_path('../../config/application', __FILE__) | |
-require 'rails/commands/plugin' | |
diff --git a/railties/lib/rails/generators/rails/app/templates/script/runner b/railties/lib/rails/generators/rails/app/templates/script/runner | |
new file mode 100755 | |
index 0000000..7a70828 | |
--- /dev/null | |
+++ b/railties/lib/rails/generators/rails/app/templates/script/runner | |
@@ -0,0 +1,2 @@ | |
+require File.expand_path('../../config/environment', __FILE__) | |
+require 'rails/commands/runner' | |
diff --git a/railties/lib/rails/generators/rails/app/templates/script/runner.tt b/railties/lib/rails/generators/rails/app/templates/script/runner.tt | |
deleted file mode 100755 | |
index 34ad7c1..0000000 | |
--- a/railties/lib/rails/generators/rails/app/templates/script/runner.tt | |
+++ /dev/null | |
@@ -1,3 +0,0 @@ | |
-<%= shebang %> | |
-require File.expand_path('../../config/environment', __FILE__) | |
-require 'rails/commands/runner' | |
diff --git a/railties/lib/rails/generators/rails/app/templates/script/server b/railties/lib/rails/generators/rails/app/templates/script/server | |
new file mode 100755 | |
index 0000000..a7aaee2 | |
--- /dev/null | |
+++ b/railties/lib/rails/generators/rails/app/templates/script/server | |
@@ -0,0 +1,2 @@ | |
+require File.expand_path('../../config/application', __FILE__) | |
+require 'rails/commands/server' | |
diff --git a/railties/lib/rails/generators/rails/app/templates/script/server.tt b/railties/lib/rails/generators/rails/app/templates/script/server.tt | |
deleted file mode 100755 | |
index 932e72e..0000000 | |
--- a/railties/lib/rails/generators/rails/app/templates/script/server.tt | |
+++ /dev/null | |
@@ -1,3 +0,0 @@ | |
-<%= shebang %> | |
-require File.expand_path('../../config/application', __FILE__) | |
-require 'rails/commands/server' | |
-- | |
1.5.4.3 | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment