module BannerEngineRunner
BannerEngineRunner — run banner CLI engines safely via argv arrays (no shell interpolation). Public: render Depends: BannerEngines, BannerFont, TextUtil Tests: test/lib/banner_engine_runner_test.rb
Constants
- ANSI_PATTERN
- DEFAULT_TIMEOUT
- MAX_LINE_WIDTH
Public Instance Methods
Source
# File lib/banner_engine_runner.rb, line 90 def default_run lambda do |argv, stdin_data: nil| Open3.capture3(*argv, stdin_data: stdin_data) end end
Source
# File lib/banner_engine_runner.rb, line 72 def normalize_lines(output, lolcat: false, strip_ansi: false) text = output.to_s text = if lolcat AnsiToIrc.convert(text) elsif strip_ansi strip_ansi_codes(text) else text end lines = text.lines.map(&:rstrip) lines.pop while lines.last&.empty? lines.map { |line| TextUtil.truncate(TextAlign.dotize(line), MAX_LINE_WIDTH) } end
Source
# File lib/banner_engine_runner.rb, line 24 def render(id, text, run: default_run, timeout: DEFAULT_TIMEOUT, glyphs: nil, engine_option: nil) entry = BannerEngines.fetch(id) return { error: "Unknown banner engine." } unless entry if entry[:type] == :internal return { lines: BannerFont.render(text, glyphs: glyphs || BannerFont::GLYPHS) } end extras = engine_option&.fetch(:argv, []) || [] if entry[:pipeline] return render_pipeline(entry[:pipeline], text, run: run, timeout: timeout, extras: extras) end argv = entry[:argv].call(text, extras: extras) stdin_data = entry[:stdin] ? text : nil stdout, _stderr, status = run_with_timeout(run, argv, stdin_data: stdin_data, timeout: timeout) return { error: "Banner engine failed." } unless status.success? { lines: normalize_lines(stdout, lolcat: id == :lolcat || entry[:bin] == "lolcat") } rescue Timeout::Error { error: "Banner engine timed out." } rescue StandardError { error: "Banner engine failed." } end
Source
# File lib/banner_engine_runner.rb, line 50 def render_pipeline(stages, text, run:, timeout:, extras: []) data = text stages.each do |stage_id| stage = BannerEngines.fetch(stage_id) stage_extras = stage_id == :figlet ? extras : [] argv = stage[:argv].call(data, extras: stage_extras) stdin_data = stage[:stdin] ? data : nil stdout, _stderr, status = run_with_timeout(run, argv, stdin_data: stdin_data, timeout: timeout) return { error: "Banner engine failed." } unless status.success? data = stdout end { lines: normalize_lines(data, lolcat: stages.include?(:lolcat)) } end
Source
# File lib/banner_engine_runner.rb, line 66 def run_with_timeout(run, argv, stdin_data:, timeout:) Timeout.timeout(timeout) do run.call(argv, stdin_data: stdin_data) end end
Source
# File lib/banner_engine_runner.rb, line 86 def strip_ansi_codes(text) text.gsub(ANSI_PATTERN, "") end