123456789_123456789_123456789_123456789_123456789_

Class: Rails::Generators::Db::System::ChangeGenerator

Do not use. This class is for internal use only.
Relationships & Source Files
Super Chains via Extension / Inclusion / Inheritance
Class Chain:
self, ::Rails::Generators::Base, Thor::Group
Instance Chain:
Inherits: Rails::Generators::Base
Defined in: railties/lib/rails/generators/rails/db/system/change/change_generator.rb

Constant Summary

::Rails::Generators::AppName - Included

RESERVED_NAMES

Class Attribute Summary

Class Method Summary

::Rails::Generators::Base - Inherited

.base_root

Returns the base root for a common set of generators.

.default_source_root

Returns the default source root for a given generator.

.desc

Tries to get the description from a USAGE file one folder above the source root otherwise uses a default description.

.hide!

Convenience method to hide this generator from the available ones when running rails generator command.

.hook_for

Invoke a generator based on the value supplied by the user to the given option named “name”.

.namespace

Convenience method to get the namespace from the class name.

.remove_hook_for

Remove a previously added hook.

.source_root

Returns the source root for this generator using default_source_root as default.

.add_shebang_option!

Small macro to add ruby as an option to the generator with proper default value plus an instance helper method called shebang.

.banner

Use Rails default banner.

.base_name

Sets the base_name taking into account the current class namespace.

.default_aliases_for_option

Returns default aliases for the option name given doing a lookup in Rails::Generators.aliases.

.default_for_option

Returns default for the option name given doing a lookup in config.

.default_generator_root,
.default_value_for_option

Returns the default value for the option name given doing a lookup in Rails::Generators.options.

.generator_name

Removes the namespaces and get the generator name.

.usage_path,
.class_option
.inherited

Cache source root and add lib/generators/base/generator/templates to source paths.

.hooks

Keep hooks configuration that are used on prepare_for_invocation.

.prepare_for_invocation

Prepare class invocation to search on ::Rails namespace if a previous added hook is being used.

Instance Attribute Summary

Instance Method Summary

::Rails::Generators::AppName - Included

::Rails::Generators::Base - Inherited

#class_collisions

Check whether the given class names are already taken by user application or Ruby on ::Rails.

#extract_last_module

Takes in an array of nested modules and extracts the last module.

#indent,
#module_namespacing

Wrap block with namespace of current application if namespace exists and is not skipped.

#namespace, #namespace_dirs, #namespaced_path, #wrap_with_namespace

::Rails::Generators::Actions - Included

#add_source

Add the given source to Gemfile

#application
#environment

Adds configuration code to a Rails runtime environment.

#gem

Adds a gem declaration to the Gemfile for the specified gem.

#gem_group

Wraps gem entries inside a group.

#generate

Runs another generator.

#git

Runs one or more git commands.

#github,
#initializer

Creates an initializer file in config/initializers/.

#lib

Creates a file in lib/.

#rails_command

Runs the specified Rails command.

#rake

Runs the specified Rake task.

#rakefile

Creates a Rake tasks file in lib/tasks/.

#readme

Reads the given file at the source root and prints it in the console.

#route

Make an entry in Rails routing file config/routes.rb.

#vendor

Creates a file in vendor/.

#append_file_with_newline

Append string to a file with a newline if necessary.

#execute_command

Runs the supplied command using either “rake …” or “rails …” based on the executor parameter provided.

#indentation

Indent the Gemfile to the depth of @indentation.

#log

Define log for backwards compatibility.

#match_file,
#optimize_indentation

Returns optimized string with indentation.

#quote

Always returns value in double quotes.

#rebase_indentation
#route_namespace_pattern,
#with_indentation

Manage Gemfile indentation for a DSL action block.

#initialize

Constructor Details

.newChangeGenerator

[ GitHub ]

  
# File 'railties/lib/rails/generators/rails/db/system/change/change_generator.rb', line 25

def initialize(*)
  super

  unless Database::DATABASES.include?(options[:to])
    raise Error, "Invalid value for --to option. Supported preconfigurations are: #{Database::DATABASES.join(", ")}."
  end

  opt = options.dup
  opt[:database] ||= opt[:to]
  self.options = opt.freeze
end

Class Method Details

.default_generator_root

[ GitHub ]

  
# File 'railties/lib/rails/generators/rails/db/system/change/change_generator.rb', line 20

def self.default_generator_root
  path = File.expand_path(File.join(base_name, "app"), base_root)
  path if File.exist?(path)
end

Instance Attribute Details

#devcontainer?Boolean (readonly, private)

[ GitHub ]

  
# File 'railties/lib/rails/generators/rails/db/system/change/change_generator.rb', line 197

def devcontainer?
  return @devcontainer if defined?(@devcontainer)

  @devcontainer = File.exist?(File.expand_path(".devcontainer", destination_root))
end

Instance Method Details

#all_database_gems (private)

[ GitHub ]

  
# File 'railties/lib/rails/generators/rails/db/system/change/change_generator.rb', line 63

def all_database_gems
  Database.all.map { |database| database.gem }
end

#all_database_gems_regex (private)

[ GitHub ]

  
# File 'railties/lib/rails/generators/rails/db/system/change/change_generator.rb', line 91

def all_database_gems_regex
  all_database_gem_names = all_database_gems.map(&:first)
  /(\b#{all_database_gem_names.join('\b|\b')}\b)/
end

#all_docker_bases (private)

[ GitHub ]

  
# File 'railties/lib/rails/generators/rails/db/system/change/change_generator.rb', line 67

def all_docker_bases
  Database.all.map { |database| docker_base_packages(database.base_package) }.uniq
end

#all_docker_bases_regex (private)

[ GitHub ]

  
# File 'railties/lib/rails/generators/rails/db/system/change/change_generator.rb', line 96

def all_docker_bases_regex
  /(\b#{all_docker_bases.join('\b|\b')}\b)/
end

#all_docker_builds (private)

[ GitHub ]

  
# File 'railties/lib/rails/generators/rails/db/system/change/change_generator.rb', line 79

def all_docker_builds
  Database.all.map { |database| docker_build_packages(database.build_package) }.uniq
end

#all_docker_builds_regex (private)

[ GitHub ]

  
# File 'railties/lib/rails/generators/rails/db/system/change/change_generator.rb', line 100

def all_docker_builds_regex
  /(\b#{all_docker_builds.join('\b|\b')}\b)/
end

#database (private)

[ GitHub ]

  
# File 'railties/lib/rails/generators/rails/db/system/change/change_generator.rb', line 193

def database
  @database ||= Database.build(options[:database])
end

#devcontainer_json (private)

[ GitHub ]

  
# File 'railties/lib/rails/generators/rails/db/system/change/change_generator.rb', line 183

def devcontainer_json
  return unless File.exist?(devcontainer_json_path)

  @devcontainer_json ||= JSON.parse(File.read(devcontainer_json_path))
end

#devcontainer_json_path (private)

[ GitHub ]

  
# File 'railties/lib/rails/generators/rails/db/system/change/change_generator.rb', line 189

def devcontainer_json_path
  File.expand_path(".devcontainer/devcontainer.json", destination_root)
end

#docker_base_packages(database_package) (private)

[ GitHub ]

  
# File 'railties/lib/rails/generators/rails/db/system/change/change_generator.rb', line 71

def docker_base_packages(database_package)
  if database_package
    [database_package].concat(BASE_PACKAGES).sort
  else
    BASE_PACKAGES
  end.join("\s")
end

#docker_build_packages(database_package) (private)

[ GitHub ]

  
# File 'railties/lib/rails/generators/rails/db/system/change/change_generator.rb', line 83

def docker_build_packages(database_package)
  if database_package
    [database_package].concat(BUILD_PACKAGES).sort
  else
    BUILD_PACKAGES
  end.join("\s")
end

#edit_compose_yaml (private)

[ GitHub ]

  
# File 'railties/lib/rails/generators/rails/db/system/change/change_generator.rb', line 120

def edit_compose_yaml
  compose_yaml_path = File.expand_path(".devcontainer/compose.yaml", destination_root)
  return unless File.exist?(compose_yaml_path)

  compose_config = YAML.load_file(compose_yaml_path)

  Database.all.each do |database|
    compose_config["services"].delete(database.name)
    compose_config["volumes"]&.delete(database.volume)
    compose_config["services"]["rails-app"]["depends_on"]&.delete(database.name)
  end

  if database.service
    compose_config["services"][database.name] = database.service
    compose_config["volumes"] = { database.volume => nil }.merge(compose_config["volumes"] || {})
    compose_config["services"]["rails-app"]["depends_on"] = [
      database.name,
      compose_config["services"]["rails-app"]["depends_on"]
    ].flatten.compact
  end

  compose_config.delete("volumes") unless compose_config["volumes"]&.any?
  compose_config["services"]["rails-app"].delete("depends_on") unless compose_config["services"]["rails-app"]["depends_on"]&.any?

  File.write(compose_yaml_path, compose_config.to_yaml)
end

#edit_database_config

[ GitHub ]

  
# File 'railties/lib/rails/generators/rails/db/system/change/change_generator.rb', line 37

def edit_database_config
  template(database.template, "config/database.yml")
end

#edit_devcontainer_files

[ GitHub ]

  
# File 'railties/lib/rails/generators/rails/db/system/change/change_generator.rb', line 55

def edit_devcontainer_files
  return unless devcontainer?

  edit_devcontainer_json
  edit_compose_yaml
end

#edit_devcontainer_json (private)

[ GitHub ]

  
# File 'railties/lib/rails/generators/rails/db/system/change/change_generator.rb', line 113

def edit_devcontainer_json
  return unless devcontainer_json

  update_devcontainer_db_host
  update_devcontainer_db_feature
end

#edit_dockerfile

[ GitHub ]

  
# File 'railties/lib/rails/generators/rails/db/system/change/change_generator.rb', line 47

def edit_dockerfile
  dockerfile_path = File.expand_path("Dockerfile", destination_root)
  return unless File.exist?(dockerfile_path)

  gsub_file("Dockerfile", all_docker_bases_regex, docker_base_packages(database.base_package))
  gsub_file("Dockerfile", all_docker_builds_regex, docker_build_packages(database.build_package))
end

#edit_gemfile

[ GitHub ]

  
# File 'railties/lib/rails/generators/rails/db/system/change/change_generator.rb', line 41

def edit_gemfile
  name, version = database.gem
  gsub_file("Gemfile", all_database_gems_regex, name)
  gsub_file("Gemfile", gem_entry_regex_for(name), gem_entry_for(name, *version))
end

#gem_entry_for(*gem_name_and_version) (private)

[ GitHub ]

  
# File 'railties/lib/rails/generators/rails/db/system/change/change_generator.rb', line 108

def gem_entry_for(*gem_name_and_version)
  gem_name_and_version.map! { |segment| "\"#{segment}\"" }
  "gem #{gem_name_and_version.join(", ")}"
end

#gem_entry_regex_for(gem_name) (private)

[ GitHub ]

  
# File 'railties/lib/rails/generators/rails/db/system/change/change_generator.rb', line 104

def gem_entry_regex_for(gem_name)
  /^gem.*\b#{gem_name}\b.*/
end

#update_devcontainer_db_feature (private)

[ GitHub ]

  
# File 'railties/lib/rails/generators/rails/db/system/change/change_generator.rb', line 168

def update_devcontainer_db_feature
  features = devcontainer_json["features"]
  db_feature = database.feature

  Database.all.each do |database|
    features.delete(database.feature_name)
  end

  features.merge!(db_feature) if db_feature

  new_json = JSON.pretty_generate(features, indent: "  ", object_nl: "\n  ")

  gsub_file(".devcontainer/devcontainer.json", /("features"\s*:\s*)(.|\n)*?(^\s{2}})/, "\\1#{new_json}")
end

#update_devcontainer_db_host (private)

[ GitHub ]

  
# File 'railties/lib/rails/generators/rails/db/system/change/change_generator.rb', line 147

def update_devcontainer_db_host
  container_env = devcontainer_json["containerEnv"]
  db_name = database.name

  if container_env["DB_HOST"]
    if database.service
      container_env["DB_HOST"] = db_name
    else
      container_env.delete("DB_HOST")
    end
  else
    if database.service
      container_env["DB_HOST"] = db_name
    end
  end

  new_json = JSON.pretty_generate(container_env, indent: "  ", object_nl: "\n  ")

  gsub_file(".devcontainer/devcontainer.json", /("containerEnv"\s*:\s*)(.|\n)*?(^\s{2}})/, "\\1#{new_json}")
end