#!/usr/bin/env ruby # coding: utf-8 require 'jr/cli/version' require 'optparse' require 'yajl' require 'coderay' opt = OptionParser.new opt.banner = "jr - Command-line JSON processor for Rubyists [Ver. #{Jr::Cli::VERSION}]\n\n" + "Usage: jr [options] [file...]" opt.version = Jr::Cli::VERSION opt.on('--require FILE', 'require the FILE before execution') { |file| require file } pretty = true opt.on('-c', '--compact-output', 'output each JSON in single line') { pretty = false } from_file = false filter_file = nil opt.on('-f', '--from-file FILE', 'read filter from file') { |file| from_file = true; filter_file = file } raw_output = false opt.on('-r', '--raw-output', 'output strings as raw output') { raw_output = true } raw_input = false opt.on('-R', '--raw-input', 'read each line as string') { raw_input = true } color_output = STDOUT.tty? opt.on('-C', '--color-output', 'output with colors even if writing to a pipe or a file') { color_output = true } opt.on('-M', '--monochrome-output', 'output without colors') { color_output = false } null_input = false opt.on('-n', '--null-input', 'use null as input instead of any files') { null_input = true } opt.parse! ARGV require 'jr/cli/core_ext' trap('INT') { exit 130 } if from_file inputs = ARGV[0] ? ARGV[0..-1].map {|f| open f } : [STDIN] jr_filter = open(filter_file).read else inputs = ARGV[1] ? ARGV[1..-1].map {|f| open f } : [STDIN] jr_filter = ARGV[0] || 'self' end if null_input input_enumerator = [nil] else if raw_input input_enumerator = Enumerator.new do |yielder| inputs.each do |input| input.each_line do |line| yielder.yield line.chop end end end.lazy else input_enumerator = Enumerator.new do |yielder| inputs.each do |input| Yajl::Parser.new(symbolize_keys: true).parse(input) do |d| yielder.yield d end end end.lazy end end result = input_enumerator.instance_eval(jr_filter) encoder = Yajl::Encoder.new(pretty: pretty) print_json = ->(data) do if raw_output and data.is_a? String puts data else if color_output puts CodeRay.scan(encoder.encode(data), :json).terminal else puts encoder.encode(data) end end end if result.is_a? Array or result.kind_of? Enumerator result.each do |data| print_json.call data end else print_json.call result end