Module: Kino::CLI
- Defined in:
- lib/kino/cli.rb
Overview
The kino executable (CLI.start) plus startup presentation shared with
Server.run: the banner, ANSI styling, and the exit credit. Nothing here
is part of the serving API. (The native layer has a twin of paint in
style.rs for the few places Rust writes to the terminal.)
This file deliberately loads no native code: require "kino" happens
inside the actions that need it, so --help and --version stay instant.
Constant Summary collapse
- MOTD =
The plain banner art: "Kino" in TheDraw's Mindbenders font; motd adds the original three-tone shading.
<<~BANNER ggg .o $$$_,o$$P aaa $$$eea,. .,aaa,. %$$`4eP' $$$ $$$``$$$% $$$```$$$ $$$--`$$o ggg $$$---$$$ $$$---$$$ $$$ ░ $$$ $$$ $$$ ░ $$$ $$$ ░ $$$ $$$---$$$ $$$ $$$---$$$ $$$---$$$ $$$ $$$ $$' $$$ $$$ ^$$aaaS$' BANNER
Class Method Summary collapse
-
.action!(server) ⇒ void
The ready block: what this process is (Ruby build with its JIT and parser flags, environment, topology, pid) and where it listens.
-
.bold(text, io: $stdout) ⇒ String
Bold styling for headings and the Action!/Fin.
-
.color?(io = $stdout) ⇒ Boolean
True when output to
iomay use ANSI styling. -
.dim(text, io: $stdout) ⇒ String
Startup-output styling, same gray family as the banner.
-
.fin_at_exit ⇒ void
Roll credits when the process ends: normal exit or crash (at_exit also runs after an uncaught exception; only a force-exit skips it).
-
.motd(color: color?) ) ⇒ String
The banner with its three-tone shading applied per character.
-
.opening_credits ⇒ void
The two banner halves around Server#start: credits before, the ready block plus a bold "Action!" after, once mode and port are known.
-
.paint(code, text, io: $stdout) ⇒ String
Wrap
textin an SGR code ("1" bold, "31" red, "38;5;N" 256-color), resetting at the end; plain wheniois not a color terminal. -
.red(text, io: $stderr) ⇒ String
Errors are red (gated on stderr unless another io is given).
-
.start(argv) ⇒ Integer
The
kinoexecutable: parse flags, then init/check/serve. -
.stats_line(stats) ⇒ String
One-line stats dump (what the SIGUSR1 handler logs).
Class Method Details
.action!(server) ⇒ void
This method returns an undefined value.
The ready block: what this process is (Ruby build with its JIT and parser flags, environment, topology, pid) and where it listens.
126 127 128 129 130 131 132 133 134 135 136 |
# File 'lib/kino/cli.rb', line 126 def action!(server) stats = server.stats puts dim("- ruby: #{RUBY_DESCRIPTION}") puts dim("- env: #{ENV["RAILS_ENV"] || ENV["RACK_ENV"] || "development"}") puts dim("- mode: #{server.mode}, #{count(stats[:workers], "worker")} × #{count(stats[:threads], "thread")}") puts dim("- pid: #{Process.pid}") puts dim("- listening: #{server.url}") puts dim("- control: #{server.control_url}") if server.control_url puts dim("- Ctrl-C to drain and stop") puts "\n#{bold("Action!")}\n\n" end |
.bold(text, io: $stdout) ⇒ String
Bold styling for headings and the Action!/Fin. bookends.
72 73 74 |
# File 'lib/kino/cli.rb', line 72 def bold(text, io: $stdout) paint("1", text, io: io) end |
.color?(io = $stdout) ⇒ Boolean
True when output to io may use ANSI styling.
49 50 51 |
# File 'lib/kino/cli.rb', line 49 def color?(io = $stdout) io.tty? && ENV["NO_COLOR"].nil? && ENV["TERM"] != "dumb" end |
.dim(text, io: $stdout) ⇒ String
Startup-output styling, same gray family as the banner.
66 67 68 |
# File 'lib/kino/cli.rb', line 66 def dim(text, io: $stdout) paint("38;5;243", text, io: io) end |
.fin_at_exit ⇒ void
This method returns an undefined value.
Roll credits when the process ends: normal exit or crash (at_exit also runs after an uncaught exception; only a force-exit skips it).
146 147 148 149 150 151 |
# File 'lib/kino/cli.rb', line 146 def fin_at_exit return if @fin_registered @fin_registered = true at_exit { $stdout.puts bold("\nFin.\n") } end |
.motd(color: color?) ) ⇒ String
The banner with its three-tone shading applied per character.
85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 |
# File 'lib/kino/cli.rb', line 85 def motd(color: color?) return MOTD unless color MOTD.lines.zip(MOTD_TONES.lines).map do |art, tones| current = nil line = art.chomp.each_char.with_index.map { |char, i| sgr = TONE_SGR[tones.to_s[i]] if char != " " && sgr && sgr != current current = sgr "\e[#{sgr}m#{char}" else char end }.join "#{line}\e[0m\n" end.join end |
.opening_credits ⇒ void
This method returns an undefined value.
The two banner halves around Server#start: credits before, the ready block plus a bold "Action!" after, once mode and port are known. Server.run is the one caller; the kino CLI funnels into it.
117 118 119 120 |
# File 'lib/kino/cli.rb', line 117 def opening_credits puts motd puts dim("\nKino #{VERSION} presents:") end |
.paint(code, text, io: $stdout) ⇒ String
Wrap text in an SGR code ("1" bold, "31" red, "38;5;N" 256-color),
resetting at the end; plain when io is not a color terminal.
60 61 62 |
# File 'lib/kino/cli.rb', line 60 def paint(code, text, io: $stdout) color?(io) ? "\e[#{code}m#{text}\e[0m" : text end |
.red(text, io: $stderr) ⇒ String
Errors are red (gated on stderr unless another io is given).
78 79 80 |
# File 'lib/kino/cli.rb', line 78 def red(text, io: $stderr) paint("91", text, io: io) end |
.start(argv) ⇒ Integer
The kino executable: parse flags, then init/check/serve. Returns
the process exit status (exe/kino passes it to Kernel#exit), except
for -v and -h, which print and exit in place per optparse convention.
159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 |
# File 'lib/kino/cli.rb', line 159 def start(argv) = {overrides: {}} parser = option_parser() parser.parse!(argv) return write_sample([:init_path]) if [:init_path] config = resolve_config() # Precedence for the rackup file: positional arg > `rackup` in config > config.ru rackup_file = argv.first || config[:rackup] || "config.ru" unless File.exist?(rackup_file) warn red("Kino: #{rackup_file} not found") puts print_help(parser) return 1 end ENV["RACK_ENV"] ||= config[:environment] if config[:environment] app = Rack::Builder.parse_file(rackup_file) app = app.first if app.is_a?(Array) # rack < 3 compat return Check.print_report(app) ? 0 : 1 if [:check] serve(app, config) 0 end |
.stats_line(stats) ⇒ String
One-line stats dump (what the SIGUSR1 handler logs). Excludes worker_status: it's an array with one entry per execution slot, and printing it inline would break the one-line contract (see /stats for per-worker detail).
109 110 111 |
# File 'lib/kino/cli.rb', line 109 def stats_line(stats) "stats #{stats.except(:worker_status).map { |k, v| "#{k}=#{v.inspect}" }.join(" ")}" end |