class RailsRoutesAnalyzer::RouteFileAnnotator
Public Class Methods
new(try_to_fix: false, allow_deleting: false, force_overwrite: false, analysis: nil, **kwargs)
click to toggle source
@param try_to_fix [Boolean] should automatic fixes be attempted @param allow_deleting [Boolean] should route lines be deleted when they match no actions @param force_overwrite [Boolean] allow overwriting routes file even if it has uncommited changes or is outside Rails.root
# File lib/rails_routes_analyzer/route_file_annotator.rb, line 7 def initialize(try_to_fix: false, allow_deleting: false, force_overwrite: false, analysis: nil, **kwargs) @analysis = analysis || RailsRoutesAnalyzer::RouteAnalysis.new(**kwargs) @try_to_fix = try_to_fix @allow_deleting = allow_deleting @force_overwrite = force_overwrite end
Protected Class Methods
check_file_git_status(filename, report: false, skip_git: false, repo_root: Rails.root.to_s)
click to toggle source
# File lib/rails_routes_analyzer/route_file_annotator.rb, line 95 def check_file_git_status(filename, report: false, skip_git: false, repo_root: Rails.root.to_s) return skip_git if skip_git git = nil begin require 'git' git = Git.open(repo_root) rescue => e log_notice "Couldn't access git repository at Rails root #{repo_root}. #{e.message}" if report return false end repo_relative_filename = filename.to_s.sub("#{repo_root}/", '') # This seems to be required to force some kind of git status # refresh because without it tests would randomly detect a file # as modified by git-status when the file in fact has no changes. # # Currently randomly causes a NoMethodError exception but can still help. begin git.diff.each { |file| } rescue NoMethodError # rubocop:disable Lint/HandleExceptions end if git.status.changed.key?(repo_relative_filename) log_notice "Refusing to modify '#{repo_relative_filename}' as it has uncommited changes" if report return false end true end
check_file_is_modifiable(filename, report: false, **kwargs)
click to toggle source
# File lib/rails_routes_analyzer/route_file_annotator.rb, line 86 def check_file_is_modifiable(filename, report: false, **kwargs) unless filename.to_s.starts_with?(Rails.root.to_s) log_notice "Refusing to modify files outside Rails root: #{Rails.root}" if report return false end check_file_git_status(filename, report: report, **kwargs) end
log_notice(message = nil) { || ... }
click to toggle source
# File lib/rails_routes_analyzer/route_file_annotator.rb, line 80 def log_notice(message = nil) return if ENV['RAILS_ENV'] == 'test' message ||= yield if block_given? $stderr.puts "# #{message}" if message.present? end
Public Instance Methods
annotate_routes_file(route_filename, inplace: false, do_exit: true)
click to toggle source
# File lib/rails_routes_analyzer/route_file_annotator.rb, line 41 def annotate_routes_file(route_filename, inplace: false, do_exit: true) filenames = files_to_work_on(route_filename, inplace: inplace) if filenames.is_a?(Integer) exit filenames if do_exit return filenames end filenames.map! { |file| RailsRoutesAnalyzer.get_full_filename(file) } filenames.each do |filename| unless File.exist?(filename) $stderr.puts "Can't find routes file: #{filename}" exit 1 end end if filenames.size != 1 && !inplace raise ArgumentError, "got #{filenames.size} files but can annotate only one at a time to stdout" end filenames.each do |filename| if inplace if @force_overwrite || self.class.check_file_is_modifiable(filename, report: true) content = annotated_file_content(filename) File.open(filename, 'w') { |f| f.write content } end else puts annotated_file_content(filename) end end end
annotated_file_content(route_filename)
click to toggle source
# File lib/rails_routes_analyzer/route_file_annotator.rb, line 14 def annotated_file_content(route_filename) route_lines = @analysis.route_lines_for_file(route_filename) if route_lines.none?(&:issues?) log_notice { "Didn't find any route issues for file: #{route_filename}, only found issues in files: #{@analysis.all_unique_issues_file_names.join(', ')}" } end log_notice { "Annotating #{route_filename}" } route_lines_map = route_lines.index_by(&:line_number) "".tap do |output| File.readlines(route_filename).each_with_index do |line, index| route_line = route_lines_map[index + 1] output << if route_line route_line.annotate(line, try_to_fix: @try_to_fix, allow_deleting: @allow_deleting) else line end end end end
Protected Instance Methods
annotatable_routes_files(inplace:)
click to toggle source
# File lib/rails_routes_analyzer/route_file_annotator.rb, line 128 def annotatable_routes_files(inplace:) filenames = @analysis.all_unique_issues_file_names if inplace && !@force_overwrite filenames.select! { |filename| self.class.check_file_is_modifiable(filename) } end filenames end
files_to_work_on(filename, inplace:)
click to toggle source
# File lib/rails_routes_analyzer/route_file_annotator.rb, line 138 def files_to_work_on(filename, inplace:) return [filename] if filename.present? filenames = annotatable_routes_files(inplace: inplace) if filenames.empty? $stderr.puts "All routes are good, nothing to annotate" return 0 elsif filenames.size > 1 && !inplace $stderr.puts "Please specify routes file with ROUTES_FILE='path/routes.rb' as you have more than one file with problems:\n #{filenames.join("\n ")}" return 1 end filenames end
log_notice(*args, &block)
click to toggle source
# File lib/rails_routes_analyzer/route_file_annotator.rb, line 75 def log_notice(*args, &block) self.class.log_notice(*args, &block) end