lib/annotate/annotate_routes/header_generator.rb
require_relative './helpers'
module AnnotateRoutes
class HeaderGenerator
PREFIX = '== Route Map'.freeze
PREFIX_MD = '## Route Map'.freeze
HEADER_ROW = ['Prefix', 'Verb', 'URI Pattern', 'Controller#Action'].freeze
class << self
def generate(options = {})
new(options, routes_map(options)).generate
end
private :new
private
def routes_map(options)
result = `rake routes`.chomp("\n").split(/\n/, -1)
# In old versions of Rake, the first line of output was the cwd. Not so
# much in newer ones. We ditch that line if it exists, and if not, we
# keep the line around.
result.shift if result.first =~ %r{^\(in \/}
ignore_routes = options[:ignore_routes]
regexp_for_ignoring_routes = ignore_routes ? /#{ignore_routes}/ : nil
# Skip routes which match given regex
# Note: it matches the complete line (route_name, path, controller/action)
if regexp_for_ignoring_routes
result.reject { |line| line =~ regexp_for_ignoring_routes }
else
result
end
end
end
def initialize(options, routes_map)
@options = options
@routes_map = routes_map
end
def generate
magic_comments_map, contents_without_magic_comments = Helpers.extract_magic_comments_from_array(routes_map)
out = []
magic_comments_map.each do |magic_comment|
out << magic_comment
end
out << '' if magic_comments_map.any?
out << comment(options[:wrapper_open]) if options[:wrapper_open]
out << comment(markdown? ? PREFIX_MD : PREFIX) + timestamp_if_required
out << comment
return out if contents_without_magic_comments.size.zero?
maxs = [HEADER_ROW.map(&:size)] + contents_without_magic_comments[1..-1].map { |line| line.split.map(&:size) }
if markdown?
max = maxs.map(&:max).compact.max
out << comment(content(HEADER_ROW, maxs))
out << comment(content(['-' * max, '-' * max, '-' * max, '-' * max], maxs))
else
out << comment(content(contents_without_magic_comments[0], maxs))
end
out += contents_without_magic_comments[1..-1].map { |line| comment(content(markdown? ? line.split(' ') : line, maxs)) }
out << comment(options[:wrapper_close]) if options[:wrapper_close]
out
end
private
attr_reader :options, :routes_map
def comment(row = '')
if row == ''
'#'
else
"# #{row}"
end
end
def content(line, maxs)
return line.rstrip unless markdown?
line.each_with_index.map { |elem, index| format_line_element(elem, maxs, index) }.join(' | ')
end
def format_line_element(elem, maxs, index)
min_length = maxs.map { |arr| arr[index] }.max || 0
format("%-#{min_length}.#{min_length}s", elem.tr('|', '-'))
end
def markdown?
options[:format_markdown]
end
def timestamp_if_required(time = Time.now)
if options[:timestamp]
time_formatted = time.strftime('%Y-%m-%d %H:%M')
" (Updated #{time_formatted})"
else
''
end
end
end
end