Skip to content

Instantly share code, notes, and snippets.

@alex-min
Created March 21, 2020 03:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save alex-min/f4c2821ce619c0219c49e0fbfba63314 to your computer and use it in GitHub Desktop.
Save alex-min/f4c2821ce619c0219c49e0fbfba63314 to your computer and use it in GitHub Desktop.
generate_routes.cr
require "json"
class RouteJSON
JSON.mapping({
verb: String,
controller: String,
action: String,
pipeline: String,
scope: String,
uri_pattern: String,
})
end
output = <<-CRYSTAL
# autogenerated file by generate_routes.cr, please do not edit
module ViewPathHelper
def active_path(path) : Bool
context.request.path.starts_with? path
end
CRYSTAL
routes = Array(RouteJSON).from_json(`amber routes --json`)
routes.each do |route|
route_method = (route.action + "_" + route.controller.sub("Controller", "").gsub { |c|
if /[A-Z]/.match(c.to_s)
"_" + c
else
c
end
}.downcase.gsub(/_+/, '_').gsub(/^_/, "").gsub(':', '_') + "_path").gsub(/_+/, '_')
route_path = "#{route.scope}#{route.uri_pattern}"
puts "#{route_method} => #{route_path}"
if !route.uri_pattern.includes?(":") && !route.scope.includes?(":")
output += <<-CRYSTAL
macro #{route_method}
"#{route_path}"
end
CRYSTAL
else
if route_path.count(':') == 1
route_split = route_path.split(/:[a-zA-Z_]*/)
arg_name = route_path.match(/(:[a-zA-Z_]*)/).not_nil![0].gsub(':', "").gsub('-', '_')
path = <<-CRYSTAL
def #{route_method}(#{arg_name} : String): String
"#{route_split[0]}" + #{arg_name} + "#{route_split[1]}"
end
CRYSTAL
path = path.gsub(" + \"\"", "")
output += path
else
arg_names = route_path.split("/").reject do |name|
!name.starts_with?(':')
end
arg_names = arg_names.map do |name|
name.gsub(':', "").gsub('-', '_')
end
list_of_args = ""
arg_names.each_with_index do |arg, i|
list_of_args = list_of_args + arg + " : String"
if i < arg_names.size - 1
list_of_args += ", "
end
end
route_concatenation = ""
route = route_path.split(/:[a-zA-Z_]*/).each_with_index do |split, i|
route_concatenation += "\"" + split + "\" + "
if i < arg_names.size
route_concatenation += arg_names[i] + " + "
end
end
route_concatenation = route_concatenation.gsub(/\+ $/, "").gsub(/\+ \"\"/, "")
output += <<-CRYSTAL
def #{route_method}(#{list_of_args}) : String
#{route_concatenation}
end
CRYSTAL
end
end
end
output += "\nend\n"
File.write("./src/controllers/helpers/view_path.cr", output)
`crystal tool format`
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment