Class: Rjq::CLI

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

Defined Under Namespace

Classes: EarlyExit, OptionError

Constant Summary collapse

HELP =
<<~HELP.freeze
  rjq - commandline JSON processor [version #{VERSION}]

  Usage:	rjq [options] <jq filter> [file...]
  	rjq [options] --args <jq filter> [strings...]
  	rjq [options] --jsonargs <jq filter> [JSON_TEXTS...]

  rjq is a tool for processing JSON inputs, applying the given filter to
  its JSON text inputs and producing the filter's results as JSON on
  standard output.

  Command options:
    -n, --null-input          use `null` as the single input value;
    -R, --raw-input           read each line as string instead of JSON;
    -s, --slurp               read all inputs into an array and use it as
                              the single input value;
    -c, --compact-output      compact instead of pretty-printed output;
    -r, --raw-output          output strings without escapes and quotes;
        --raw-output0         implies -r and output NUL after each output;
    -j, --join-output         implies -r and output without newline after
                              each output;
    -a, --ascii-output        output strings by only ASCII characters
                              using escape sequences;
    -S, --sort-keys           sort keys of each object on output;
    -C, --color-output        colorize JSON output;
    -M, --monochrome-output   disable colored output;
        --tab                 use tabs for indentation;
        --indent n            use n spaces for indentation (max 7 spaces);
        --unbuffered          flush output stream after each output;
        --stream              parse the input value in streaming fashion;
        --stream-errors       implies --stream and report parse error as
                              an array;
        --seq                 parse input/output as application/json-seq;
        --max-filter-depth n  reject filters nested deeper than n;
        --max-call-depth n    bound non-tail user-function calls;
        --max-instructions n  bound executed bytecode instructions;
        --max-replay-cache n  bound values cached for filter replay;
    -f, --from-file file      load filter from the file;
    -L directory              search modules from the directory;
        --arg name value      set $name to the string value;
        --argjson name value  set $name to the JSON value;
        --slurpfile name file set $name to an array of JSON values read
                              from the file;
        --rawfile name file   set $name to string contents of file;
        --args                consume remaining arguments as positional
                              string values;
        --jsonargs            consume remaining arguments as positional
                              JSON values;
    -e, --exit-status         set exit status code based on the output;
    -V, --version             show the version;
    --build-configuration     show rjq's build configuration;
    -h, --help                show the help;
    --                        terminates argument processing;

  Named arguments are also available as $ARGS.named[], while
  positional arguments are available as $ARGS.positional[].
HELP
OPTION_HELP =
<<~HELP
  Use rjq --help for help with command-line options,
  or see the jq manpage, or online docs at https://jqlang.github.io/jq
HELP

Instance Method Summary collapse

Constructor Details

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

Returns a new instance of CLI.



79
80
81
82
83
84
85
86
87
# File 'lib/rjq/cli.rb', line 79

def initialize(argv, stdin:, stdout:, stderr:)
  @argv = argv.dup
  @stdin = stdin
  @stdout = stdout
  @stderr = stderr
  @opts = Runtime::DEFAULT_OPTIONS.merge(variables: { 'ARGS.named' => {}, 'ARGS.positional' => [] })
  @filter = nil
  @files = []
end

Instance Method Details

#runObject



89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
# File 'lib/rjq/cli.rb', line 89

def run
  parse!
  return run_tests if @opts[:run_tests]

  @opts[:stderr] = @stderr
  @opts[:color] = @stdout.tty? && !ENV.key?('NO_COLOR') if @opts[:color].nil?
  runtime_failed = false
  @opts[:runtime_error_handler] = lambda do |error, _record|
    runtime_failed = true
    @stderr.puts("rjq: runtime error: #{error.message}")
  end
  last = nil
  count = 0
  runtime = Runtime.new(@filter || '.', @opts)
  runtime.run_io_streams(input_streams).each do |value|
    last = value
    count += 1
    write_value(runtime, value)
  end
  return 5 if runtime_failed
  return exit_status(last, count) if @opts[:exit_status]

  0
rescue HaltError => e
  @stderr.puts(e.message) if e.value
  e.status
rescue EarlyExit => e
  e.status
rescue OptionError => e
  @stderr.puts(e.message)
  @stderr.print(OPTION_HELP)
  2
rescue JSONParseError => e
  @stderr.puts("rjq: JSON parse error: #{e.message}")
  5
rescue ParseError, CompileError => e
  @stderr.puts("rjq: compile error: #{e.message}")
  3
rescue Rjq::RuntimeError => e
  @stderr.puts("rjq: runtime error: #{e.message}")
  5
rescue SystemStackError
  @stderr.puts('rjq: runtime error: recursion limit exceeded')
  5
rescue Errno::EPIPE
  0
rescue Errno::ENOENT, Errno::EACCES, Errno::EISDIR => e
  @stderr.puts("rjq: #{e.message}")
  2
end