railties 5.0.7.2 → 5.1.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (197) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +77 -567
  3. data/MIT-LICENSE +1 -1
  4. data/RDOC_MAIN.rdoc +3 -3
  5. data/README.rdoc +1 -1
  6. data/exe/rails +2 -2
  7. data/lib/rails.rb +18 -18
  8. data/lib/rails/all.rb +1 -1
  9. data/lib/rails/api/generator.rb +28 -0
  10. data/lib/rails/api/task.rb +54 -42
  11. data/lib/rails/app_loader.rb +9 -9
  12. data/lib/rails/application.rb +30 -35
  13. data/lib/rails/application/bootstrap.rb +13 -7
  14. data/lib/rails/application/configuration.rb +30 -53
  15. data/lib/rails/application/default_middleware_stack.rb +3 -5
  16. data/lib/rails/application/finisher.rb +16 -7
  17. data/lib/rails/application/routes_reloader.rb +16 -1
  18. data/lib/rails/application_controller.rb +10 -10
  19. data/lib/rails/backtrace_cleaner.rb +5 -5
  20. data/lib/rails/cli.rb +7 -5
  21. data/lib/rails/code_statistics.rb +16 -17
  22. data/lib/rails/code_statistics_calculator.rb +3 -3
  23. data/lib/rails/command.rb +111 -0
  24. data/lib/rails/command/actions.rb +42 -0
  25. data/lib/rails/command/base.rb +149 -0
  26. data/lib/rails/command/behavior.rb +123 -0
  27. data/lib/rails/command/environment_argument.rb +34 -0
  28. data/lib/rails/commands.rb +2 -4
  29. data/lib/rails/commands/application/application_command.rb +29 -0
  30. data/lib/rails/commands/console/console_command.rb +89 -0
  31. data/lib/rails/commands/dbconsole/dbconsole_command.rb +155 -0
  32. data/lib/rails/commands/destroy/destroy_command.rb +21 -0
  33. data/lib/rails/commands/generate/generate_command.rb +23 -0
  34. data/lib/rails/commands/help/USAGE +15 -0
  35. data/lib/rails/commands/help/help_command.rb +13 -0
  36. data/lib/rails/commands/new/new_command.rb +15 -0
  37. data/lib/rails/commands/plugin/plugin_command.rb +43 -0
  38. data/lib/rails/commands/rake/rake_command.rb +49 -0
  39. data/lib/rails/commands/runner/USAGE +17 -0
  40. data/lib/rails/commands/runner/runner_command.rb +46 -0
  41. data/lib/rails/commands/secrets/USAGE +52 -0
  42. data/lib/rails/commands/secrets/secrets_command.rb +36 -0
  43. data/lib/rails/commands/server/server_command.rb +177 -0
  44. data/lib/rails/commands/test/test_command.rb +20 -0
  45. data/lib/rails/commands/version/version_command.rb +9 -0
  46. data/lib/rails/configuration.rb +7 -7
  47. data/lib/rails/console/app.rb +4 -4
  48. data/lib/rails/dev_caching.rb +8 -8
  49. data/lib/rails/engine.rb +62 -63
  50. data/lib/rails/engine/commands.rb +6 -13
  51. data/lib/rails/engine/configuration.rb +2 -2
  52. data/lib/rails/gem_version.rb +3 -3
  53. data/lib/rails/generators.rb +229 -313
  54. data/lib/rails/generators/actions.rb +20 -21
  55. data/lib/rails/generators/actions/create_migration.rb +24 -25
  56. data/lib/rails/generators/active_model.rb +3 -3
  57. data/lib/rails/generators/app_base.rb +123 -93
  58. data/lib/rails/generators/base.rb +32 -33
  59. data/lib/rails/generators/css/assets/assets_generator.rb +1 -1
  60. data/lib/rails/generators/erb.rb +14 -14
  61. data/lib/rails/generators/erb/controller/controller_generator.rb +1 -1
  62. data/lib/rails/generators/erb/mailer/mailer_generator.rb +12 -12
  63. data/lib/rails/generators/erb/scaffold/scaffold_generator.rb +3 -3
  64. data/lib/rails/generators/generated_attribute.rb +27 -27
  65. data/lib/rails/generators/js/assets/assets_generator.rb +1 -1
  66. data/lib/rails/generators/migration.rb +8 -8
  67. data/lib/rails/generators/model_helpers.rb +2 -2
  68. data/lib/rails/generators/named_base.rb +56 -56
  69. data/lib/rails/generators/rails/app/app_generator.rb +98 -81
  70. data/lib/rails/generators/rails/app/templates/Gemfile +7 -2
  71. data/lib/rails/generators/rails/app/templates/app/assets/config/manifest.js.tt +0 -2
  72. data/lib/rails/generators/rails/app/templates/app/assets/javascripts/application.js.tt +6 -4
  73. data/lib/rails/generators/rails/app/templates/app/assets/javascripts/cable.js +1 -1
  74. data/lib/rails/generators/rails/app/templates/app/assets/stylesheets/application.css +2 -2
  75. data/lib/rails/generators/rails/app/templates/app/views/layouts/application.html.erb.tt +1 -1
  76. data/lib/rails/generators/rails/app/templates/bin/{setup → setup.tt} +6 -0
  77. data/lib/rails/generators/rails/app/templates/bin/{update → update.tt} +2 -1
  78. data/lib/rails/generators/rails/app/templates/bin/yarn +9 -0
  79. data/lib/rails/generators/rails/app/templates/config/cable.yml +1 -0
  80. data/lib/rails/generators/rails/app/templates/config/databases/frontbase.yml +1 -0
  81. data/lib/rails/generators/rails/app/templates/config/databases/ibm_db.yml +1 -0
  82. data/lib/rails/generators/rails/app/templates/config/databases/jdbc.yml +1 -0
  83. data/lib/rails/generators/rails/app/templates/config/databases/jdbcmysql.yml +2 -1
  84. data/lib/rails/generators/rails/app/templates/config/databases/jdbcpostgresql.yml +1 -0
  85. data/lib/rails/generators/rails/app/templates/config/databases/jdbcsqlite3.yml +1 -0
  86. data/lib/rails/generators/rails/app/templates/config/databases/mysql.yml +2 -2
  87. data/lib/rails/generators/rails/app/templates/config/databases/oracle.yml +1 -0
  88. data/lib/rails/generators/rails/app/templates/config/databases/postgresql.yml +1 -1
  89. data/lib/rails/generators/rails/app/templates/config/databases/sqlite3.yml +1 -1
  90. data/lib/rails/generators/rails/app/templates/config/environments/development.rb.tt +1 -1
  91. data/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt +10 -1
  92. data/lib/rails/generators/rails/app/templates/config/environments/test.rb.tt +1 -1
  93. data/lib/rails/generators/rails/app/templates/config/initializers/application_controller_renderer.rb +4 -6
  94. data/lib/rails/generators/rails/app/templates/config/initializers/assets.rb.tt +8 -3
  95. data/lib/rails/generators/rails/app/templates/config/initializers/new_framework_defaults.rb.tt +6 -5
  96. data/lib/rails/generators/rails/app/templates/config/locales/en.yml +10 -0
  97. data/lib/rails/generators/rails/app/templates/config/puma.rb +16 -7
  98. data/lib/rails/generators/rails/app/templates/config/secrets.yml +12 -2
  99. data/lib/rails/generators/rails/app/templates/gitignore +5 -1
  100. data/lib/rails/generators/rails/app/templates/package.json +5 -0
  101. data/lib/rails/generators/rails/app/templates/public/404.html +6 -6
  102. data/lib/rails/generators/rails/app/templates/public/422.html +6 -6
  103. data/lib/rails/generators/rails/app/templates/public/500.html +6 -6
  104. data/lib/rails/generators/rails/app/templates/public/robots.txt +0 -4
  105. data/lib/rails/generators/rails/app/templates/test/application_system_test_case.rb +5 -0
  106. data/lib/rails/generators/rails/app/templates/test/test_helper.rb +0 -1
  107. data/lib/rails/generators/rails/assets/assets_generator.rb +10 -10
  108. data/lib/rails/generators/rails/controller/controller_generator.rb +15 -12
  109. data/lib/rails/generators/rails/encrypted_secrets/encrypted_secrets_generator.rb +66 -0
  110. data/lib/rails/generators/rails/encrypted_secrets/templates/config/secrets.yml.enc +3 -0
  111. data/lib/rails/generators/rails/generator/generator_generator.rb +2 -3
  112. data/lib/rails/generators/rails/helper/helper_generator.rb +1 -1
  113. data/lib/rails/generators/rails/model/model_generator.rb +1 -1
  114. data/lib/rails/generators/rails/plugin/plugin_generator.rb +21 -26
  115. data/lib/rails/generators/rails/plugin/templates/bin/rails.tt +1 -0
  116. data/lib/rails/generators/rails/plugin/templates/bin/test.tt +3 -9
  117. data/lib/rails/generators/rails/plugin/templates/test/application_system_test_case.rb +5 -0
  118. data/lib/rails/generators/rails/plugin/templates/test/test_helper.rb +0 -3
  119. data/lib/rails/generators/rails/resource/resource_generator.rb +2 -2
  120. data/lib/rails/generators/rails/scaffold/scaffold_generator.rb +5 -1
  121. data/lib/rails/generators/rails/scaffold/templates/scaffold.css +4 -8
  122. data/lib/rails/generators/rails/scaffold_controller/scaffold_controller_generator.rb +2 -3
  123. data/lib/rails/generators/rails/system_test/USAGE +10 -0
  124. data/lib/rails/generators/rails/system_test/system_test_generator.rb +7 -0
  125. data/lib/rails/generators/rails/task/task_generator.rb +1 -2
  126. data/lib/rails/generators/resource_helpers.rb +13 -10
  127. data/lib/rails/generators/test_case.rb +5 -6
  128. data/lib/rails/generators/test_unit.rb +1 -1
  129. data/lib/rails/generators/test_unit/controller/controller_generator.rb +3 -3
  130. data/lib/rails/generators/test_unit/generator/generator_generator.rb +3 -3
  131. data/lib/rails/generators/test_unit/helper/helper_generator.rb +1 -1
  132. data/lib/rails/generators/test_unit/integration/integration_generator.rb +2 -2
  133. data/lib/rails/generators/test_unit/job/job_generator.rb +3 -3
  134. data/lib/rails/generators/test_unit/mailer/mailer_generator.rb +5 -5
  135. data/lib/rails/generators/test_unit/model/model_generator.rb +3 -4
  136. data/lib/rails/generators/test_unit/plugin/plugin_generator.rb +2 -2
  137. data/lib/rails/generators/test_unit/scaffold/scaffold_generator.rb +3 -3
  138. data/lib/rails/generators/test_unit/system/system_generator.rb +17 -0
  139. data/lib/rails/generators/test_unit/system/templates/application_system_test_case.rb +5 -0
  140. data/lib/rails/generators/test_unit/system/templates/system_test.rb +9 -0
  141. data/lib/rails/generators/testing/assertions.rb +4 -4
  142. data/lib/rails/generators/testing/behaviour.rb +20 -21
  143. data/lib/rails/info.rb +20 -20
  144. data/lib/rails/info_controller.rb +15 -15
  145. data/lib/rails/initializable.rb +6 -2
  146. data/lib/rails/mailers_controller.rb +11 -11
  147. data/lib/rails/paths.rb +4 -5
  148. data/lib/rails/plugin/test.rb +7 -0
  149. data/lib/rails/rack/logger.rb +44 -46
  150. data/lib/rails/railtie.rb +41 -38
  151. data/lib/rails/railtie/configurable.rb +6 -6
  152. data/lib/rails/railtie/configuration.rb +1 -1
  153. data/lib/rails/ruby_version_check.rb +1 -1
  154. data/lib/rails/secrets.rb +111 -0
  155. data/lib/rails/source_annotation_extractor.rb +15 -9
  156. data/lib/rails/tasks.rb +3 -2
  157. data/lib/rails/tasks/annotations.rake +3 -3
  158. data/lib/rails/tasks/dev.rake +2 -2
  159. data/lib/rails/tasks/engine.rake +4 -4
  160. data/lib/rails/tasks/framework.rake +4 -18
  161. data/lib/rails/tasks/initializers.rake +1 -1
  162. data/lib/rails/tasks/log.rake +14 -10
  163. data/lib/rails/tasks/middleware.rake +1 -1
  164. data/lib/rails/tasks/misc.rake +10 -10
  165. data/lib/rails/tasks/restart.rake +4 -4
  166. data/lib/rails/tasks/routes.rake +3 -12
  167. data/lib/rails/tasks/statistics.rake +3 -3
  168. data/lib/rails/tasks/tmp.rake +7 -7
  169. data/lib/rails/tasks/yarn.rake +11 -0
  170. data/lib/rails/templates/rails/mailers/email.html.erb +4 -1
  171. data/lib/rails/test_help.rb +28 -10
  172. data/lib/rails/test_unit/line_filtering.rb +69 -3
  173. data/lib/rails/test_unit/minitest_plugin.rb +139 -0
  174. data/lib/rails/test_unit/railtie.rb +2 -1
  175. data/lib/rails/test_unit/reporter.rb +3 -8
  176. data/lib/rails/test_unit/test_requirer.rb +28 -0
  177. data/lib/rails/test_unit/testing.rake +19 -14
  178. data/lib/rails/version.rb +1 -1
  179. data/lib/rails/welcome_controller.rb +1 -1
  180. metadata +53 -30
  181. data/lib/minitest/rails_plugin.rb +0 -49
  182. data/lib/rails/commands/application.rb +0 -17
  183. data/lib/rails/commands/commands_tasks.rb +0 -180
  184. data/lib/rails/commands/console.rb +0 -68
  185. data/lib/rails/commands/console_helper.rb +0 -34
  186. data/lib/rails/commands/dbconsole.rb +0 -173
  187. data/lib/rails/commands/destroy.rb +0 -11
  188. data/lib/rails/commands/generate.rb +0 -13
  189. data/lib/rails/commands/plugin.rb +0 -23
  190. data/lib/rails/commands/rake_proxy.rb +0 -41
  191. data/lib/rails/commands/runner.rb +0 -71
  192. data/lib/rails/commands/server.rb +0 -163
  193. data/lib/rails/commands/test.rb +0 -10
  194. data/lib/rails/engine/commands_tasks.rb +0 -118
  195. data/lib/rails/generators/rails/app/templates/config/initializers/session_store.rb.tt +0 -3
  196. data/lib/rails/rack/debugger.rb +0 -3
  197. data/lib/rails/test_unit/runner.rb +0 -141
@@ -43,7 +43,7 @@ class CodeStatisticsCalculator #:nodoc:
43
43
 
44
44
  def add_by_file_path(file_path)
45
45
  File.open(file_path) do |f|
46
- self.add_by_io(f, file_type(file_path))
46
+ add_by_io(f, file_type(file_path))
47
47
  end
48
48
  end
49
49
 
@@ -77,10 +77,10 @@ class CodeStatisticsCalculator #:nodoc:
77
77
 
78
78
  private
79
79
  def file_type(file_path)
80
- if file_path.end_with? '_test.rb'
80
+ if file_path.end_with? "_test.rb"
81
81
  :minitest
82
82
  else
83
- File.extname(file_path).sub(/\A\./, '').downcase.to_sym
83
+ File.extname(file_path).sub(/\A\./, "").downcase.to_sym
84
84
  end
85
85
  end
86
86
  end
@@ -0,0 +1,111 @@
1
+ require "active_support"
2
+ require "active_support/dependencies/autoload"
3
+ require "active_support/core_ext/enumerable"
4
+ require "active_support/core_ext/object/blank"
5
+ require "active_support/core_ext/hash/transform_values"
6
+
7
+ require "thor"
8
+
9
+ module Rails
10
+ module Command
11
+ extend ActiveSupport::Autoload
12
+
13
+ autoload :Behavior
14
+ autoload :Base
15
+
16
+ include Behavior
17
+
18
+ HELP_MAPPINGS = %w(-h -? --help)
19
+
20
+ class << self
21
+ def hidden_commands # :nodoc:
22
+ @hidden_commands ||= []
23
+ end
24
+
25
+ def environment # :nodoc:
26
+ ENV["RAILS_ENV"] || ENV["RACK_ENV"] || "development"
27
+ end
28
+
29
+ # Receives a namespace, arguments and the behavior to invoke the command.
30
+ def invoke(full_namespace, args = [], **config)
31
+ namespace = full_namespace = full_namespace.to_s
32
+
33
+ if char = namespace =~ /:(\w+)$/
34
+ command_name, namespace = $1, namespace.slice(0, char)
35
+ else
36
+ command_name = namespace
37
+ end
38
+
39
+ command_name = "help" if command_name.blank? || HELP_MAPPINGS.include?(command_name)
40
+ namespace = "version" if %w( -v --version ).include?(command_name)
41
+
42
+ command = find_by_namespace(namespace, command_name)
43
+ if command && command.all_commands[command_name]
44
+ command.perform(command_name, args, config)
45
+ else
46
+ find_by_namespace("rake").perform(full_namespace, args, config)
47
+ end
48
+ end
49
+
50
+ # Rails finds namespaces similar to Thor, it only adds one rule:
51
+ #
52
+ # Command names must end with "_command.rb". This is required because Rails
53
+ # looks in load paths and loads the command just before it's going to be used.
54
+ #
55
+ # find_by_namespace :webrat, :rails, :integration
56
+ #
57
+ # Will search for the following commands:
58
+ #
59
+ # "rails:webrat", "webrat:integration", "webrat"
60
+ #
61
+ # Notice that "rails:commands:webrat" could be loaded as well, what
62
+ # Rails looks for is the first and last parts of the namespace.
63
+ def find_by_namespace(namespace, command_name = nil) # :nodoc:
64
+ lookups = [ namespace ]
65
+ lookups << "#{namespace}:#{command_name}" if command_name
66
+ lookups.concat lookups.map { |lookup| "rails:#{lookup}" }
67
+
68
+ lookup(lookups)
69
+
70
+ namespaces = subclasses.index_by(&:namespace)
71
+ namespaces[(lookups & namespaces.keys).first]
72
+ end
73
+
74
+ # Returns the root of the Rails engine or app running the command.
75
+ def root
76
+ if defined?(ENGINE_ROOT)
77
+ Pathname.new(ENGINE_ROOT)
78
+ elsif defined?(APP_PATH)
79
+ Pathname.new(File.expand_path("../..", APP_PATH))
80
+ end
81
+ end
82
+
83
+ def print_commands # :nodoc:
84
+ sorted_groups.each { |b, n| print_list(b, n) }
85
+ end
86
+
87
+ def sorted_groups # :nodoc:
88
+ lookup!
89
+
90
+ groups = (subclasses - hidden_commands).group_by { |c| c.namespace.split(":").first }
91
+ groups.transform_values! { |commands| commands.flat_map(&:printing_commands).sort }
92
+
93
+ rails = groups.delete("rails")
94
+ [[ "rails", rails ]] + groups.sort.to_a
95
+ end
96
+
97
+ private
98
+ def command_type # :doc:
99
+ @command_type ||= "command"
100
+ end
101
+
102
+ def lookup_paths # :doc:
103
+ @lookup_paths ||= %w( rails/commands commands )
104
+ end
105
+
106
+ def file_lookup_paths # :doc:
107
+ @file_lookup_paths ||= [ "{#{lookup_paths.join(',')}}", "**", "*_command.rb" ]
108
+ end
109
+ end
110
+ end
111
+ end
@@ -0,0 +1,42 @@
1
+ module Rails
2
+ module Command
3
+ module Actions
4
+ # Change to the application's path if there is no config.ru file in current directory.
5
+ # This allows us to run `rails server` from other directories, but still get
6
+ # the main config.ru and properly set the tmp directory.
7
+ def set_application_directory!
8
+ Dir.chdir(File.expand_path("../../", APP_PATH)) unless File.exist?(File.expand_path("config.ru"))
9
+ end
10
+
11
+ def require_application_and_environment!
12
+ require ENGINE_PATH if defined?(ENGINE_PATH)
13
+
14
+ if defined?(APP_PATH)
15
+ require APP_PATH
16
+ Rails.application.require_environment!
17
+ end
18
+ end
19
+
20
+ if defined?(ENGINE_PATH)
21
+ def load_tasks
22
+ Rake.application.init("rails")
23
+ Rake.application.load_rakefile
24
+ end
25
+
26
+ def load_generators
27
+ engine = ::Rails::Engine.find(ENGINE_ROOT)
28
+ Rails::Generators.namespace = engine.railtie_namespace
29
+ engine.load_generators
30
+ end
31
+ else
32
+ def load_tasks
33
+ Rails.application.load_tasks
34
+ end
35
+
36
+ def load_generators
37
+ Rails.application.load_generators
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,149 @@
1
+ require "thor"
2
+ require "erb"
3
+
4
+ require "active_support/core_ext/string/filters"
5
+ require "active_support/core_ext/string/inflections"
6
+
7
+ require "rails/command/actions"
8
+
9
+ module Rails
10
+ module Command
11
+ class Base < Thor
12
+ class Error < Thor::Error # :nodoc:
13
+ end
14
+
15
+ include Actions
16
+
17
+ class << self
18
+ # Returns true when the app is a Rails engine.
19
+ def engine?
20
+ defined?(ENGINE_ROOT)
21
+ end
22
+
23
+ # Tries to get the description from a USAGE file one folder above the command
24
+ # root.
25
+ def desc(usage = nil, description = nil, options = {})
26
+ if usage
27
+ super
28
+ else
29
+ @desc ||= ERB.new(File.read(usage_path)).result(binding) if usage_path
30
+ end
31
+ end
32
+
33
+ # Convenience method to get the namespace from the class name. It's the
34
+ # same as Thor default except that the Command at the end of the class
35
+ # is removed.
36
+ def namespace(name = nil)
37
+ if name
38
+ super
39
+ else
40
+ @namespace ||= super.chomp("_command").sub(/:command:/, ":")
41
+ end
42
+ end
43
+
44
+ # Convenience method to hide this command from the available ones when
45
+ # running rails command.
46
+ def hide_command!
47
+ Rails::Command.hidden_commands << self
48
+ end
49
+
50
+ def inherited(base) #:nodoc:
51
+ super
52
+
53
+ if base.name && base.name !~ /Base$/
54
+ Rails::Command.subclasses << base
55
+ end
56
+ end
57
+
58
+ def perform(command, args, config) # :nodoc:
59
+ if Rails::Command::HELP_MAPPINGS.include?(args.first)
60
+ command, args = "help", []
61
+ end
62
+
63
+ dispatch(command, args.dup, nil, config)
64
+ end
65
+
66
+ def printing_commands
67
+ namespace.sub(/^rails:/, "")
68
+ end
69
+
70
+ def executable
71
+ "bin/rails #{command_name}"
72
+ end
73
+
74
+ # Use Rails' default banner.
75
+ def banner(*)
76
+ "#{executable} #{arguments.map(&:usage).join(' ')} [options]".squish!
77
+ end
78
+
79
+ # Sets the base_name taking into account the current class namespace.
80
+ #
81
+ # Rails::Command::TestCommand.base_name # => 'rails'
82
+ def base_name
83
+ @base_name ||= begin
84
+ if base = name.to_s.split("::").first
85
+ base.underscore
86
+ end
87
+ end
88
+ end
89
+
90
+ # Return command name without namespaces.
91
+ #
92
+ # Rails::Command::TestCommand.command_name # => 'test'
93
+ def command_name
94
+ @command_name ||= begin
95
+ if command = name.to_s.split("::").last
96
+ command.chomp!("Command")
97
+ command.underscore
98
+ end
99
+ end
100
+ end
101
+
102
+ # Path to lookup a USAGE description in a file.
103
+ def usage_path
104
+ if default_command_root
105
+ path = File.join(default_command_root, "USAGE")
106
+ path if File.exist?(path)
107
+ end
108
+ end
109
+
110
+ # Default file root to place extra files a command might need, placed
111
+ # one folder above the command file.
112
+ #
113
+ # For a `Rails::Command::TestCommand` placed in `rails/command/test_command.rb`
114
+ # would return `rails/test`.
115
+ def default_command_root
116
+ path = File.expand_path(File.join("../commands", command_root_namespace), __dir__)
117
+ path if File.exist?(path)
118
+ end
119
+
120
+ private
121
+ # Allow the command method to be called perform.
122
+ def create_command(meth)
123
+ if meth == "perform"
124
+ alias_method command_name, meth
125
+ else
126
+ # Prevent exception about command without usage.
127
+ # Some commands define their documentation differently.
128
+ @usage ||= ""
129
+ @desc ||= ""
130
+
131
+ super
132
+ end
133
+ end
134
+
135
+ def command_root_namespace
136
+ (namespace.split(":") - %w( rails )).first
137
+ end
138
+ end
139
+
140
+ def help
141
+ if command_name = self.class.command_name
142
+ self.class.command_help(shell, command_name)
143
+ else
144
+ super
145
+ end
146
+ end
147
+ end
148
+ end
149
+ end
@@ -0,0 +1,123 @@
1
+ require "active_support"
2
+
3
+ module Rails
4
+ module Command
5
+ module Behavior #:nodoc:
6
+ extend ActiveSupport::Concern
7
+
8
+ class_methods do
9
+ # Remove the color from output.
10
+ def no_color!
11
+ Thor::Base.shell = Thor::Shell::Basic
12
+ end
13
+
14
+ # Track all command subclasses.
15
+ def subclasses
16
+ @subclasses ||= []
17
+ end
18
+
19
+ private
20
+
21
+ # This code is based directly on the Text gem implementation.
22
+ # Copyright (c) 2006-2013 Paul Battley, Michael Neumann, Tim Fletcher.
23
+ #
24
+ # Returns a value representing the "cost" of transforming str1 into str2.
25
+ def levenshtein_distance(str1, str2) # :doc:
26
+ s = str1
27
+ t = str2
28
+ n = s.length
29
+ m = t.length
30
+
31
+ return m if (0 == n)
32
+ return n if (0 == m)
33
+
34
+ d = (0..m).to_a
35
+ x = nil
36
+
37
+ # avoid duplicating an enumerable object in the loop
38
+ str2_codepoint_enumerable = str2.each_codepoint
39
+
40
+ str1.each_codepoint.with_index do |char1, i|
41
+ e = i + 1
42
+
43
+ str2_codepoint_enumerable.with_index do |char2, j|
44
+ cost = (char1 == char2) ? 0 : 1
45
+ x = [
46
+ d[j + 1] + 1, # insertion
47
+ e + 1, # deletion
48
+ d[j] + cost # substitution
49
+ ].min
50
+ d[j] = e
51
+ e = x
52
+ end
53
+
54
+ d[m] = x
55
+ end
56
+
57
+ x
58
+ end
59
+
60
+ # Prints a list of generators.
61
+ def print_list(base, namespaces)
62
+ return if namespaces.empty?
63
+ puts "#{base.camelize}:"
64
+
65
+ namespaces.each do |namespace|
66
+ puts(" #{namespace}")
67
+ end
68
+
69
+ puts
70
+ end
71
+
72
+ # Receives namespaces in an array and tries to find matching generators
73
+ # in the load path.
74
+ def lookup(namespaces)
75
+ paths = namespaces_to_paths(namespaces)
76
+
77
+ paths.each do |raw_path|
78
+ lookup_paths.each do |base|
79
+ path = "#{base}/#{raw_path}_#{command_type}"
80
+
81
+ begin
82
+ require path
83
+ return
84
+ rescue LoadError => e
85
+ raise unless e.message =~ /#{Regexp.escape(path)}$/
86
+ rescue Exception => e
87
+ warn "[WARNING] Could not load #{command_type} #{path.inspect}. Error: #{e.message}.\n#{e.backtrace.join("\n")}"
88
+ end
89
+ end
90
+ end
91
+ end
92
+
93
+ # This will try to load any command in the load path to show in help.
94
+ def lookup!
95
+ $LOAD_PATH.each do |base|
96
+ Dir[File.join(base, *file_lookup_paths)].each do |path|
97
+ begin
98
+ path = path.sub("#{base}/", "")
99
+ require path
100
+ rescue Exception
101
+ # No problem
102
+ end
103
+ end
104
+ end
105
+ end
106
+
107
+ # Convert namespaces to paths by replacing ":" for "/" and adding
108
+ # an extra lookup. For example, "rails:model" should be searched
109
+ # in both: "rails/model/model_generator" and "rails/model_generator".
110
+ def namespaces_to_paths(namespaces)
111
+ paths = []
112
+ namespaces.each do |namespace|
113
+ pieces = namespace.split(":")
114
+ paths << pieces.dup.push(pieces.last).join("/")
115
+ paths << pieces.join("/")
116
+ end
117
+ paths.uniq!
118
+ paths
119
+ end
120
+ end
121
+ end
122
+ end
123
+ end