lib/simple/httpd/cli.rb in simple-httpd-0.3.0 vs lib/simple/httpd/cli.rb in simple-httpd-0.3.1

- old
+ new

@@ -1,7 +1,5 @@ -# rubocop:disable Metrics/AbcSize, Metrics/MethodLength - module Simple class Httpd class << self attr_accessor :env end @@ -9,72 +7,115 @@ end module Simple::Httpd::CLI include Simple::CLI + def logger + ::Simple::CLI.logger + end + # Runs a simple httpd server # - # A mount_spec is either the location of a directory, which would then be mounted + # A mount is either the location of a directory, which would then be mounted # at the "/" HTTP location, or a directory followed by a colon and where to mount # the directory. # # Mounted directories might contain either ruby source code which is then executed # or static files to be delivered verbatim. See README.md for more details. # # Examples: # - # simple-httpd --port=8080 httpd/root --service=src/to/service.rb MyService:/ httpd/assets:assets + # PORT=8080 simple-httpd start httpd/root --service=src/to/service.rb \ + # MyService:/ + # httpd/assets:assets # # serves the content of ./httpd/root on http://0.0.0.0/ and the content of httpd/assets # on http://0.0.0.0/assets. # # Options: # # --environment=ENV ... the environment setting, which adjusts configuration. - # --services=<path>,<path> ... load these ruby file during startup. Used to define service objects. + # --services=<path>,<path> ... load these ruby files or directories during startup. This + # can be used to define service objects. # # simple-httpd respects the HOST and PORT environment values to determine the interface # and port to listen to. Default values are "127.0.0.1" and 8181. # # Each entry in mounts can be either: # # - a mount_point <tt>[ mount_point, path ]</tt>, e.g. <tt>[ "path/to/root", "/"]</tt> # - a string denoting a mount_point, e.g. "path/to/root:/") # - a string denoting a "/" mount_point (e.g. "path", which is shorthand for "path:/") - def main(*mount_specs, environment: "development", services: nil) - ::Simple::Httpd.env = environment + def start(*mounts, environment: "development", services: nil) + host = ENV["HOST"] || "127.0.0.1" + port = Integer(ENV["PORT"] || 8181) - start_simplecov if environment == "test" + prepare_environment!(environment: environment) - mount_specs << "." if mount_specs.empty? + app = build_app!(mounts: mounts, services: services) + logger.info "start to listen on #{mounts.inspect}" + ::Simple::Httpd.listen!(app, environment: environment, + host: host, + port: port) + end - host = ENV["HOST"] || "127.0.0.1" - port = Integer(ENV["PORT"] || 8181) + def routes(*mounts, environment: "development", services: nil) + prepare_environment!(environment: environment) + app = build_app!(mounts: mounts, services: services) + routes = app.route_descriptions + logger.info "Found #{routes.count} routes" + + max_verb_len = routes.map(&:verb).map(&:length).max + max_path_len = routes.map(&:path).map(&:length).max + + routes. + sort_by { |route| [route.path, route.verb] }. + each { |route| + puts format("%#{max_verb_len}s %-#{max_path_len}s %s", route.verb, route.path, route.source_location_str) + } + end + + private + + def prepare_environment!(environment:) + ::Simple::Httpd.env = environment + start_simplecov if environment == "test" + # late loading simple/httpd, for simplecov support require "simple/httpd" - helpers = ::Simple::Httpd::Helpers + end - services&.split(",")&.each do |service_path| - paths = if Dir.exist?(service_path) - Dir.glob("#{service_path}/**/*.rb").sort - else - [service_path] - end + def build_app!(mounts:, services:) + mounts << "." if mounts.empty? + logger.info "building server on #{mounts.inspect}" - paths.each do |path| - logger.info "Loading service(s) from #{helpers.shorten_path path}" - load path - end - end + load_services! services if services + app = ::Simple::Httpd.build(*mounts) + app.rack # builds the rack application + app + end - ::Simple::Httpd.listen!(*mount_specs, environment: environment, - host: host, - port: port, - logger: logger) + def load_services!(paths) + expect! paths => String + + resolve_service_path(paths).each do |path| + logger.info "Loading service(s) from #{::Simple::Httpd::Helpers.shorten_path path}" + load path + end end - private + def resolve_service_path(paths) + # each service_path either denotes the path to a file or to a directory + # of files. + paths.split(",").each_with_object([]) do |service_path, ary| + if Dir.exist?(service_path) + ary.concat Dir.glob("#{service_path}/**/*.rb").sort + else + ary << service_path + end + end + end def stderr_logger logger = ::Logger.new STDERR logger.level = ::Logger::INFO logger