lib/generators/dockerfile_generator.rb in dockerfile-rails-1.0.18 vs lib/generators/dockerfile_generator.rb in dockerfile-rails-1.1.0
- old
+ new
@@ -1,192 +1,242 @@
-require 'erb'
-require_relative '../dockerfile-rails/scanner.rb'
+# frozen_string_literal: true
+require "erb"
+require_relative "../dockerfile-rails/scanner.rb"
+
class DockerfileGenerator < Rails::Generators::Base
include DockerfileRails::Scanner
- OPTION_DEFAULTS = OpenStruct.new(
- 'bin-cd' => false,
- 'cache' => false,
- 'ci' => false,
- 'compose' => false,
- 'fullstaq' => false,
- 'jemalloc' => false,
- 'label' => {},
- 'mysql' => false,
- 'nginx' => false,
- 'parallel' => false,
- 'platform' => nil,
- 'postgresql' => false,
- 'precompile' => nil,
- 'prepare' => true,
- 'redis' => false,
- 'root' => false,
- 'swap' => nil,
- 'yjit' => false,
- )
+ OPTION_DEFAULTS = {
+ "bin-cd" => false,
+ "cache" => false,
+ "ci" => false,
+ "compose" => false,
+ "fullstaq" => false,
+ "jemalloc" => false,
+ "label" => {},
+ "mysql" => false,
+ "nginx" => false,
+ "parallel" => false,
+ "platform" => nil,
+ "postgresql" => false,
+ "precompile" => nil,
+ "prepare" => true,
+ "redis" => false,
+ "root" => false,
+ "sqlite3" => false,
+ "swap" => nil,
+ "yjit" => false,
+ }.then { |hash| Struct.new(*hash.keys.map(&:to_sym)).new(*hash.values) }
@@labels = {}
- @@packages = {"base" => [], "build" => [], "deploy" => []}
+ @@packages = { "base" => [], "build" => [], "deploy" => [] }
+ @@vars = { "base" => {}, "build" => {}, "deploy" => {} }
+ @@args = { "base" => {}, "build" => {}, "deploy" => {} }
# load defaults from config file
- if File.exist? 'config/dockerfile.yml'
- options = YAML.safe_load(IO.read('config/dockerfile.yml'), symbolize_names: true)[:options]
+ if File.exist? "config/dockerfile.yml"
+ options = YAML.safe_load(IO.read("config/dockerfile.yml"), symbolize_names: true)[:options]
if options
OPTION_DEFAULTS.to_h.each do |option, value|
- OPTION_DEFAULTS[option] = options[option] if options.include? option
+ OPTION_DEFAULTS[option] = options[option] if options.include? option
end
if options[:packages]
options[:packages].each do |stage, list|
@@packages[stage.to_s] = list
end
end
+ if options[:envs]
+ options[:envs].each do |stage, vars|
+ @@vars[stage.to_s] = vars.stringify_keys
+ end
+ end
+
+ if options[:args]
+ options[:args].each do |stage, vars|
+ @@args[stage.to_s] = vars.stringify_keys
+ end
+ end
+
@@labels = options[:label].stringify_keys if options.include? :label
end
end
class_option :ci, type: :boolean, default: OPTION_DEFAULTS.ci,
- desc: 'include test gems in bundle'
+ desc: "include test gems in bundle"
class_option :precompile, type: :string, default: OPTION_DEFAULTS.precompile,
desc: 'if set to "defer", assets:precompile will be done at deploy time'
- class_option 'bin-cd', type: :boolean, default: OPTION_DEFAULTS['bin-cd'],
- desc: 'modify binstubs to set working directory'
+ class_option "bin-cd", type: :boolean, default: OPTION_DEFAULTS["bin-cd"],
+ desc: "modify binstubs to set working directory"
class_option :cache, type: :boolean, default: OPTION_DEFAULTS.cache,
- desc: 'use build cache to speed up installs'
+ desc: "use build cache to speed up installs"
class_option :prepare, type: :boolean, default: OPTION_DEFAULTS.prepare,
- desc: 'include db:prepare step'
+ desc: "include db:prepare step"
class_option :parallel, type: :boolean, default: OPTION_DEFAULTS.parallel,
- desc: 'use build stages to install gems and node modules in parallel'
+ desc: "use build stages to install gems and node modules in parallel"
class_option :swap, type: :string, default: OPTION_DEFAULTS.swap,
- desc: 'allocate swapspace'
+ desc: "allocate swapspace"
class_option :compose, type: :boolean, default: OPTION_DEFAULTS.compose,
- desc: 'generate a docker-compose.yml file'
+ desc: "generate a docker-compose.yml file"
class_option :redis, type: :boolean, default: OPTION_DEFAULTS.redis,
- desc: 'include redis libraries'
+ desc: "include redis libraries"
- class_option :sqlite3, aliases: '--sqlite', type: :boolean, default: OPTION_DEFAULTS.sqlite3,
- desc: 'include sqlite3 libraries'
+ class_option :sqlite3, aliases: "--sqlite", type: :boolean, default: OPTION_DEFAULTS.sqlite3,
+ desc: "include sqlite3 libraries"
- class_option :postgresql, aliases: '--postgres', type: :boolean, default: OPTION_DEFAULTS.postgresql,
- desc: 'include postgresql libraries'
+ class_option :postgresql, aliases: "--postgres", type: :boolean, default: OPTION_DEFAULTS.postgresql,
+ desc: "include postgresql libraries"
class_option :mysql, type: :boolean, default: OPTION_DEFAULTS.mysql,
- desc: 'include mysql libraries'
+ desc: "include mysql libraries"
class_option :platform, type: :string, default: OPTION_DEFAULTS.platform,
- desc: 'image platform (example: linux/arm64)'
+ desc: "image platform (example: linux/arm64)"
class_option :jemalloc, type: :boolean, default: OPTION_DEFAULTS.jemalloc,
- desc: 'use jemalloc alternative malloc implementation'
-
+ desc: "use jemalloc alternative malloc implementation"
+
class_option :fullstaq, type: :boolean, default: OPTION_DEFAULTS.fullstaq,
- descr: 'use Fullstaq Ruby image from Quay.io'
+ descr: "use Fullstaq Ruby image from Quay.io"
class_option :yjit, type: :boolean, default: OPTION_DEFAULTS.yjit,
- desc: 'enable YJIT optimizing compiler'
+ desc: "enable YJIT optimizing compiler"
class_option :label, type: :hash, default: {},
- desc: 'Add Docker label(s)'
+ desc: "Add Docker label(s)"
class_option :nginx, type: :boolean, default: OPTION_DEFAULTS.nginx,
- desc: 'Serve static files with nginx'
+ desc: "Serve static files with nginx"
class_option :root, type: :boolean, default: OPTION_DEFAULTS.root,
- desc: 'Run application as root user'
+ desc: "Run application as root user"
- class_option 'add-base', type: :array, default: [],
- desc: 'additional packages to install for both build and deploy'
- class_option 'add-build', type: :array, default: [],
- desc: 'additional packages to install for use during build'
+ class_option "add-base", type: :array, default: [],
+ desc: "additional packages to install for both build and deploy"
- class_option 'add-deploy', aliases: '--add', type: :array, default: [],
- desc: 'additional packages to install for deployment'
+ class_option "add-build", type: :array, default: [],
+ desc: "additional packages to install for use during build"
- class_option 'remove-base', type: :array, default: [],
- desc: 'remove from list of base packages'
+ class_option "add-deploy", aliases: "--add", type: :array, default: [],
+ desc: "additional packages to install for deployment"
- class_option 'remove-build', type: :array, default: [],
- desc: 'remove from list of build packages'
+ class_option "remove-base", type: :array, default: [],
+ desc: "remove from list of base packages"
- class_option 'remove-deploy', aliases: '--remove', type: :array, default: [],
- desc: 'remove from list of deploy packages'
+ class_option "remove-build", type: :array, default: [],
+ desc: "remove from list of build packages"
+ class_option "remove-deploy", aliases: "--remove", type: :array, default: [],
+ desc: "remove from list of deploy packages"
+
+
+ class_option "env-base", type: :hash, default: {},
+ desc: "additional environment variables for both build and deploy"
+
+ class_option "env-build", type: :hash, default: {},
+ desc: "additional environment variables to set during build"
+
+ class_option "env-deploy", aliases: "--env", type: :hash, default: {},
+ desc: "additional environment variables to set for deployment"
+
+
+ class_option "arg-base", aliases: "--arg", type: :hash, default: {},
+ desc: "additional build arguments for both build and deploy"
+
+ class_option "arg-build", type: :hash, default: {},
+ desc: "additional build arguments to set during build"
+
+ class_option "arg-deploy", type: :hash, default: {},
+ desc: "additional build arguments to set for deployment"
+
+
def generate_app
- source_paths.push File.expand_path('./templates', __dir__)
+ source_paths.push File.expand_path("./templates", __dir__)
# merge options
- options.label.replace(@@labels.merge(options.label).select {|key, value| value != ''})
+ options.label.replace(@@labels.merge(options.label).select { |key, value| value != "" })
# gather up options for config file
@dockerfile_config = OPTION_DEFAULTS.dup.to_h.stringify_keys
options.to_h.each do |option, value|
@dockerfile_config[option] = value if @dockerfile_config.include? option
end
- # apply requested package changes
%w(base build deploy).each do |phase|
@@packages[phase] += options["add-#{phase}"]
@@packages[phase] -= options["remove-#{phase}"]
@@packages[phase].uniq!
@@packages.delete phase if @@packages[phase].empty?
+
+ @@vars[phase].merge! options["env-#{phase}"]
+ @@vars[phase].delete_if { |key, value| value.blank? }
+ @@vars.delete phase if @@vars[phase].empty?
+
+ @@args[phase].merge! options["arg-#{phase}"]
+ @@args[phase].delete_if { |key, value| value.blank? }
+ @@args.delete phase if @@args[phase].empty?
end
- @dockerfile_config['packages'] = @@packages
+ @dockerfile_config["packages"] = @@packages
+ @dockerfile_config["envs"] = @@vars
+ @dockerfile_config["args"] = @@args
scan_rails_app
Bundler.with_original_env { install_gems }
- template 'Dockerfile.erb', 'Dockerfile'
- template 'dockerignore.erb', '.dockerignore'
+ template "Dockerfile.erb", "Dockerfile"
+ template "dockerignore.erb", ".dockerignore"
- if using_node? and node_version =~ /\A\d+\.\d+\.\d+\z/
- template 'node-version.erb', '.node-version'
+ if using_node? && node_version =~ (/\A\d+\.\d+\.\d+\z/)
+ template "node-version.erb", ".node-version"
end
- template 'docker-entrypoint.erb', 'bin/docker-entrypoint'
+ template "docker-entrypoint.erb", "bin/docker-entrypoint"
chmod "bin/docker-entrypoint", 0755 & ~File.umask, verbose: false
- template 'docker-compose.yml.erb', 'docker-compose.yml' if options.compose
+ template "docker-compose.yml.erb", "docker-compose.yml" if options.compose
- template 'dockerfile.yml.erb', 'config/dockerfile.yml', force: true
+ template "dockerfile.yml.erb", "config/dockerfile.yml", force: true
- if @gemfile.include?('vite_ruby')
- package = JSON.load_file('package.json')
- unless package.dig('scripts', 'build')
- package['scripts'] ||= {}
- package['scripts']['build'] = 'vite build --outDir public'
+ if @gemfile.include?("vite_ruby")
+ package = JSON.load_file("package.json")
+ unless package.dig("scripts", "build")
+ package["scripts"] ||= {}
+ package["scripts"]["build"] = "vite build --outDir public"
- say_status :update, 'package.json'
- IO.write('package.json', JSON.pretty_generate(package))
+ say_status :update, "package.json"
+ IO.write("package.json", JSON.pretty_generate(package))
end
end
end
private
-
def render(options)
scope = (Class.new do
def initialize(obj, locals)
@_obj = obj
- @_locals = OpenStruct.new(locals)
+ @_locals = locals.then do |hash|
+ return nil if hash.empty?
+ Struct.new(*hash.keys.map(&:to_sym)).new(*hash.values)
+ end
end
def method_missing(method, *args, &block)
- if @_locals.respond_to? method
+ if @_locals&.respond_to? method
@_locals.send method, *args, &block
else
@_obj.send method, *args, &block
end
end
@@ -195,11 +245,11 @@
binding
end
end).new(self, options[:locals] || {})
template = IO.read(File.join(source_paths.last, "_#{options[:partial]}.erb"))
- ERB.new(template, trim_mode: '-').result(scope.get_binding).strip
+ ERB.new(template, trim_mode: "-").result(scope.get_binding).strip
end
def platform
if options.platform
"--platform #{options.platform} "
@@ -207,60 +257,60 @@
""
end
end
def run_as_root?
- true # options.root? || options.nginx?
+ options.root? || options.nginx? # needed to access /dev/stdout
end
def using_node?
return @using_node if @using_node != nil
- @using_node = File.exist? 'package.json'
+ @using_node = File.exist? "package.json"
end
def using_redis?
- options.redis? or @redis or @gemfile.include?('sidekiq')
+ options.redis? or @redis or @gemfile.include?("sidekiq")
end
def using_execjs?
- @gemfile.include?('execjs') or @gemfile.include?('grover')
+ @gemfile.include?("execjs") or @gemfile.include?("grover")
end
def using_puppeteer?
- @gemfile.include?('grover') or @gemfile.include?('puppeteer-ruby')
+ @gemfile.include?("grover") or @gemfile.include?("puppeteer-ruby")
end
def using_sidekiq?
- @gemfile.include?('sidekiq')
+ @gemfile.include?("sidekiq")
end
def parallel?
using_node? && options.parallel
end
def keeps?
return @keeps if @keeps != nil
- @keeps = !!Dir['**/.keep']
+ @keeps = !!Dir["**/.keep"]
end
def install_gems
- if options.postgresql? or @postgresql
- system "bundle add pg" unless @gemfile.include? 'pg'
+ if options.postgresql? || @postgresql
+ system "bundle add pg" unless @gemfile.include? "pg"
end
- if options.mysql? or @mysql
- system "bundle add mysql2" unless @gemfile.include? 'mysql2'
+ if options.mysql? || @mysql
+ system "bundle add mysql2" unless @gemfile.include? "mysql2"
end
- if options.redis? or using_redis?
- system "bundle add redis" unless @gemfile.include? 'redis'
+ if options.redis? || using_redis?
+ system "bundle add redis" unless @gemfile.include? "redis"
end
end
def base_packages
packages = []
- packages += @@packages['base'] if @@packages['base']
+ packages += @@packages["base"] if @@packages["base"]
if using_execjs?
packages += %w(curl unzip)
end
@@ -268,55 +318,55 @@
packages += %w(curl gnupg)
end
# charlock_holmes. Placed here as the library itself is
# libicu63 in buster, libicu67 in bullseye, libiclu72 in bookworm...
- packages << "libicu-dev" if @gemfile.include? 'charlock_holmes'
+ packages << "libicu-dev" if @gemfile.include? "charlock_holmes"
- if @gemfile.include? 'webp-ffi'
+ if @gemfile.include? "webp-ffi"
# https://github.com/le0pard/webp-ffi#requirements
packages += %w(libjpeg-dev libpng-dev libtiff-dev libwebp-dev)
end
packages.sort.uniq
end
def base_requirements
requirements = []
- requirements << 'nodejs' if using_execjs?
- requirements << 'chrome' if using_puppeteer?
- requirements << "charlock_holmes" if @gemfile.include? 'charlock_holmes'
- requirements.join(' and ')
+ requirements << "nodejs" if using_execjs?
+ requirements << "chrome" if using_puppeteer?
+ requirements << "charlock_holmes" if @gemfile.include? "charlock_holmes"
+ requirements.join(" and ")
end
def build_packages
# start with the essentials
packages = %w(build-essential)
- packages += @@packages['build'] if @@packages['build']
+ packages += @@packages["build"] if @@packages["build"]
# add databases: sqlite3, postgres, mysql
- packages << 'pkg-config' if options.sqlite3? or @sqlite3
- packages << 'libpq-dev' if options.postgresql? or @postgresql
- packages << 'default-libmysqlclient-dev' if options.mysql? or @mysql
+ packages << "pkg-config" if options.sqlite3? || @sqlite3
+ packages << "libpq-dev" if options.postgresql? || @postgresql
+ packages << "default-libmysqlclient-dev" if options.mysql? || @mysql
# add git if needed to install gems
- packages << 'git' if @git
+ packages << "git" if @git
# add redis if Action Cable, caching, or sidekiq are used
- packages << "redis" if options.redis? or using_redis?
+ packages << "redis" if options.redis? || using_redis?
# ActiveStorage preview support
- packages << "libvips" if @gemfile.include? 'ruby-vips'
+ packages << "libvips" if @gemfile.include? "ruby-vips"
# Rmagick gem
- packages += %w[pkg-config libmagickwand-dev] if @gemfile.include? 'rmagick'
+ packages += %w[pkg-config libmagickwand-dev] if @gemfile.include? "rmagick"
# node support, including support for building native modules
if using_node?
packages += %w(node-gyp pkg-config)
- packages += %w(curl unzip) unless using_execjs? or using_puppeteer?
+ packages += %w(curl unzip) unless using_execjs? || using_puppeteer?
# module build process depends on Python, and debian changed
# how python is installed with the bullseye release. Below
# is based on debian release included with the Ruby images on
# Dockerhub.
@@ -341,33 +391,33 @@
packages.sort.uniq
end
def deploy_packages
packages = []
- packages += @@packages['deploy'] if @@packages['deploy']
+ packages += @@packages["deploy"] if @@packages["deploy"]
# start with databases: sqlite3, postgres, mysql
- packages << 'libsqlite3-0' if options.sqlite3? or @sqlite3
- packages << 'postgresql-client' if options.postgresql? or @postgresql
- packages << 'default-mysql-client' if options.mysql or @mysql
+ packages << "libsqlite3-0" if options.sqlite3? || @sqlite3
+ packages << "postgresql-client" if options.postgresql? || @postgresql
+ packages << "default-mysql-client" if options.mysql || @mysql
# add redis in case Action Cable, caching, or sidekiq are added later
packages << "redis" if using_redis?
# ActiveStorage preview support
- packages << "libvips" if @gemfile.include? 'ruby-vips'
+ packages << "libvips" if @gemfile.include? "ruby-vips"
# Rmagick gem
- if @gemfile.include?('rmagick') or @gemfile.include?('mini_magick')
- packages << 'imagemagick'
+ if @gemfile.include?("rmagick") || @gemfile.include?("mini_magick")
+ packages << "imagemagick"
end
# Puppeteer
- packages << 'google-chrome-stable' if using_puppeteer?
+ packages << "google-chrome-stable" if using_puppeteer?
# nginx
- packages << 'nginx' if options.nginx?
+ packages << "nginx" if options.nginx?
packages.sort
end
def deploy_repos
@@ -380,154 +430,230 @@
'echo "deb http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google.list'
]
end
if repos.empty?
- ''
+ ""
else
repos.join(" \\\n ") + " && \\\n "
end
end
+ def base_env
+ env = {
+ "RAILS_ENV" => "production",
+ "BUNDLE_PATH" => "vendor/bundle",
+ "BUNDLE_WITHOUT" => options.ci? ? "development" : "development:test"
+ }
+
+ if @@args["base"]
+ env.merge! @@args["base"].to_h { |key, value| [key, "$#{key}"] }
+ end
+
+ env.merge! @@vars["base"] if @@vars["base"]
+
+ env.map { |key, value| "#{key}=#{value.inspect}" }
+ end
+
+ def build_env
+ env = {}
+
+ if @@args["build"]
+ env.merge! @@args["build"].to_h { |key, value| [key, "$#{key}"] }
+ end
+
+ env.merge! @@vars["build"] if @@vars["build"]
+
+ env.map { |key, value| "#{key}=#{value.inspect}" }
+ end
+
def deploy_env
- env = []
+ env = {}
- env << 'PORT="3001"' if options.nginx?
+ env["PORT"] = "3001" if options.nginx?
- if Rails::VERSION::MAJOR<7 || Rails::VERSION::STRING.start_with?('7.0')
- env << 'RAILS_LOG_TO_STDOUT="1"'
- env << 'RAILS_SERVE_STATIC_FILES="true"' unless options.nginx?
+ if Rails::VERSION::MAJOR < 7 || Rails::VERSION::STRING.start_with?("7.0")
+ env["RAILS_LOG_TO_STDOUT"] = "1"
+ env["RAILS_SERVE_STATIC_FILES"] = "true" unless options.nginx?
end
if options.yjit?
- env << 'RUBY_YJIT_ENABLE="1"'
+ env["RUBY_YJIT_ENABLE"] = "1"
end
- if options.jemalloc? and not options.fullstaq?
- if (options.platform || Gem::Platform::local.cpu).include? 'arm'
- env << 'LD_PRELOAD="/usr/lib/aarch64-linux-gnu/libjemalloc.so.2"'
+ if options.jemalloc? && (not options.fullstaq?)
+ if (options.platform || Gem::Platform.local.cpu).include? "arm"
+ env["LD_PRELOAD"] = "/usr/lib/aarch64-linux-gnu/libjemalloc.so.2"
else
- env << 'LD_PRELOAD="/usr/lib/x86_64-linux-gnu/libjemalloc.so.2"'
+ env["LD_PRELOAD"] = "/usr/lib/x86_64-linux-gnu/libjemalloc.so.2"
end
- env << 'MALLOC_CONF="dirty_decay_ms:1000,narenas:2,background_thread:true"'
+ env["MALLOC_CONF"] = "dirty_decay_ms:1000,narenas:2,background_thread:true"
end
if using_puppeteer?
- env << 'GROVER_NO_SANDBOX="true"' if @gemfile.include? 'grover'
- env << 'PUPPETEER_RUBY_NO_SANDBOX="1"' if @gemfile.include? 'puppeteer-ruby'
- env << 'PUPPETEER_EXECUTABLE_PATH="/usr/bin/google-chrome"'
+ if options.root?
+ env["GROVER_NO_SANDBOX"] = "true" if @gemfile.include? "grover"
+ env["PUPPETEER_RUBY_NO_SANDBOX"] = "1" if @gemfile.include? "puppeteer-ruby"
+ end
+
+ env["PUPPETEER_EXECUTABLE_PATH"] = "/usr/bin/google-chrome"
end
- env
+ if @@args["deploy"]
+ env.merge! @@args["deploy"].to_h { |key, value| [key, "$#{key}"] }
+ end
+
+ env.merge! @@vars["base"] if @@vars["base"]
+
+ env.map { |key, value| "#{key}=#{value.inspect}" }
end
+ def base_args
+ args = {}
+
+ args.merge! @@args["base"] if @@args["base"]
+
+ args
+ end
+
+ def build_args
+ args = {}
+
+ args.merge! @@args["build"] if @@args["build"]
+
+ args
+ end
+
+ def deploy_args
+ args = {}
+
+ args.merge! @@args["deploy"] if @@args["deploy"]
+
+ args
+ end
+
+ def all_args
+ args = {}
+
+ unless options.root?
+ args[:UID] = "${UID:-1000}".html_safe
+ args[:GID] = "${GID:-${UID:-1000}}".html_safe
+ end
+
+ args.merge! base_args
+ args.merge! build_args
+ args.merge! deploy_args
+
+ args
+ end
+
def binfile_fixups
# binfiles may have OS specific paths to ruby. Normalize them.
shebangs = Dir["bin/*"].map { |file| IO.read(file).lines.first }.join
rubies = shebangs.scan(%r{#!/usr/bin/env (ruby.*)}).flatten.uniq
-
+
binfixups = (rubies - %w(ruby)).map do |ruby|
"sed -i 's/#{Regexp.quote(ruby)}$/ruby/' bin/*"
end
-
+
# Windows line endings will cause scripts to fail. If any
- # or found OR this generation is run on a windows platform
- # and there are other binfixups required, then convert
+ # or found OR this generation is run on a windows platform
+ # and there are other binfixups required, then convert
# line endings. This avoids adding unnecessary fixups if
# none are required, but prepares for the need to do the
# fix line endings if other fixups are required.
has_cr = Dir["bin/*"].any? { |file| IO.read(file).include? "\r" }
if has_cr || (Gem.win_platform? && !binfixups.empty?)
binfixups.unshift 'sed -i "s/\r$//g" bin/*'
end
-
+
# Windows file systems may not have the concept of executable.
# In such cases, fix up during the build.
unless Dir["bin/*"].all? { |file| File.executable? file }
binfixups.unshift "chmod +x bin/*"
end
# optionally, adjust cwd
- if options['bin-cd']
+ if options["bin-cd"]
binfixups.push %{grep -l '#!/usr/bin/env ruby' /rails/bin/* | xargs sed -i '/^#!/aDir.chdir File.expand_path("..", __dir__)'}
end
binfixups
end
def deploy_database
- if options.postgresql? or @postgresql
- 'postgresql'
- elsif options.mysql or @mysql
- 'mysql'
+ if options.postgresql? || @postgresql
+ "postgresql"
+ elsif options.mysql || @mysql
+ "mysql"
else
- 'sqlite3'
+ "sqlite3"
end
end
def node_version
version = nil
- if File.exist? '.node-version'
- version = IO.read('.node-version')[/\d+\.\d+\.\d+/]
+ if File.exist? ".node-version"
+ version = IO.read(".node-version")[/\d+\.\d+\.\d+/]
end
- if !version and File.exist? 'package.json'
- version = JSON.parse(IO.read('package.json')).dig("engines", "node")
- version = nil unless version =~ /\A(\d+\.)+(\d+|x)\z/
+ if !version && File.exist?("package.json")
+ version = JSON.parse(IO.read("package.json")).dig("engines", "node")
+ version = nil unless /\A(\d+\.)+(\d+|x)\z/.match?(version)
end
version || `node --version`[/\d+\.\d+\.\d+/]
rescue
- "lts"
+ "lts"
end
def yarn_version
- package = JSON.parse(IO.read('package.json'))
+ package = JSON.parse(IO.read("package.json"))
- if ENV['RAILS_ENV'] == 'test'
+ if ENV["RAILS_ENV"] == "test"
# yarn install instructions changed in v2
- version = '1.22.19'
- elsif package['packageManager'].to_s.start_with? "yarn@"
- version = package['packageManager'].sub('yarn@', '')
+ version = "1.22.19"
+ elsif package["packageManager"].to_s.start_with? "yarn@"
+ version = package["packageManager"].sub("yarn@", "")
else
- version = `yarn --version`[/\d+\.\d+\.\d+/] || '1.22.19'
+ version = `yarn --version`[/\d+\.\d+\.\d+/] || "1.22.19"
system "yarn set version #{version}"
- package = JSON.parse(IO.read('package.json'))
+ package = JSON.parse(IO.read("package.json"))
# apparently not all versions of yarn will update package.json...
end
- unless package['packageManager']
- package['packageManager'] = "yarn@#{version}"
- IO.write('package.json', JSON.pretty_generate(package))
+ unless package["packageManager"]
+ package["packageManager"] = "yarn@#{version}"
+ IO.write("package.json", JSON.pretty_generate(package))
end
version
rescue
"latest"
end
def depend_on_bootsnap?
- @gemfile.include? 'bootsnap'
+ @gemfile.include? "bootsnap"
end
def api_only?
Rails.application.config.api_only
end
# scan for node clients. Do a wide scan if api_only?, otherwise look
# for specific directories.
def api_client_dir
if api_only?
- scan = '*/package.json'
+ scan = "*/package.json"
else
- scan = '{client,frontend}/package.json'
+ scan = "{client,frontend}/package.json"
end
file = Dir[scan].find do |file|
- JSON.load_file(file).dig('scripts', 'build')
+ JSON.load_file(file).dig("scripts", "build")
end
file && File.dirname(file)
end
@@ -538,35 +664,37 @@
Dir["#{client}/{package.json,package-lock.json,yarn.lock}"]
end
def dbprep_command
if Rails::VERSION::MAJOR >= 6
- 'db:prepare'
+ "db:prepare"
else
- 'db:migrate'
+ "db:migrate"
end
end
def procfile
if options.nginx?
{
nginx: 'nginx -g "daemon off;"',
- rails: './bin/rails server -p 3001'
+ rails: "./bin/rails server -p 3001"
}
else
{
- rails: './bin/rails server'
+ rails: "./bin/rails server"
}
end
end
def more_docker_ignores
- more = ''
+ more = ""
- if @gemfile.include?('vite_ruby')
- lines = IO.read('.gitignore')[/^# Vite.*?\n\n/m].to_s.chomp.lines -
+ if @gemfile.include?("vite_ruby")
+ lines = IO.read(".gitignore")[/^# Vite.*?\n\n/m].to_s.chomp.lines -
["node_modules\n"]
more += "\n" + lines.join
end
+
+ more
end
end