lib/rails/generators/actions.rb in railties-7.0.0 vs lib/rails/generators/actions.rb in railties-7.0.1
- old
+ new
@@ -277,30 +277,36 @@
# Make an entry in Rails routing file <tt>config/routes.rb</tt>
#
# 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#{optimize_indentation(code, 2)}end"
+ namespace = Array(namespace)
+ namespace_pattern = route_namespace_pattern(namespace)
+ routing_code = namespace.reverse.reduce(routing_code) do |code, name|
+ "namespace :#{name} do\n#{rebase_indentation(code, 2)}end"
end
log :route, routing_code
- 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
- 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
+ if namespace_match = match_file("config/routes.rb", namespace_pattern)
+ base_indent, *, existing_block_indent = namespace_match.captures.compact.map(&:length)
+ existing_line_pattern = /^[ ]{,#{existing_block_indent}}\S.+\n?/
+ routing_code = rebase_indentation(routing_code, base_indent + 2).gsub(existing_line_pattern, "")
+ namespace_pattern = /#{Regexp.escape namespace_match.to_s}/
end
- inject_into_file "config/routes.rb", routing_code, after: after_pattern, verbose: false, force: false
+ inject_into_file "config/routes.rb", routing_code, after: namespace_pattern, verbose: false, force: false
+
+ if behavior == :revoke && namespace.any? && namespace_match
+ empty_block_pattern = /(#{namespace_pattern})((?:\s*end\n){1,#{namespace.size}})/
+ gsub_file "config/routes.rb", empty_block_pattern, verbose: false, force: true do |matched|
+ beginning, ending = empty_block_pattern.match(matched).captures
+ ending.sub!(/\A\s*end\n/, "") while !ending.empty? && beginning.sub!(/^[ ]*namespace .+ do\n\s*\z/, "")
+ beginning + ending
+ end
+ end
end
end
# Reads the given file at the source root and prints it in the console.
#
@@ -361,10 +367,11 @@
# Returns optimized string with indentation
def optimize_indentation(value, amount = 0) # :doc:
return "#{value}\n" unless value.is_a?(String)
"#{value.strip_heredoc.indent(amount).chomp}\n"
end
+ alias rebase_indentation optimize_indentation
# Indent the +Gemfile+ to the depth of @indentation
def indentation # :doc:
" " * @indentation
end
@@ -384,9 +391,19 @@
end
end
def match_file(path, pattern)
File.read(path).match(pattern) if File.exist?(path)
+ end
+
+ def route_namespace_pattern(namespace)
+ namespace.each_with_index.reverse_each.reduce(nil) do |pattern, (name, i)|
+ cummulative_margin = "\\#{i + 1}[ ]{2}"
+ blank_or_indented_line = "^[ ]*\n|^#{cummulative_margin}.*\n"
+ "(?:(?:#{blank_or_indented_line})*?^(#{cummulative_margin})namespace :#{name} do\n#{pattern})?"
+ end.then do |pattern|
+ /^([ ]*).+\.routes\.draw do[ ]*\n#{pattern}/
+ end
end
end
end
end