lib/rails/generators/actions.rb in railties-6.1.7.10 vs lib/rails/generators/actions.rb in railties-7.0.0.alpha1

- old
+ new

@@ -16,18 +16,22 @@ # # gem "rspec", group: :test # gem "technoweenie-restful-authentication", lib: "restful-authentication", source: "http://gems.github.com/" # gem "rails", "3.0", git: "https://github.com/rails/rails" # gem "RedCloth", ">= 4.1.0", "< 4.2.0" + # gem "rspec", comment: "Put this comment above the gem declaration" def gem(*args) options = args.extract_options! name, *versions = args # Set the message to be shown in logs. Uses the git repo if one is given, # otherwise use name (version). parts, message = [ quote(name) ], name.dup + # Output a comment above the gem declaration. + comment = options.delete(:comment) + if versions = versions.any? ? versions : options.delete(:version) _versions = Array(versions) _versions.each do |version| parts << quote(version) end @@ -38,13 +42,21 @@ log :gemfile, message parts << quote(options) unless options.empty? in_root do - str = "gem #{parts.join(", ")}" - str = indentation + str - append_file_with_newline "Gemfile", str, verbose: false + str = [] + if comment + comment.each_line do |comment_line| + str << indentation + str << "# #{comment_line}" + end + str << "\n" + end + str << indentation + str << "gem #{parts.join(", ")}" + append_file_with_newline "Gemfile", str.join, verbose: false end end # Wraps gem entries inside a group. # @@ -266,18 +278,29 @@ # # route "root 'welcome#index'" # route "root 'admin#index'", namespace: :admin def route(routing_code, namespace: nil) routing_code = Array(namespace).reverse.reduce(routing_code) do |code, ns| - "namespace :#{ns} do\n#{indent(code, 2)}\nend" + "namespace :#{ns} do\n#{optimize_indentation(code, 2)}end" end log :route, routing_code - sentinel = /\.routes\.draw do\s*\n/m + after_pattern = Array(namespace).each_with_index.reverse_each.reduce(nil) do |pattern, (ns, i)| + margin = "\\#{i + 1}[ ]{2}" + "(?:(?:^[ ]*\n|^#{margin}.*\n)*?^(#{margin})namespace :#{ns} do\n#{pattern})?" + end.then do |pattern| + /^([ ]*).+\.routes\.draw do[ ]*\n#{pattern}/ + end + in_root do - inject_into_file "config/routes.rb", optimize_indentation(routing_code, 2), after: sentinel, verbose: false, force: false + if existing = match_file("config/routes.rb", after_pattern) + base_indent, *, prev_indent = existing.captures.compact.map(&:length) + routing_code = optimize_indentation(routing_code, base_indent + 2).lines.grep_v(/^[ ]{,#{prev_indent}}\S/).join + end + + inject_into_file "config/routes.rb", routing_code, after: after_pattern, verbose: false, force: false end end # Reads the given file at the source root and prints it in the console. # @@ -321,25 +344,20 @@ else name end end - # Surround string with single quotes if there is no quotes. - # Otherwise fall back to double quotes + # Always returns value in double quotes. def quote(value) # :doc: if value.respond_to? :each_pair return value.map do |k, v| "#{k}: #{quote(v)}" end.join(", ") end return value.inspect unless value.is_a? String - if value.include?("'") - value.inspect - else - "'#{value}'" - end + "\"#{value.tr("'", '"')}\"" end # Returns optimized string with indentation def optimize_indentation(value, amount = 0) # :doc: return "#{value}\n" unless value.is_a?(String) @@ -362,9 +380,13 @@ # Append string to a file with a newline if necessary def append_file_with_newline(path, str, options = {}) gsub_file path, /\n?\z/, options do |match| match.end_with?("\n") ? "" : "\n#{str}\n" end + end + + def match_file(path, pattern) + File.read(path).match(pattern) if File.exist?(path) end end end end