railties 4.0.3 → 4.0.4.rc1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4b5689b5bea25ae05f0c03d307d2bcbf1100c24e
4
- data.tar.gz: a7a34a697e412f009059402902938d23a7a1461d
3
+ metadata.gz: 7ecf31fbccd4ced48e27c08f96230389580a2e0e
4
+ data.tar.gz: a4e8cf6b10f3147049b34b4731608860fa4cd46b
5
5
  SHA512:
6
- metadata.gz: 14344507cdc099caddb83f5a37ff555071cc9d7c7dcda6f6192f5e8b354ec5a1ea1ecd5a3eb31698a5431a864589ef21c72d2f11b2de8b24c39b7cbf78612f94
7
- data.tar.gz: 8998b34540deef294c1715dfd72abbe4ff0c8ae1d6a33543705163b80827995a00150585a31e85fe4a6bacbcf83121231152a8cb0a2269c41fd174460d5945e5
6
+ metadata.gz: 82641a8f707a8da6d6f208d190efb19b41d948cef2934259f7ae4b8112bbeef4cf91887b0d4170ea571fcbb43f7dc5cab01d06f996a851ea0e23e28f1c3dbfcb
7
+ data.tar.gz: 17376d4b68ed6e74421d31a14eb38c5a9f6f7e403a14e0d6b9528dbf714dbb8a62e666a3254e5933b7da8410907ea33de9a9bda00abbb583a27951b4dc6d7391
@@ -1,3 +1,34 @@
1
+ ## Rails 4.0.4 ##
2
+
3
+ * Added Thor-action for creation of migrations.
4
+
5
+ Fixes #13588 and #12674.
6
+
7
+ *Gert Goet*
8
+
9
+ * Add `ENV['DATABASE_URL']` support in `rails dbconsole`. Fixes #13320.
10
+
11
+ *Huiming Teo*
12
+
13
+ * Fix default `config/application.rb` template to honor the RAILS_GROUPS env variable.
14
+
15
+ *Guillermo Iguaran*
16
+
17
+ * Fix default `config/application.rb` template to remove unused `config.assets.enabled` variable.
18
+
19
+ *Guillermo Iguaran*
20
+
21
+
22
+ ## Rails 4.0.3 (February 18, 2014) ##
23
+
24
+ *No changes*
25
+
26
+
27
+ ## Rails 4.0.2 (December 02, 2013) ##
28
+
29
+ *No changes*
30
+
31
+
1
32
  ## Rails 4.0.1 (November 01, 2013) ##
2
33
 
3
34
  * Fix the event name of action_dispatch requests.
data/bin/rails CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  git_path = File.join(File.expand_path('../../..', __FILE__), '.git')
4
4
 
5
- if File.exists?(git_path)
5
+ if File.exist?(git_path)
6
6
  railties_path = File.expand_path('../../lib', __FILE__)
7
7
  $:.unshift(railties_path)
8
8
  end
@@ -55,7 +55,7 @@ EOS
55
55
  end
56
56
 
57
57
  def self.find_executable
58
- EXECUTABLES.find { |exe| File.exists?(exe) }
58
+ EXECUTABLES.find { |exe| File.exist?(exe) }
59
59
  end
60
60
  end
61
61
  end
@@ -181,7 +181,7 @@ module Rails
181
181
  # you need to load files in lib/ during the application configuration as well.
182
182
  def add_lib_to_load_path! #:nodoc:
183
183
  path = File.join config.root, 'lib'
184
- $LOAD_PATH.unshift(path) if File.exists?(path)
184
+ $LOAD_PATH.unshift(path) if File.exist?(path)
185
185
  end
186
186
 
187
187
  def require_environment! #:nodoc:
@@ -101,7 +101,7 @@ module Rails
101
101
  # Loads and returns the configuration of the database.
102
102
  def database_configuration
103
103
  yaml = paths["config/database"].first
104
- if File.exists?(yaml)
104
+ if File.exist?(yaml)
105
105
  require "erb"
106
106
  YAML.load ERB.new(IO.read(yaml)).result
107
107
  elsif ENV['DATABASE_URL']
@@ -65,7 +65,7 @@ when 'server'
65
65
  # Change to the application's path if there is no config.ru file in current directory.
66
66
  # This allows us to run `rails server` from other directories, but still get
67
67
  # the main config.ru and properly set the tmp directory.
68
- Dir.chdir(File.expand_path('../../', APP_PATH)) unless File.exists?(File.expand_path("config.ru"))
68
+ Dir.chdir(File.expand_path('../../', APP_PATH)) unless File.exist?(File.expand_path("config.ru"))
69
69
 
70
70
  require 'rails/commands/server'
71
71
  Rails::Server.new.tap do |server|
@@ -81,14 +81,11 @@ module Rails
81
81
 
82
82
  def config
83
83
  @config ||= begin
84
- cfg = begin
85
- YAML.load(ERB.new(IO.read("config/database.yml")).result)
86
- rescue SyntaxError, StandardError
87
- require APP_PATH
88
- Rails.application.config.database_configuration
89
- end
90
-
91
- cfg[environment] || abort("No database is configured for the environment '#{environment}'")
84
+ require APP_PATH
85
+ ActiveRecord::ConnectionAdapters::ConnectionSpecification::Resolver.new(
86
+ ENV['DATABASE_URL'],
87
+ (Rails.application.config.database_configuration || {})
88
+ ).spec.config.stringify_keys
92
89
  end
93
90
  end
94
91
 
@@ -50,5 +50,5 @@ elsif File.exist?(code_or_file)
50
50
  $0 = code_or_file
51
51
  eval(File.read(code_or_file), nil, code_or_file)
52
52
  else
53
- eval(code_or_file)
53
+ eval(code_or_file, binding, __FILE__, __LINE__)
54
54
  end
@@ -0,0 +1,68 @@
1
+ require 'thor/actions/create_file'
2
+
3
+ module Rails
4
+ module Generators
5
+ module Actions
6
+ class CreateMigration < Thor::Actions::CreateFile
7
+
8
+ def migration_dir
9
+ File.dirname(@destination)
10
+ end
11
+
12
+ def migration_file_name
13
+ @base.migration_file_name
14
+ end
15
+
16
+ def identical?
17
+ exists? && File.binread(existing_migration) == render
18
+ end
19
+
20
+ def revoke!
21
+ say_destination = exists? ? relative_existing_migration : relative_destination
22
+ say_status :remove, :red, say_destination
23
+ return unless exists?
24
+ ::FileUtils.rm_rf(existing_migration) unless pretend?
25
+ existing_migration
26
+ end
27
+
28
+ def relative_existing_migration
29
+ base.relative_to_original_destination_root(existing_migration)
30
+ end
31
+
32
+ def existing_migration
33
+ @existing_migration ||= begin
34
+ @base.class.migration_exists?(migration_dir, migration_file_name) ||
35
+ File.exist?(@destination) && @destination
36
+ end
37
+ end
38
+ alias :exists? :existing_migration
39
+
40
+ protected
41
+
42
+ def on_conflict_behavior(&block)
43
+ options = base.options.merge(config)
44
+ if identical?
45
+ say_status :identical, :blue, relative_existing_migration
46
+ elsif options[:force]
47
+ say_status :remove, :green, relative_existing_migration
48
+ say_status :create, :green
49
+ unless pretend?
50
+ ::FileUtils.rm_rf(existing_migration)
51
+ block.call
52
+ end
53
+ elsif options[:skip]
54
+ say_status :skip, :yellow
55
+ else
56
+ say_status :conflict, :red
57
+ raise Error, "Another migration is already named #{migration_file_name}: " +
58
+ "#{existing_migration}. Use --force to replace this migration file."
59
+ end
60
+ end
61
+
62
+ def say_status(status, color, message = relative_destination)
63
+ base.shell.say_status(status, message, color) if config[:verbose]
64
+ end
65
+ end
66
+ end
67
+ end
68
+ end
@@ -134,12 +134,12 @@ module Rails
134
134
  if options.dev?
135
135
  <<-GEMFILE.strip_heredoc
136
136
  gem 'rails', path: '#{Rails::Generators::RAILS_DEV_PATH}'
137
- gem 'arel', github: 'rails/arel'
137
+ gem 'arel', github: 'rails/arel', branch: '4-0-stable'
138
138
  GEMFILE
139
139
  elsif options.edge?
140
140
  <<-GEMFILE.strip_heredoc
141
- gem 'rails', github: 'rails/rails'
142
- gem 'arel', github: 'rails/arel'
141
+ gem 'rails', github: 'rails/rails', branch: '4-0-stable'
142
+ gem 'arel', github: 'rails/arel', branch: '4-0-stable'
143
143
  GEMFILE
144
144
  else
145
145
  <<-GEMFILE.strip_heredoc
@@ -211,7 +211,7 @@ module Rails
211
211
  return unless base_name && generator_name
212
212
  return unless default_generator_root
213
213
  path = File.join(default_generator_root, 'templates')
214
- path if File.exists?(path)
214
+ path if File.exist?(path)
215
215
  end
216
216
 
217
217
  # Returns the base root for a common set of generators. This is used to dynamically
@@ -365,12 +365,12 @@ module Rails
365
365
  source_root && File.expand_path("../USAGE", source_root),
366
366
  default_generator_root && File.join(default_generator_root, "USAGE")
367
367
  ]
368
- paths.compact.detect { |path| File.exists? path }
368
+ paths.compact.detect { |path| File.exist? path }
369
369
  end
370
370
 
371
371
  def self.default_generator_root
372
372
  path = File.expand_path(File.join(base_name, generator_name), base_root)
373
- path if File.exists?(path)
373
+ path if File.exist?(path)
374
374
  end
375
375
 
376
376
  end
@@ -1,3 +1,5 @@
1
+ require 'rails/generators/actions/create_migration'
2
+
1
3
  module Rails
2
4
  module Generators
3
5
  # Holds common methods for migrations. It assumes that migrations has the
@@ -30,6 +32,19 @@ module Rails
30
32
  end
31
33
  end
32
34
 
35
+ def create_migration(destination, data, config = {}, &block)
36
+ action Rails::Generators::Actions::CreateMigration.new(self, destination, block || data.to_s, config)
37
+ end
38
+
39
+ def set_migration_assigns!(destination)
40
+ destination = File.expand_path(destination, self.destination_root)
41
+
42
+ migration_dir = File.dirname(destination)
43
+ @migration_number = self.class.next_migration_number(migration_dir)
44
+ @migration_file_name = File.basename(destination, '.rb')
45
+ @migration_class_name = @migration_file_name.camelize
46
+ end
47
+
33
48
  # Creates a migration template at the given destination. The difference
34
49
  # to the default template method is that the migration version is appended
35
50
  # to the destination file name.
@@ -38,26 +53,18 @@ module Rails
38
53
  # available as instance variables in the template to be rendered.
39
54
  #
40
55
  # migration_template "migration.rb", "db/migrate/add_foo_to_bar.rb"
41
- def migration_template(source, destination=nil, config={})
42
- destination = File.expand_path(destination || source, self.destination_root)
56
+ def migration_template(source, destination, config = {})
57
+ source = File.expand_path(find_in_source_paths(source.to_s))
43
58
 
44
- migration_dir = File.dirname(destination)
45
- @migration_number = self.class.next_migration_number(migration_dir)
46
- @migration_file_name = File.basename(destination).sub(/\.rb$/, '')
47
- @migration_class_name = @migration_file_name.camelize
59
+ set_migration_assigns!(destination)
60
+ context = instance_eval('binding')
48
61
 
49
- destination = self.class.migration_exists?(migration_dir, @migration_file_name)
62
+ dir, base = File.split(destination)
63
+ numbered_destination = File.join(dir, ["%migration_number%", base].join('_'))
50
64
 
51
- if !(destination && options[:skip]) && behavior == :invoke
52
- if destination && options.force?
53
- remove_file(destination)
54
- elsif destination
55
- raise Error, "Another migration is already named #{@migration_file_name}: #{destination}. Use --force to remove the old migration file and replace it."
56
- end
57
- destination = File.join(migration_dir, "#{@migration_number}_#{@migration_file_name}.rb")
65
+ create_migration numbered_destination, nil, config do
66
+ ERB.new(::File.binread(source), nil, '-', '@output_buffer').result(context)
58
67
  end
59
-
60
- template(source, destination, config)
61
68
  end
62
69
  end
63
70
  end
@@ -16,7 +16,7 @@ group :doc do
16
16
  end
17
17
 
18
18
  # Use ActiveModel has_secure_password
19
- # gem 'bcrypt-ruby', '~> 3.1.2'
19
+ # gem 'bcrypt', '~> 3.1.7'
20
20
 
21
21
  # Use unicorn as the app server
22
22
  # gem 'unicorn'
@@ -13,7 +13,7 @@ require "action_mailer/railtie"
13
13
 
14
14
  # Require the gems listed in Gemfile, including any gems
15
15
  # you've limited to :test, :development, or :production.
16
- Bundler.require(:default, Rails.env)
16
+ Bundler.require(*Rails.groups)
17
17
 
18
18
  module <%= app_const_base %>
19
19
  class Application < Rails::Application
@@ -28,10 +28,5 @@ module <%= app_const_base %>
28
28
  # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
29
29
  # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
30
30
  # config.i18n.default_locale = :de
31
- <% if options.skip_sprockets? -%>
32
-
33
- # Disable the asset pipeline.
34
- config.assets.enabled = false
35
- <% end -%>
36
31
  end
37
32
  end
@@ -1,4 +1,4 @@
1
1
  # Set up gems listed in the Gemfile.
2
2
  ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)
3
3
 
4
- require 'bundler/setup' if File.exists?(ENV['BUNDLE_GEMFILE'])
4
+ require 'bundler/setup' if File.exist?(ENV['BUNDLE_GEMFILE'])
@@ -22,8 +22,8 @@
22
22
  <%- unless options.skip_active_record? -%>
23
23
  # Raise an error on page load if there are pending migrations
24
24
  config.active_record.migration_error = :page_load
25
- <%- end -%>
26
25
 
26
+ <%- end -%>
27
27
  <%- unless options.skip_sprockets? -%>
28
28
  # Debug mode disables concatenation and preprocessing of assets.
29
29
  # This option may cause significant delays in view rendering with a large
@@ -1,4 +1,4 @@
1
- # See http://www.robotstxt.org/wc/norobots.html for documentation on how to use the robots.txt file
1
+ # See http://www.robotstxt.org/robotstxt.html for documentation on how to use the robots.txt file
2
2
  #
3
3
  # To ban all spiders from the entire site uncomment the next two lines:
4
4
  # User-agent: *
@@ -60,7 +60,7 @@ Available field types:
60
60
  For decimal two integers separated by a comma in curly braces will be used
61
61
  for precision and scale:
62
62
 
63
- `rails generate model product price:decimal{10,2}`
63
+ `rails generate model product 'price:decimal{10,2}'`
64
64
 
65
65
  You can add a `:uniq` or `:index` suffix for unique or standard indexes
66
66
  respectively:
@@ -317,7 +317,7 @@ task default: :test
317
317
  @application_definition ||= begin
318
318
 
319
319
  dummy_application_path = File.expand_path("#{dummy_path}/config/application.rb", destination_root)
320
- unless options[:pretend] || !File.exists?(dummy_application_path)
320
+ unless options[:pretend] || !File.exist?(dummy_application_path)
321
321
  contents = File.read(dummy_application_path)
322
322
  contents[(contents.index(/module ([\w]+)\n(.*)class Application/m))..-1]
323
323
  end
@@ -3,5 +3,9 @@
3
3
  ENGINE_ROOT = File.expand_path('../..', __FILE__)
4
4
  ENGINE_PATH = File.expand_path('../../lib/<%= name -%>/engine', __FILE__)
5
5
 
6
+ # Set up gems listed in the Gemfile.
7
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)
8
+ require 'bundler/setup' if File.exist?(ENV['BUNDLE_GEMFILE'])
9
+
6
10
  require 'rails/all'
7
11
  require 'rails/engine/commands'
@@ -1,5 +1,5 @@
1
1
  # Set up gems listed in the Gemfile.
2
2
  ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../../../Gemfile', __FILE__)
3
3
 
4
- require 'bundler/setup' if File.exists?(ENV['BUNDLE_GEMFILE'])
4
+ require 'bundler/setup' if File.exist?(ENV['BUNDLE_GEMFILE'])
5
5
  $LOAD_PATH.unshift File.expand_path('../../../../lib', __FILE__)
@@ -22,7 +22,7 @@ module Rails
22
22
  # end
23
23
  def assert_file(relative, *contents)
24
24
  absolute = File.expand_path(relative, destination_root)
25
- assert File.exists?(absolute), "Expected file #{relative.inspect} to exist, but does not"
25
+ assert File.exist?(absolute), "Expected file #{relative.inspect} to exist, but does not"
26
26
 
27
27
  read = File.read(absolute) if block_given? || !contents.empty?
28
28
  yield read if block_given?
@@ -44,7 +44,7 @@ module Rails
44
44
  # assert_no_file "config/random.rb"
45
45
  def assert_no_file(relative)
46
46
  absolute = File.expand_path(relative, destination_root)
47
- assert !File.exists?(absolute), "Expected file #{relative.inspect} to not exist, but does"
47
+ assert !File.exist?(absolute), "Expected file #{relative.inspect} to not exist, but does"
48
48
  end
49
49
  alias :assert_no_directory :assert_no_file
50
50
 
@@ -61,9 +61,11 @@ module Rails
61
61
  # You can provide a configuration hash as second argument. This method returns the output
62
62
  # printed by the generator.
63
63
  def run_generator(args=self.default_arguments, config={})
64
- capture(:stdout) do
65
- args += ['--skip-bundle'] unless args.include? '--dev'
66
- self.generator_class.start(args, config.reverse_merge(destination_root: destination_root))
64
+ without_thor_debug do
65
+ capture(:stdout) do
66
+ args += ['--skip-bundle'] unless args.include? '--dev'
67
+ self.generator_class.start(args, config.reverse_merge(destination_root: destination_root))
68
+ end
67
69
  end
68
70
  end
69
71
 
@@ -100,6 +102,14 @@ module Rails
100
102
  dirname, file_name = File.dirname(absolute), File.basename(absolute).sub(/\.rb$/, '')
101
103
  Dir.glob("#{dirname}/[0-9]*_*.rb").grep(/\d+_#{file_name}.rb$/).first
102
104
  end
105
+
106
+ # TODO: remove this once Bundler 1.5.2 is released
107
+ def without_thor_debug # :nodoc:
108
+ thor_debug, ENV['THOR_DEBUG'] = ENV['THOR_DEBUG'], nil
109
+ yield
110
+ ensure
111
+ ENV['THOR_DEBUG'] = thor_debug
112
+ end
103
113
  end
104
114
  end
105
115
  end
@@ -203,7 +203,7 @@ module Rails
203
203
 
204
204
  # Returns all expanded paths but only if they exist in the filesystem.
205
205
  def existent
206
- expanded.select { |f| File.exists?(f) }
206
+ expanded.select { |f| File.exist?(f) }
207
207
  end
208
208
 
209
209
  def existent_directories
@@ -7,7 +7,7 @@ module Rails
7
7
  path = Pathname.new(log || "#{::File.expand_path(Rails.root)}/log/#{Rails.env}.log").cleanpath
8
8
 
9
9
  @cursor = @file = nil
10
- if ::File.exists?(path)
10
+ if ::File.exist?(path)
11
11
  @cursor = ::File.size(path)
12
12
  @file = ::File.open(path, 'r')
13
13
  end
@@ -46,7 +46,7 @@ namespace :rails do
46
46
  require 'rails/generators/rails/app/app_generator'
47
47
  gen = Rails::Generators::AppGenerator.new ["rails"], { with_dispatchers: true },
48
48
  destination_root: Rails.root
49
- File.exists?(Rails.root.join("config", "application.rb")) ?
49
+ File.exist?(Rails.root.join("config", "application.rb")) ?
50
50
  gen.send(:app_const) : gen.send(:valid_const?)
51
51
  gen
52
52
  end
@@ -67,7 +67,7 @@ namespace :rails do
67
67
  task :application_controller do
68
68
  old_style = Rails.root + '/app/controllers/application.rb'
69
69
  new_style = Rails.root + '/app/controllers/application_controller.rb'
70
- if File.exists?(old_style) && !File.exists?(new_style)
70
+ if File.exist?(old_style) && !File.exist?(new_style)
71
71
  FileUtils.mv(old_style, new_style)
72
72
  puts "#{old_style} has been renamed to #{new_style}, update your SCM as necessary"
73
73
  end
@@ -10,7 +10,7 @@ namespace :log do
10
10
  if ENV['LOGS']
11
11
  ENV['LOGS'].split(',')
12
12
  .map { |file| "log/#{file.strip}.log" }
13
- .select { |file| File.exists?(file) }
13
+ .select { |file| File.exist?(file) }
14
14
  else
15
15
  FileList["log/*.log"]
16
16
  end
@@ -2,8 +2,8 @@ module Rails
2
2
  module VERSION
3
3
  MAJOR = 4
4
4
  MINOR = 0
5
- TINY = 3
6
- PRE = nil
5
+ TINY = 4
6
+ PRE = "rc1"
7
7
 
8
8
  STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".")
9
9
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: railties
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.0.3
4
+ version: 4.0.4.rc1
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Heinemeier Hansson
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-02-18 00:00:00.000000000 Z
11
+ date: 2014-03-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -16,28 +16,28 @@ dependencies:
16
16
  requirements:
17
17
  - - '='
18
18
  - !ruby/object:Gem::Version
19
- version: 4.0.3
19
+ version: 4.0.4.rc1
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - '='
25
25
  - !ruby/object:Gem::Version
26
- version: 4.0.3
26
+ version: 4.0.4.rc1
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: actionpack
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - '='
32
32
  - !ruby/object:Gem::Version
33
- version: 4.0.3
33
+ version: 4.0.4.rc1
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - '='
39
39
  - !ruby/object:Gem::Version
40
- version: 4.0.3
40
+ version: 4.0.4.rc1
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rake
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -116,6 +116,7 @@ files:
116
116
  - lib/rails/engine/railties.rb
117
117
  - lib/rails/generators.rb
118
118
  - lib/rails/generators/actions.rb
119
+ - lib/rails/generators/actions/create_migration.rb
119
120
  - lib/rails/generators/active_model.rb
120
121
  - lib/rails/generators/app_base.rb
121
122
  - lib/rails/generators/base.rb
@@ -320,12 +321,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
320
321
  version: 1.9.3
321
322
  required_rubygems_version: !ruby/object:Gem::Requirement
322
323
  requirements:
323
- - - ">="
324
+ - - ">"
324
325
  - !ruby/object:Gem::Version
325
- version: '0'
326
+ version: 1.3.1
326
327
  requirements: []
327
328
  rubyforge_project:
328
- rubygems_version: 2.2.0
329
+ rubygems_version: 2.2.2
329
330
  signing_key:
330
331
  specification_version: 4
331
332
  summary: Tools for creating, working with, and running Rails applications.