Skip to content

Instantly share code, notes, and snippets.

@JoshCheek
Created May 4, 2018 17:50
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JoshCheek/417757938623da4ea3779e4b21c248aa to your computer and use it in GitHub Desktop.
Save JoshCheek/417757938623da4ea3779e4b21c248aa to your computer and use it in GitHub Desktop.
Cache / filter / reformat filtered routes since `rake routes` is so expensive.
#!/usr/bin/env ruby
argv = ARGV
# handle help screen
if argv.any? { |arg| arg == '-h' || arg == '--help' }
$stderr.puts <<~HELP
Usage: routes [--load] [--reload] [filter ...]
Runs `bin/rake routes` and caches the result so that you don't have to wait
forever to see your routes. Pass regexes to filter the output.
HELP
exit
end
# load / reload routes
load_commands, argv = argv.partition { |a| a =~ /^--(re-?)?load/ }
if load_commands.any? || DATA.eof?
require 'open3'
out, err, status = Open3.capture3 "bin/rake routes"
if status.success?
File.truncate __FILE__, DATA.pos
File.open(__FILE__, mode: 'a') { |f| f.puts out }
else
$stderr.puts err
exit status.exitstatus
end
end
# parse routes
lines = DATA.readlines
max = lines.map(&:size).max
delims = [0, *max.times.select { |i| lines.all? { |l| l[i] == " " } }, max]
ranges = delims.each_cons(2).map { |start, stop| start..stop }
routes = lines.map { |line| ranges.map { |r| line[r].strip } }
header = routes.shift
# filter routes
argv.each do |arg|
regex = Regexp.new arg
routes.select! { |r| r.join(" ") =~ regex }
end
# format string
cols = [header, *routes].transpose
sizes = cols.map { |col| col.map(&:size).max }
fmt = sizes.map.with_index do |size, i|
"%#{'-' unless i.zero?}#{size unless i == sizes.length.pred}s"
end.join(" ")
# print filtered routes
begin
puts fmt%header if $stdout.tty?
routes.each { |route| puts fmt%route }
rescue Errno::EPIPE # don't blow up if piping the output to things like `head`
end
__END__
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment