lib/yq.rb in yq-0.0.1 vs lib/yq.rb in yq-0.0.2

- old
+ new

@@ -1,26 +1,82 @@ require "yq/version" -require 'jmespath' +require 'open3' +require 'contracts' require 'stringio' require 'yaml' +require 'json' +require 'timeout' module Yq + def self.which(cmd) + exts = ENV['PATH'] ? ENV['PATH'].split(':') : [''] + exts.each { |ext| + exe = File.join(ext, cmd) + return exe if File.executable?(exe) && !File.directory?(exe) + } + return nil + end + def self.search_yaml(query, yaml) - hash = yaml_to_hash(yaml) - resp_hash = search(query, hash) - resp_yaml = hash_to_yaml(resp_hash) + req_json = yaml_to_json(yaml) + resp_json = search(query, req_json) + resp_yaml = json_to_yaml(resp_json) return resp_yaml end - def self.search(query, hash) - return hash if query == '.' - JMESPath.search(query, hash) + def self.search(query, json) + cmd = which('jq') + %Q[ '#{query}'] + input = json + output = "" + LOGGER.debug "sending jq #{cmd}" + + Open3.popen2(cmd) do |i, o, t| + begin + pid = t.pid + + if input + i.puts input + i.close + end + + Timeout.timeout(5) do + o.each { |v| + output << v + } + end + rescue Timeout::Error + LOGGER.warn "Timing out #{t.inspect} after 1 second" + Process.kill(15, pid) + ensure + status = t.value + raise "JQ failed to exit cleanly" unless status.success? + end + end + return output end + def self.yaml_to_json(yaml) + a = yaml_to_hash(yaml) + hash_to_json(a) + end + + def self.json_to_yaml(json) + a = json_to_hash(json) + hash_to_yaml(a) + end + def self.yaml_to_hash(yaml) YAML.parse(yaml).to_ruby end def self.hash_to_yaml(hash) hash.to_yaml + end + + def self.json_to_hash(json) + JSON.parse(json) + end + + def self.hash_to_json(hash) + hash.to_json end end