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