require "json" require "shellwords" module Rsg module Generators module Actions def rsg_install append_gem "rsg", within_group: %i(development test), install: false, path: options[:path] end def rsg_generate(name, quiet: false) cmd = "generate #{name}" cmd << " -q" if quiet rails_command cmd git_add_commit "RSG Generator executed: #{name}" end def rsg_apply_default! rsg_apply "rsg-default" end def rsg_apply(template) apply Rsg.lookup_app_template(template) end def api_mode? return @api_mode if defined?(@api_mode) @api_mode = !!(File.read("config/application.rb") =~ /^[^#]*config\.api_only = true[^\n]*$/) end def confirm?(prompt) opts = { limited_to: %w(y n) } ask(prompt, opts).downcase == 'y' end def git_add_commit(commit_msg) truncated_msg = commit_msg.strip.gsub("\n", ' ')[0..59].strip truncated_msg.gsub!(/.{3}$/, '...') if commit_msg.length > 60 say_status :run, "git add . && git commit -m \"#{truncated_msg}\"" run "git add .", verbose: false, capture: true run "git commit -m #{Shellwords.escape(commit_msg)}", verbose: false, capture: true end def enable_railtie(name) uncomment_lines "config/application.rb", /require ['"]#{name}\/railtie['"]/ end def append_gem(gem_name, install: true, within_group: [], after: ["bootsnap", "rails"], **gem_line_params) within_group = Array(within_group) if within_group.any? group_part = within_group.map { |g| "[:'\"]#{g}['\"]?" }.join(", ") regex = /^ *group #{group_part} do\n(\s*(gem|#)[^\n]+\n)+ *end\n/ else regex = /.+/m end gsub_file "Gemfile", regex do |match| gem_line = build_gem_line(gem_name, gem_line_params) append_gem_line(match, gem_line, after) end run("bundle install", capture: true) if install end private def append_gem_line(code, gem_line, after) code_lines = code.split("\n") index = code_lines.length indentation = "" # Goes to the line above the `end` line by default if code_lines[0] =~ /^([^#]*)group/ index -= 1 indentation = "#{$1} " end Array(after).each do |candidate| idx = code_lines.index { |l| l =~ /^([^#]*)gem ['"]#{candidate}['"].*$/ } next unless idx indentation = $1 index = idx + 1 break end code_lines.insert(index, "#{indentation}#{gem_line}").join("\n") << "\n" end def build_gem_line(gem_name, params = {}) line = "gem '#{gem_name}'" if params.key?(:version) version_args = Array(params[:version]).map { |v| "'#{v}'" }.join(", ") line << ", #{version_args}" end line << ", require: '#{params[:require]}'" if params.key?(:require) line << ", group: #{params[:group]}" if params.key?(:group) line << ", path: '#{params[:path]}'" if params[:path].present? line end end end end