lib/monolens/command.rb in monolens-0.5.3 vs lib/monolens/command.rb in monolens-0.6.0
- old
+ new
@@ -9,45 +9,55 @@
@argv = argv
@stdin = stdin
@stdout = stdout
@stderr = stderr
@pretty = false
+ @enclose = []
+ @output_format = :json
+ @stream = false
+ @fail_strategy = 'fail'
+ @override = false
+ #
+ @input_file = nil
+ @use_stdin = false
end
attr_reader :argv, :stdin, :stdout, :stderr
- attr_reader :pretty
+ attr_reader :pretty, :stream, :override
+ attr_reader :enclose_map, :fail_strategy
+ attr_reader :input_file, :use_stdin
def self.call(argv, stdin = $stdin, stdout = $stdout, stderr = $stderr)
new(argv, stdin, stdout, stderr).call
end
def call
- lens, input = options.parse!(argv)
- show_help_and_exit if lens.nil? || input.nil?
+ lens, @input_file = options.parse!(argv)
+ show_help_and_exit if lens.nil? || (@input_file.nil? && !use_stdin)
- lens, input = read_file(lens), read_file(input)
+ lens_data, input = read_file(lens), read_input
+ lens = build_lens(lens_data)
error_handler = ErrorHandler.new
- lens = Monolens.lens(lens)
result = lens.call(input, error_handler: error_handler)
unless error_handler.empty?
stderr.puts(error_handler.report)
end
- if result
- output = if pretty
- JSON.pretty_generate(result)
- else
- result.to_json
- end
-
- stdout.puts output
- end
+ output_result(result) if result
rescue Monolens::LensError => ex
stderr.puts("[#{ex.location.join('/')}] #{ex.message}")
do_exit(-2)
end
+ def read_input
+ if use_stdin
+ JSON.parse(stdin.read)
+ else
+ read_file(@input_file)
+ end
+ end
+
def read_file(file)
case ::File.extname(file)
when /json$/
content = ::File.read(file)
JSON.parse(content)
@@ -85,12 +95,99 @@
opts.on('--version', 'Show version and exit') do
stdout.puts "Monolens v#{VERSION} - (c) Enspirit #{Date.today.year}"
do_exit(0)
end
+ opts.on('-m', '--map', 'Enclose the loaded lens inside an array.map') do
+ @enclose << :map
+ end
+ opts.on('-l', '--literal', 'Enclose the loaded lens inside core.literal') do
+ @enclose << :literal
+ end
+ opts.on('--on-error=STRATEGY', 'Apply a specific strategy on error') do |strategy|
+ @fail_strategy = strategy
+ end
+ opts.on('-ILIB', 'Add a folder to ruby load path') do |lib|
+ $LOAD_PATH.unshift(lib)
+ end
+ opts.on('-rLIB', 'Add a ruby require of a lib') do |lib|
+ require(lib)
+ end
+ opts.on( '--stdin', 'Takes input data from STDIN') do
+ @use_stdin = true
+ end
opts.on('-p', '--[no-]pretty', 'Show version and exit') do |pretty|
@pretty = pretty
end
+ opts.on('-y', '--yaml', 'Print output in YAML') do
+ @output_format = :yaml
+ end
+ opts.on('-s', '--stream', 'Stream mode: output each result item separately') do
+ @stream = true
+ end
+ opts.on('-j', '--json', 'Print output in JSON') do
+ @output_format = :json
+ end
+ opts.on('--override', 'Write output back to the input file') do
+ @override = true
+ end
end
+ end
+
+ def build_lens(lens_data)
+ lens_data = @enclose.inject(lens_data) do |memo, lens_name|
+ case lens_name
+ when :map
+ {
+ 'array.map' => {
+ 'on_error' => ['handler', fail_strategy].compact,
+ 'lenses' => memo,
+ }
+ }
+ when :literal
+ {
+ 'core.literal' => {
+ 'defn' => memo,
+ }
+ }
+ end
+ end
+ Monolens.lens(lens_data)
+ end
+
+ def output_result(result)
+ with_output_io do |io|
+ output = case @output_format
+ when :json
+ output_json(result, io)
+ when :yaml
+ output_yaml(result, io)
+ end
+ end
+ end
+
+ def with_output_io(&block)
+ if override
+ ::File.open(@input_file, 'w', &block)
+ else
+ block.call(stdout)
+ end
+ end
+
+ def output_json(result, io)
+ method = pretty ? :pretty_generate : :generate
+ if stream
+ fail!("Stream mode only works with an output Array") unless result.is_a?(::Enumerable)
+ result.each do |item|
+ io.puts JSON.send(method, item)
+ end
+ else
+ io.puts JSON.send(method, result)
+ end
+ end
+
+ def output_yaml(result, io)
+ output = stream ? YAML.dump_stream(*result) : YAML.dump(result)
+ io.puts output
end
end
end