Class: SvgSentinel::CLI

Inherits:
Object
  • Object
show all
Defined in:
lib/svg_sentinel/cli.rb

Overview

Command-line entry point. Scans one or more SVG files (or STDIN) and exits non-zero when any input is unsafe, so it drops into CI and pre-commit hooks.

svg_sentinel logo.svg                 # exit 0 if safe, 1 if unsafe
cat logo.svg | svg_sentinel           # read from STDIN
svg_sentinel --format sarif *.svg     # SARIF for code scanning
svg_sentinel --context img icons/*.svg

Settings come from .svg_sentinel.yml (auto-discovered in the working directory, or --config PATH); command-line flags override the file.

Exit codes:

0  every input scanned and safe
1  at least one input scanned as unsafe (takes precedence, so CI fails)
2  a usage/config error, or an input could not be read

Constant Summary collapse

EXIT_SAFE =
0
EXIT_UNSAFE =
1
EXIT_ERROR =
2
SANITIZE_KEYS =

Options that Sanitizer accepts (context/overrides are scan-only).

%i[
  profile allow_external allow_data_uri
  max_bytes hard_max_bytes max_depth max_nodes max_attributes
].freeze

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(stdin: $stdin, stdout: $stdout, stderr: $stderr) ⇒ CLI

Returns a new instance of CLI.



40
41
42
43
44
45
# File 'lib/svg_sentinel/cli.rb', line 40

def initialize(stdin: $stdin, stdout: $stdout, stderr: $stderr)
  @stdin = stdin
  @stdout = stdout
  @stderr = stderr
  @done = false
end

Class Method Details

.run(argv, stdin: $stdin, stdout: $stdout, stderr: $stderr) ⇒ Object



36
37
38
# File 'lib/svg_sentinel/cli.rb', line 36

def self.run(argv, stdin: $stdin, stdout: $stdout, stderr: $stderr)
  new(stdin: stdin, stdout: stdout, stderr: stderr).run(argv)
end

Instance Method Details

#run(argv) ⇒ Object



47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/svg_sentinel/cli.rb', line 47

def run(argv)
  flags = {}
  meta = {format: :text, config: nil, sanitize: false}
  paths = parse!(argv, flags, meta)
  return EXIT_SAFE if @done # --help / --version already printed

  scan_opts = load_config(meta[:config]).to_scan_options.merge(flags)
  inputs = collect_inputs(paths)

  return run_sanitize(inputs, scan_opts) if meta[:sanitize]

  run_scan(inputs, scan_opts, meta[:format])
rescue OptionParser::ParseError, ConfigError => e
  @stderr.puts("svg_sentinel: #{e.message}")
  EXIT_ERROR
end