diff --git a/lib/annotate/annotate_routes.rb b/lib/annotate/annotate_routes.rb index c9a2218ac..7d3f6d3c6 100644 --- a/lib/annotate/annotate_routes.rb +++ b/lib/annotate/annotate_routes.rb @@ -18,18 +18,16 @@ # Released under the same license as Ruby. No Support. No Warranty. # -require_relative './annotate_routes/helpers' -require_relative './annotate_routes/header_generator' +require_relative './annotate_routes/annotation_processor' +require_relative './annotate_routes/removal_processor' module AnnotateRoutes class << self def do_annotations(options = {}) - if routes_file_exist? - existing_text = File.read(routes_file) - content, header_position = Helpers.strip_annotations(existing_text) - new_content = annotate_routes(HeaderGenerator.generate(options), content, header_position, options) - new_text = new_content.join("\n") - if rewrite_contents(existing_text, new_text, options[:frozen]) + routes_file = File.join('config', 'routes.rb') + processor = AnnotationProcessor.new(options, routes_file) + if processor.routes_file_exist? + if processor.update puts "#{routes_file} was annotated." else puts "#{routes_file} was not changed." @@ -39,13 +37,11 @@ def do_annotations(options = {}) end end - def remove_annotations(options={}) - if routes_file_exist? - existing_text = File.read(routes_file) - content, header_position = Helpers.strip_annotations(existing_text) - new_content = strip_on_removal(content, header_position) - new_text = new_content.join("\n") - if rewrite_contents(existing_text, new_text, options[:frozen]) + def remove_annotations(options = {}) + routes_file = File.join('config', 'routes.rb') + processor = RemovalProcessor.new(options, routes_file) + if processor.routes_file_exist? + if processor.update puts "Annotations were removed from #{routes_file}." else puts "#{routes_file} was not changed (Annotation did not exist)." @@ -54,66 +50,5 @@ def remove_annotations(options={}) puts "#{routes_file} could not be found." end end - - private - - def routes_file_exist? - File.exist?(routes_file) - end - - def routes_file - @routes_rb ||= File.join('config', 'routes.rb') - end - - def strip_on_removal(content, header_position) - if header_position == :before - content.shift while content.first == '' - elsif header_position == :after - content.pop while content.last == '' - end - - # Make sure we end on a trailing newline. - content << '' unless content.last == '' - - # TODO: If the user buried it in the middle, we should probably see about - # TODO: preserving a single line of space between the content above and - # TODO: below... - content - end - - def rewrite_contents(existing_text, new_text, frozen) - content_changed = (existing_text != new_text) - - if content_changed - abort "annotate error. #{routes_file} needs to be updated, but annotate was run with `--frozen`." if frozen - File.open(routes_file, 'wb') { |f| f.puts(new_text) } - end - - content_changed - end - - def annotate_routes(header, content, header_position, options = {}) - magic_comments_map, content = Helpers.extract_magic_comments_from_array(content) - if %w(before top).include?(options[:position_in_routes]) - header = header << '' if content.first != '' - magic_comments_map << '' if magic_comments_map.any? - new_content = magic_comments_map + header + content - else - # Ensure we have adequate trailing newlines at the end of the file to - # ensure a blank line separating the content from the annotation. - content << '' unless content.last == '' - - # We're moving something from the top of the file to the bottom, so ditch - # the spacer we put in the first time around. - content.shift if header_position == :before && content.first == '' - - new_content = magic_comments_map + content + header - end - - # Make sure we end on a trailing newline. - new_content << '' unless new_content.last == '' - - new_content - end end end diff --git a/lib/annotate/annotate_routes/annotation_processor.rb b/lib/annotate/annotate_routes/annotation_processor.rb new file mode 100644 index 000000000..055ef31ab --- /dev/null +++ b/lib/annotate/annotate_routes/annotation_processor.rb @@ -0,0 +1,43 @@ +require_relative './base_processor' +require_relative './helpers' +require_relative './header_generator' + +module AnnotateRoutes + # Class to add and update annotations in routes.rb + class AnnotationProcessor < BaseProcessor + # @return [Boolean] + def update + header = HeaderGenerator.generate(options) + content, header_position = Helpers.strip_annotations(existing_text) + new_content = annotate_routes(header, content, header_position) + new_text = new_content.join("\n") + rewrite_contents(new_text) + end + + private + + def annotate_routes(header, content, header_position) + magic_comments_map, content = Helpers.extract_magic_comments_from_array(content) + if %w[before top].include?(options[:position_in_routes]) + header = header << '' if content.first != '' + magic_comments_map << '' if magic_comments_map.any? + new_content = magic_comments_map + header + content + else + # Ensure we have adequate trailing newlines at the end of the file to + # ensure a blank line separating the content from the annotation. + content << '' unless content.last == '' + + # We're moving something from the top of the file to the bottom, so ditch + # the spacer we put in the first time around. + content.shift if header_position == :before && content.first == '' + + new_content = magic_comments_map + content + header + end + + # Make sure we end on a trailing newline. + new_content << '' unless new_content.last == '' + + new_content + end + end +end diff --git a/lib/annotate/annotate_routes/base_processor.rb b/lib/annotate/annotate_routes/base_processor.rb new file mode 100644 index 000000000..a01fb475b --- /dev/null +++ b/lib/annotate/annotate_routes/base_processor.rb @@ -0,0 +1,48 @@ +module AnnotateRoutes + # Base class of processors (AnnotationProcessor and RemovalProcessor) + class BaseProcessor + def initialize(options, routes_file) + @options = options + @routes_file = routes_file + end + + def routes_file_exist? + File.exist?(routes_file) + end + + private + + attr_reader :options, :routes_file + + def existing_text + @existing_text ||= File.read(routes_file) + end + + # @param new_text [String] + # @return [Boolean] + def rewrite_contents(new_text) + content_changed = content_changed?(new_text) + + abort "annotate error. #{routes_file} needs to be updated, but annotate was run with `--frozen`." if content_changed && frozen? + + if content_changed + write(new_text) + true + else + false + end + end + + def write(text) + File.open(routes_file, 'wb') { |f| f.puts(text) } + end + + def content_changed?(new_text) + existing_text != new_text + end + + def frozen? + options[:frozen] + end + end +end diff --git a/lib/annotate/annotate_routes/removal_processor.rb b/lib/annotate/annotate_routes/removal_processor.rb new file mode 100644 index 000000000..1b41d3b1c --- /dev/null +++ b/lib/annotate/annotate_routes/removal_processor.rb @@ -0,0 +1,34 @@ +require_relative './base_processor' +require_relative './helpers' + +module AnnotateRoutes + # Class to remove annotations in routes.rb + class RemovalProcessor < BaseProcessor + # @return [Boolean] + def update + content, header_position = Helpers.strip_annotations(existing_text) + new_content = strip_on_removal(content, header_position) + new_text = new_content.join("\n") + rewrite_contents(new_text) + end + + private + + def strip_on_removal(content, header_position) + case header_position + when :before + content.shift while content.first == '' + when :after + content.pop while content.last == '' + end + + # Make sure we end on a trailing newline. + content << '' unless content.last == '' + + # TODO: If the user buried it in the middle, we should probably see about + # TODO: preserving a single line of space between the content above and + # TODO: below... + content + end + end +end