yq 0.1.1 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/.github/dependabot.yml +14 -0
- data/.github/workflows/rspec_and_release.yml +54 -0
- data/.gitignore +2 -2
- data/Gemfile +1 -9
- data/Guardfile +3 -3
- data/README.md +6 -15
- data/Rakefile +1 -2
- data/bin/yq +23 -25
- data/lib/yq.rb +45 -34
- data/lib/yq/version.rb +1 -1
- data/release.config.js +43 -0
- data/spec/spec_helper.rb +2 -6
- data/spec/yq_bin_spec.rb +21 -23
- data/spec/yq_spec.rb +105 -54
- data/yq.gemspec +16 -13
- metadata +76 -18
- data/.travis.yml +0 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 6976e6a19af13ebbe442c23b74ffaaebfbd751de6893a9953182d346264d6089
|
4
|
+
data.tar.gz: bbce1e5d4b1430d6f158e6e8c0f669db83af69b6c1256358f55dffc653b5d750
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 172d6483b7a3a5b8a6e7a6cf37e63d031b816e297ce602ef25890e452dabaac19578d967d606cd6daeb5c5f4611fa9d0a1231979a2c44736f18f5952ca9276bc
|
7
|
+
data.tar.gz: f8565b4d2878a21c90a1fcfe45eb5ae91653361260faebe8cfc0637b8c86b3e360b35862fb00e960913c34cbb945c87959c041ab5bb73cea2a925bb10b621073
|
@@ -0,0 +1,14 @@
|
|
1
|
+
version: 2
|
2
|
+
updates:
|
3
|
+
- package-ecosystem: "bundler"
|
4
|
+
directory: "/" # Location of package manifests
|
5
|
+
schedule:
|
6
|
+
interval: "daily"
|
7
|
+
commit-message:
|
8
|
+
prefix: "fix"
|
9
|
+
prefix-development: "chore"
|
10
|
+
include: "scope"
|
11
|
+
- package-ecosystem: "github-actions"
|
12
|
+
directory: "/" # Location of package manifests
|
13
|
+
schedule:
|
14
|
+
interval: "daily"
|
@@ -0,0 +1,54 @@
|
|
1
|
+
name: Rspec and Release
|
2
|
+
|
3
|
+
on:
|
4
|
+
push:
|
5
|
+
pull_request:
|
6
|
+
workflow_dispatch:
|
7
|
+
|
8
|
+
jobs:
|
9
|
+
rspec:
|
10
|
+
strategy:
|
11
|
+
fail-fast: false
|
12
|
+
matrix:
|
13
|
+
os: [ubuntu-latest, macos-latest]
|
14
|
+
# Due to https://github.com/actions/runner/issues/849, we have to use quotes for '3.0'
|
15
|
+
ruby: [2.5, 2.6, 2.7]
|
16
|
+
runs-on: ${{ matrix.os }}
|
17
|
+
steps:
|
18
|
+
- uses: actions/checkout@v2
|
19
|
+
- name: Set up Ruby
|
20
|
+
uses: ruby/setup-ruby@v1
|
21
|
+
with:
|
22
|
+
ruby-version: ${{ matrix.ruby }}
|
23
|
+
bundler-cache: true
|
24
|
+
- name: Test with Rspec
|
25
|
+
run: |
|
26
|
+
bundle exec rspec --format documentation --require spec_helper
|
27
|
+
release:
|
28
|
+
if: github.event_name == 'push'
|
29
|
+
needs: rspec
|
30
|
+
runs-on: ubuntu-latest
|
31
|
+
env:
|
32
|
+
BUNDLE_DEPLOYMENT: true
|
33
|
+
steps:
|
34
|
+
- uses: actions/checkout@v2
|
35
|
+
- name: Set up Ruby 2.7
|
36
|
+
uses: ruby/setup-ruby@v1
|
37
|
+
with:
|
38
|
+
ruby-version: 2.7
|
39
|
+
bundler-cache: true
|
40
|
+
- name: Zip
|
41
|
+
run : |
|
42
|
+
zip -r yq.zip ./*
|
43
|
+
- name: Semantic Release
|
44
|
+
id: semantic
|
45
|
+
uses: cycjimmy/semantic-release-action@v2
|
46
|
+
env:
|
47
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
48
|
+
GEM_HOST_API_KEY: ${{ secrets.RUBYGEMS_API_TOKEN }}
|
49
|
+
with:
|
50
|
+
semantic_version: 17
|
51
|
+
extra_plugins: |
|
52
|
+
@semantic-release/changelog
|
53
|
+
@semantic-release/git
|
54
|
+
semantic-release-rubygem
|
data/.gitignore
CHANGED
@@ -109,8 +109,8 @@ build/
|
|
109
109
|
# for a library or gem, you might want to ignore these files since the code is
|
110
110
|
# intended to run in multiple environments; otherwise, check them in:
|
111
111
|
Gemfile.lock
|
112
|
-
.ruby-version
|
113
|
-
.ruby-gemset
|
112
|
+
.ruby-version*
|
113
|
+
.ruby-gemset*
|
114
114
|
|
115
115
|
# unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
|
116
116
|
.rvmrc
|
data/Gemfile
CHANGED
data/Guardfile
CHANGED
@@ -1,9 +1,9 @@
|
|
1
|
-
directories %w
|
1
|
+
directories %w[lib bin spec]
|
2
2
|
|
3
3
|
clearing :on
|
4
4
|
|
5
|
-
guard :rspec, cmd:
|
6
|
-
require
|
5
|
+
guard :rspec, cmd: 'bundle exec rspec' do
|
6
|
+
require 'guard/rspec/dsl'
|
7
7
|
dsl = Guard::RSpec::Dsl.new(self)
|
8
8
|
|
9
9
|
# Feel free to open issues for suggestions and improvements
|
data/README.md
CHANGED
@@ -1,24 +1,13 @@
|
|
1
1
|
# Yq
|
2
2
|
|
3
3
|
[](http://badge.fury.io/rb/yq)
|
4
|
-
|
5
|
-
[](https://coveralls.io/github/jim80net/yq?branch=master)
|
4
|
+

|
6
5
|
|
7
|
-
Use `yq` to parse YAML documents using [jq](https://stedolan.github.io/jq/). This gem is a simple wrapper around the executable. `jq`
|
6
|
+
Use `yq` to parse YAML documents using [jq](https://stedolan.github.io/jq/). This gem is a simple wrapper around the executable. It will convert the YAML input into JSON, run `jq` against it, then convert the output back into YAML. Sometimes, `jq` will output non-JSON, but `yq` will just turn that into valid YAML.
|
8
7
|
|
9
|
-
|
10
|
-
|
11
|
-
Add this line to your application's Gemfile:
|
12
|
-
|
13
|
-
```ruby
|
14
|
-
gem 'yq'
|
15
|
-
```
|
8
|
+
`jq` should be available in your `$PATH` to use this gem.
|
16
9
|
|
17
|
-
|
18
|
-
|
19
|
-
$ bundle
|
20
|
-
|
21
|
-
Or install it yourself as:
|
10
|
+
## Installation
|
22
11
|
|
23
12
|
$ gem install yq
|
24
13
|
|
@@ -39,6 +28,8 @@ bar: baz
|
|
39
28
|
|
40
29
|
```
|
41
30
|
|
31
|
+
`yq` converts the STDIN to JSON, and passes it to `jq`, along with the `jq` query you specify. The result is then turned back into YAML.
|
32
|
+
|
42
33
|
## Contributing
|
43
34
|
|
44
35
|
1. Fork it ( https://github.com/jim80net/yq/fork )
|
data/Rakefile
CHANGED
data/bin/yq
CHANGED
@@ -8,17 +8,15 @@ require 'optparse'
|
|
8
8
|
require 'yq'
|
9
9
|
|
10
10
|
$stdout.sync = $stderr.sync = true
|
11
|
-
unless defined?(LOGGER)
|
12
|
-
LOGGER = Logger.new($stderr)
|
13
|
-
end
|
11
|
+
LOGGER = Logger.new($stderr) unless defined?(LOGGER)
|
14
12
|
LOGGER.level = Logger::INFO
|
15
13
|
|
16
14
|
@options = {
|
17
|
-
context: :main_loop
|
15
|
+
context: :main_loop,
|
16
|
+
output: :yaml
|
18
17
|
}
|
19
18
|
|
20
|
-
|
21
|
-
def prereqs
|
19
|
+
def prereqs
|
22
20
|
ARGV << '--help' if ARGV.empty?
|
23
21
|
|
24
22
|
opts = OptionParser.new do |opts|
|
@@ -28,45 +26,46 @@ def prereqs
|
|
28
26
|
puts opts
|
29
27
|
exit 0
|
30
28
|
end
|
31
|
-
opts.on('--verbose', '-v', 'verbose') do
|
29
|
+
opts.on('--verbose', '-v', 'verbose') do
|
32
30
|
LOGGER.level = Logger::DEBUG
|
33
31
|
end
|
34
|
-
opts.on(
|
32
|
+
opts.on('--develop', 'Run in developer mode') do
|
35
33
|
@options[:context] = :develop
|
36
34
|
end
|
35
|
+
opts.on('-r', '--raw-output') do
|
36
|
+
@options[:output] = :raw
|
37
|
+
end
|
38
|
+
opts.on('--json-output') do
|
39
|
+
@options[:output] = :json
|
40
|
+
end
|
37
41
|
end
|
38
42
|
opts.parse!
|
39
|
-
|
43
|
+
|
40
44
|
required_vars = %w[
|
41
45
|
]
|
42
46
|
required_vars.each do |v|
|
43
47
|
raise "#{v} must be specified in the environment variables" unless ENV[v]
|
44
48
|
end
|
45
49
|
|
46
|
-
raise
|
50
|
+
raise 'jq not installed' unless Yq.which('jq')
|
47
51
|
end
|
48
52
|
|
49
|
-
|
50
53
|
def start
|
51
|
-
|
52
|
-
@yaml = $stdin.read
|
53
|
-
|
54
|
-
puts Yq.search_yaml(ARGV[0], @yaml)
|
54
|
+
@yaml = $stdin.read
|
55
55
|
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
raise
|
56
|
+
puts Yq.search_yaml(ARGV[0], @yaml, output: @options[:output])
|
57
|
+
rescue StandardError => e
|
58
|
+
LOGGER.error "Unhandled exception #{e.class}: #{e.message}"
|
59
|
+
e.backtrace.each do |v|
|
60
|
+
LOGGER.debug v
|
62
61
|
end
|
63
|
-
|
62
|
+
raise
|
64
63
|
end
|
65
64
|
|
66
65
|
def develop
|
67
66
|
require 'pry'
|
68
67
|
LOGGER.level = Logger::DEBUG
|
69
|
-
LOGGER.info
|
68
|
+
LOGGER.info 'Develop mode'
|
70
69
|
start
|
71
70
|
end
|
72
71
|
|
@@ -74,6 +73,5 @@ def main_loop
|
|
74
73
|
start
|
75
74
|
end
|
76
75
|
|
77
|
-
|
78
76
|
prereqs
|
79
|
-
|
77
|
+
send(@options[:context])
|
data/lib/yq.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require 'yq/version'
|
2
2
|
require 'open3'
|
3
3
|
require 'stringio'
|
4
4
|
require 'yaml'
|
@@ -8,49 +8,53 @@ require 'timeout'
|
|
8
8
|
module Yq
|
9
9
|
def self.which(cmd)
|
10
10
|
exts = ENV['PATH'] ? ENV['PATH'].split(':') : ['']
|
11
|
-
exts.each
|
11
|
+
exts.each do |ext|
|
12
12
|
exe = File.join(ext, cmd)
|
13
13
|
return exe if File.executable?(exe) && !File.directory?(exe)
|
14
|
-
|
15
|
-
|
14
|
+
end
|
15
|
+
nil
|
16
16
|
end
|
17
17
|
|
18
|
-
def self.search_yaml(query, yaml)
|
18
|
+
def self.search_yaml(query, yaml, output: :yaml)
|
19
19
|
req_json = yaml_to_json(yaml)
|
20
|
-
|
21
|
-
|
22
|
-
|
20
|
+
case output
|
21
|
+
when :raw
|
22
|
+
search(query, req_json, flags: ['--raw-output'])
|
23
|
+
when :json
|
24
|
+
search(query, req_json)
|
25
|
+
when :yaml
|
26
|
+
resp_json = search(query, req_json)
|
27
|
+
json_to_yaml(resp_json)
|
28
|
+
end
|
23
29
|
end
|
24
30
|
|
25
|
-
def self.search(query, json)
|
26
|
-
cmd = which('jq') +
|
31
|
+
def self.search(query, json, flags: [])
|
32
|
+
cmd = [which('jq')] + flags + [query]
|
27
33
|
input = json
|
28
|
-
output =
|
34
|
+
output = ''
|
29
35
|
LOGGER.debug "sending jq #{cmd}"
|
30
36
|
|
31
|
-
Open3.popen2(cmd) do |i, o, t|
|
32
|
-
|
33
|
-
pid = t.pid
|
37
|
+
Open3.popen2(*cmd) do |i, o, t|
|
38
|
+
pid = t.pid
|
34
39
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
40
|
+
if input
|
41
|
+
i.puts input
|
42
|
+
i.close
|
43
|
+
end
|
39
44
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
}
|
45
|
+
Timeout.timeout(5) do
|
46
|
+
o.each do |v|
|
47
|
+
output << v
|
44
48
|
end
|
45
|
-
rescue Timeout::Error
|
46
|
-
LOGGER.warn "Timing out #{t.inspect} after 1 second"
|
47
|
-
Process.kill(15, pid)
|
48
|
-
ensure
|
49
|
-
status = t.value
|
50
|
-
raise "JQ failed to exit cleanly" unless status.success?
|
51
49
|
end
|
50
|
+
rescue Timeout::Error
|
51
|
+
LOGGER.warn "Timing out #{t.inspect} after 1 second"
|
52
|
+
Process.kill(15, pid)
|
53
|
+
ensure
|
54
|
+
status = t.value
|
55
|
+
raise 'JQ failed to exit cleanly' unless status.success?
|
52
56
|
end
|
53
|
-
|
57
|
+
output
|
54
58
|
end
|
55
59
|
|
56
60
|
def self.yaml_to_json(yaml)
|
@@ -73,8 +77,8 @@ module Yq
|
|
73
77
|
|
74
78
|
def self.json_to_hash(json)
|
75
79
|
JSON.parse(json)
|
76
|
-
rescue JSON::ParserError
|
77
|
-
LOGGER.debug
|
80
|
+
rescue JSON::ParserError
|
81
|
+
LOGGER.debug 'Non JSON output from jq. Interpreting.'
|
78
82
|
interpret_non_json_output(json)
|
79
83
|
end
|
80
84
|
|
@@ -83,9 +87,16 @@ module Yq
|
|
83
87
|
end
|
84
88
|
|
85
89
|
def self.interpret_non_json_output(string)
|
86
|
-
|
87
|
-
|
88
|
-
|
90
|
+
regex = /(^\{.+?^\}|^\[.+?\]|^".+?")/m
|
91
|
+
matches = string.scan(regex)
|
92
|
+
|
93
|
+
without_the_wrapping_array = matches.map(&:first)
|
94
|
+
without_the_wrapping_array.map do |line|
|
95
|
+
JSON.parse(line)
|
96
|
+
rescue JSON::ParserError
|
97
|
+
LOGGER.debug "Assuming #{line} is a string."
|
98
|
+
obj = JSON.parse(%({ "value": #{line} }))
|
99
|
+
obj['value']
|
89
100
|
end
|
90
101
|
end
|
91
102
|
end
|
data/lib/yq/version.rb
CHANGED
data/release.config.js
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
module.exports = {
|
2
|
+
"plugins": [
|
3
|
+
"@semantic-release/commit-analyzer",
|
4
|
+
"@semantic-release/release-notes-generator",
|
5
|
+
[
|
6
|
+
"@semantic-release/changelog",
|
7
|
+
{
|
8
|
+
"changelogFile": "CHANGELOG.md"
|
9
|
+
}
|
10
|
+
],
|
11
|
+
[
|
12
|
+
"semantic-release-rubygem",
|
13
|
+
{
|
14
|
+
"gemFileDir": "."
|
15
|
+
}
|
16
|
+
],
|
17
|
+
[
|
18
|
+
"@semantic-release/git",
|
19
|
+
{
|
20
|
+
"assets": [
|
21
|
+
"CHANGELOG.md"
|
22
|
+
],
|
23
|
+
"message": "chore(release): ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}"
|
24
|
+
}
|
25
|
+
],
|
26
|
+
[
|
27
|
+
"@semantic-release/github",
|
28
|
+
{
|
29
|
+
"assets": [
|
30
|
+
{
|
31
|
+
"path": "yq.zip",
|
32
|
+
"name": "yq.${nextRelease.version}.zip",
|
33
|
+
"label": "Full zip distribution"
|
34
|
+
},
|
35
|
+
{
|
36
|
+
"path": "yq-*.gem",
|
37
|
+
"label": "Gem distribution"
|
38
|
+
}
|
39
|
+
]
|
40
|
+
}
|
41
|
+
],
|
42
|
+
]
|
43
|
+
};
|
data/spec/spec_helper.rb
CHANGED
@@ -1,15 +1,11 @@
|
|
1
|
-
$:.unshift(File.expand_path(
|
2
|
-
|
3
|
-
require 'coveralls'
|
4
|
-
Coveralls.wear!
|
1
|
+
$:.unshift(File.expand_path('../lib', File.dirname(__FILE__)))
|
5
2
|
|
6
3
|
require 'logger'
|
7
4
|
require 'pry'
|
8
5
|
require 'yq'
|
9
6
|
|
10
|
-
|
11
7
|
LOGGER = Logger.new('/dev/null')
|
12
|
-
SPEC_ROOT =
|
8
|
+
SPEC_ROOT = __dir__
|
13
9
|
WORK_ROOT = File.expand_path(File.join(SPEC_ROOT, '..'))
|
14
10
|
|
15
11
|
RSpec.configure do |config|
|
data/spec/yq_bin_spec.rb
CHANGED
@@ -4,30 +4,28 @@ require 'timeout'
|
|
4
4
|
|
5
5
|
describe 'bin/yq' do
|
6
6
|
# Contract Or[nil,String] => self
|
7
|
-
def run_bin(args =
|
7
|
+
def run_bin(args = '', input = nil)
|
8
8
|
status = nil
|
9
|
-
output =
|
9
|
+
output = ''
|
10
10
|
cmd = "bin/yq #{args}"
|
11
11
|
Open3.popen2e(cmd) do |i, oe, t|
|
12
|
-
|
13
|
-
pid = t.pid
|
12
|
+
pid = t.pid
|
14
13
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
14
|
+
if input
|
15
|
+
i.puts input
|
16
|
+
i.close
|
17
|
+
end
|
19
18
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
}
|
19
|
+
Timeout.timeout(1.0) do
|
20
|
+
oe.each do |v|
|
21
|
+
output << v
|
24
22
|
end
|
25
|
-
rescue Timeout::Error
|
26
|
-
LOGGER.warn "Timing out #{t.inspect} after 1 second"
|
27
|
-
Process.kill(15, pid)
|
28
|
-
ensure
|
29
|
-
status = t.value
|
30
23
|
end
|
24
|
+
rescue Timeout::Error
|
25
|
+
LOGGER.warn "Timing out #{t.inspect} after 1 second"
|
26
|
+
Process.kill(15, pid)
|
27
|
+
ensure
|
28
|
+
status = t.value
|
31
29
|
end
|
32
30
|
[output, status]
|
33
31
|
end
|
@@ -51,17 +49,17 @@ describe 'bin/yq' do
|
|
51
49
|
end
|
52
50
|
|
53
51
|
it 'supplies help' do
|
54
|
-
out_err, status = run_bin(
|
52
|
+
out_err, status = run_bin('--help')
|
55
53
|
expect(out_err).to match(/Usage: yq/)
|
56
54
|
expect(status).to be_success
|
57
55
|
end
|
58
56
|
|
59
57
|
describe 'parses' do
|
60
|
-
let(:yaml) {
|
61
|
-
foo:
|
62
|
-
|
63
|
-
|
64
|
-
EOF
|
58
|
+
let(:yaml) { <<~EOF }
|
59
|
+
foo:
|
60
|
+
bar:
|
61
|
+
baz: value
|
62
|
+
EOF
|
65
63
|
|
66
64
|
it '.foo.bar' do
|
67
65
|
out_err, status = run_bin('.foo.bar', yaml)
|
data/spec/yq_spec.rb
CHANGED
@@ -1,52 +1,99 @@
|
|
1
1
|
describe Yq do
|
2
2
|
subject { described_class }
|
3
3
|
|
4
|
-
let(:hash)
|
5
|
-
{
|
6
|
-
|
7
|
-
|
8
|
-
let(:yaml) {
|
9
|
-
foo:
|
10
|
-
|
11
|
-
|
12
|
-
EOF
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
}
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
"foo"
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
4
|
+
let(:hash) do
|
5
|
+
{ 'foo' => { 'bar' => { "'" => 'value' } } }
|
6
|
+
end
|
7
|
+
|
8
|
+
let(:yaml) { <<~EOF }
|
9
|
+
foo:
|
10
|
+
bar:
|
11
|
+
"'": value
|
12
|
+
EOF
|
13
|
+
|
14
|
+
# support equivalent YAML syntaxes (depends on ruby version)
|
15
|
+
let(:yaml_regexp) { <<~EOF }
|
16
|
+
foo:
|
17
|
+
bar:
|
18
|
+
("'"|''''|! ''''): value
|
19
|
+
EOF
|
20
|
+
|
21
|
+
let(:json) { <<~EOF.chomp }
|
22
|
+
{"foo":{"bar":{"'":"value"}}}
|
23
|
+
EOF
|
24
|
+
|
25
|
+
let(:jq_query) { %q({"\\t": .foo.bar["'"]}) }
|
26
|
+
|
27
|
+
let(:jq_response) { <<~EOF }
|
28
|
+
{
|
29
|
+
"\\t": "value"
|
30
|
+
}
|
31
|
+
EOF
|
32
|
+
|
33
|
+
let(:jq_non_json_response) { <<~EOF }
|
34
|
+
"foo"
|
35
|
+
"bar"
|
36
|
+
"baz"
|
37
|
+
EOF
|
38
|
+
|
39
|
+
let(:yaml_from_non_json_response) { <<~EOF }
|
40
|
+
---
|
41
|
+
- foo
|
42
|
+
- bar
|
43
|
+
- baz
|
44
|
+
EOF
|
45
|
+
|
46
|
+
let(:jq_non_json_response_2) { <<~EOF }
|
47
|
+
{
|
48
|
+
"foo": "bar",
|
49
|
+
"baz": {
|
50
|
+
"blah": 10240,
|
51
|
+
"asdf": "qwer"
|
52
|
+
},
|
53
|
+
"bing": "bo.ng"
|
54
|
+
}
|
55
|
+
{
|
56
|
+
"foo": "far",
|
57
|
+
"bing": "ba.ng"
|
58
|
+
}
|
59
|
+
[1,2,3]
|
60
|
+
[4,5,6]
|
61
|
+
"asdf"
|
62
|
+
"qwer"
|
63
|
+
EOF
|
64
|
+
|
65
|
+
let(:yaml_from_non_json_response_2) { <<~EOF }
|
66
|
+
---
|
67
|
+
- foo: bar
|
68
|
+
baz:
|
69
|
+
blah: 10240
|
70
|
+
asdf: qwer
|
71
|
+
bing: bo.ng
|
72
|
+
- foo: far
|
73
|
+
bing: ba.ng
|
74
|
+
- - 1
|
75
|
+
- 2
|
76
|
+
- 3
|
77
|
+
- - 4
|
78
|
+
- 5
|
79
|
+
- 6
|
80
|
+
- asdf
|
81
|
+
- qwer
|
82
|
+
EOF
|
36
83
|
|
37
84
|
describe '.search' do
|
38
|
-
subject { described_class.search(
|
85
|
+
subject { described_class.search(jq_query, json) }
|
39
86
|
|
40
87
|
it { is_expected.to match(jq_response) }
|
41
88
|
|
42
89
|
it 'passes it through to jq' do
|
43
90
|
allow(Yq).to receive(:which).with('jq').and_return('/bin/jq')
|
44
|
-
expect(Open3).to receive(:popen2).with(
|
91
|
+
expect(Open3).to receive(:popen2).with('/bin/jq', jq_query).and_return(jq_response)
|
45
92
|
subject
|
46
93
|
end
|
47
94
|
|
48
95
|
context 'unclean exit' do
|
49
|
-
subject { described_class.search'.foobar', json }
|
96
|
+
subject { described_class.search '.foobar', json }
|
50
97
|
|
51
98
|
it 'stops processing when jq exits uncleanly' do
|
52
99
|
# not mocking at this level, see implementation
|
@@ -61,7 +108,7 @@ EOF
|
|
61
108
|
|
62
109
|
describe '.hash_to_yaml' do
|
63
110
|
subject { described_class.hash_to_yaml(hash) }
|
64
|
-
it { is_expected.to match(
|
111
|
+
it { is_expected.to match(yaml_regexp) }
|
65
112
|
end
|
66
113
|
|
67
114
|
describe '.yaml_to_json' do
|
@@ -71,43 +118,47 @@ EOF
|
|
71
118
|
|
72
119
|
describe '.json_to_yaml' do
|
73
120
|
subject { described_class.json_to_yaml(json) }
|
74
|
-
it { is_expected.to match(
|
121
|
+
it { is_expected.to match(yaml_regexp) }
|
75
122
|
|
76
123
|
context 'non-json response' do
|
77
124
|
subject { described_class.json_to_yaml(jq_non_json_response) }
|
78
|
-
it {is_expected.to match(yaml_from_non_json_response)}
|
125
|
+
it { is_expected.to match(yaml_from_non_json_response) }
|
126
|
+
end
|
127
|
+
|
128
|
+
context 'non-json response 2' do
|
129
|
+
subject { described_class.json_to_yaml(jq_non_json_response_2) }
|
130
|
+
it { is_expected.to match(yaml_from_non_json_response_2) }
|
79
131
|
end
|
80
132
|
end
|
81
133
|
|
82
134
|
describe '.search_yaml' do
|
83
135
|
subject { described_class.search_yaml('.foo.bar', yaml) }
|
84
136
|
|
85
|
-
it { is_expected.to match("
|
137
|
+
it { is_expected.to match(/("'"|''''|! ''''): value/) }
|
86
138
|
end
|
87
139
|
|
88
|
-
|
89
140
|
describe '.which' do
|
90
141
|
subject { described_class.which('jq') }
|
91
142
|
|
92
|
-
before(:each)
|
93
|
-
allow(ENV).to receive(:[]).with('PATH').and_return(
|
94
|
-
allow(File).to receive(:executable?).with(
|
95
|
-
allow(File).to receive(:directory?).with(
|
96
|
-
allow(File).to receive(:directory?).with(
|
97
|
-
|
143
|
+
before(:each) do
|
144
|
+
allow(ENV).to receive(:[]).with('PATH').and_return('/bin:/other/bin')
|
145
|
+
allow(File).to receive(:executable?).with('/bin/jq').and_return(false)
|
146
|
+
allow(File).to receive(:directory?).with('/bin/jq').and_return(false)
|
147
|
+
allow(File).to receive(:directory?).with('/other/bin/jq').and_return(false)
|
148
|
+
end
|
98
149
|
|
99
150
|
context 'but it does not exist' do
|
100
|
-
before(:each)
|
101
|
-
allow(File).to receive(:executable?).with(
|
102
|
-
|
103
|
-
it
|
151
|
+
before(:each) do
|
152
|
+
allow(File).to receive(:executable?).with('/other/bin/jq').and_return(false)
|
153
|
+
end
|
154
|
+
it { is_expected.to be_falsey }
|
104
155
|
end
|
105
156
|
|
106
157
|
context 'and it does exist' do
|
107
|
-
before(:each)
|
108
|
-
allow(File).to receive(:executable?).with(
|
109
|
-
|
110
|
-
it
|
158
|
+
before(:each) do
|
159
|
+
allow(File).to receive(:executable?).with('/other/bin/jq').and_return(true)
|
160
|
+
end
|
161
|
+
it { is_expected.to eq('/other/bin/jq') }
|
111
162
|
end
|
112
163
|
end
|
113
164
|
end
|
data/yq.gemspec
CHANGED
@@ -1,26 +1,29 @@
|
|
1
|
-
|
2
|
-
lib = File.expand_path('../lib', __FILE__)
|
1
|
+
lib = File.expand_path('lib', __dir__)
|
3
2
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
3
|
require 'yq/version'
|
5
4
|
|
6
5
|
Gem::Specification.new do |spec|
|
7
|
-
spec.name =
|
6
|
+
spec.name = 'yq'
|
8
7
|
spec.version = Yq::VERSION
|
9
|
-
spec.authors = [
|
10
|
-
spec.email = [
|
11
|
-
spec.summary =
|
8
|
+
spec.authors = ['Jim Park']
|
9
|
+
spec.email = ['yq@jim80.net']
|
10
|
+
spec.summary = 'A JQ wrapper for YAML'
|
12
11
|
spec.description = "This unceremoniously shells out to a jq available in $PATH.
|
13
12
|
Please make sure jq is installed."
|
14
|
-
spec.homepage =
|
15
|
-
spec.license =
|
13
|
+
spec.homepage = 'https://github.com/jim80net/yq'
|
14
|
+
spec.license = 'GPLv2'
|
16
15
|
|
17
16
|
spec.files = `git ls-files -z`.split("\x0")
|
18
17
|
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
19
18
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
20
|
-
spec.require_paths = [
|
19
|
+
spec.require_paths = ['lib']
|
21
20
|
|
22
|
-
spec.add_development_dependency
|
23
|
-
spec.add_development_dependency
|
24
|
-
spec.add_development_dependency
|
25
|
-
spec.add_development_dependency
|
21
|
+
spec.add_development_dependency 'bundler'
|
22
|
+
spec.add_development_dependency 'climate_control'
|
23
|
+
spec.add_development_dependency 'guard'
|
24
|
+
spec.add_development_dependency 'guard-rspec'
|
25
|
+
spec.add_development_dependency 'pry'
|
26
|
+
spec.add_development_dependency 'rake'
|
27
|
+
spec.add_development_dependency 'rspec'
|
28
|
+
spec.add_development_dependency 'rubocop'
|
26
29
|
end
|
metadata
CHANGED
@@ -1,59 +1,115 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: yq
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jim Park
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-05-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - "
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: climate_control
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: guard
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
18
53
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: guard-rspec
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
20
62
|
type: :development
|
21
63
|
prerelease: false
|
22
64
|
version_requirements: !ruby/object:Gem::Requirement
|
23
65
|
requirements:
|
24
|
-
- - "
|
66
|
+
- - ">="
|
25
67
|
- !ruby/object:Gem::Version
|
26
|
-
version: '
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: pry
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
27
83
|
- !ruby/object:Gem::Dependency
|
28
84
|
name: rake
|
29
85
|
requirement: !ruby/object:Gem::Requirement
|
30
86
|
requirements:
|
31
|
-
- - "
|
87
|
+
- - ">="
|
32
88
|
- !ruby/object:Gem::Version
|
33
|
-
version: '
|
89
|
+
version: '0'
|
34
90
|
type: :development
|
35
91
|
prerelease: false
|
36
92
|
version_requirements: !ruby/object:Gem::Requirement
|
37
93
|
requirements:
|
38
|
-
- - "
|
94
|
+
- - ">="
|
39
95
|
- !ruby/object:Gem::Version
|
40
|
-
version: '
|
96
|
+
version: '0'
|
41
97
|
- !ruby/object:Gem::Dependency
|
42
98
|
name: rspec
|
43
99
|
requirement: !ruby/object:Gem::Requirement
|
44
100
|
requirements:
|
45
|
-
- - "
|
101
|
+
- - ">="
|
46
102
|
- !ruby/object:Gem::Version
|
47
|
-
version: '
|
103
|
+
version: '0'
|
48
104
|
type: :development
|
49
105
|
prerelease: false
|
50
106
|
version_requirements: !ruby/object:Gem::Requirement
|
51
107
|
requirements:
|
52
|
-
- - "
|
108
|
+
- - ">="
|
53
109
|
- !ruby/object:Gem::Version
|
54
|
-
version: '
|
110
|
+
version: '0'
|
55
111
|
- !ruby/object:Gem::Dependency
|
56
|
-
name:
|
112
|
+
name: rubocop
|
57
113
|
requirement: !ruby/object:Gem::Requirement
|
58
114
|
requirements:
|
59
115
|
- - ">="
|
@@ -76,9 +132,11 @@ executables:
|
|
76
132
|
extensions: []
|
77
133
|
extra_rdoc_files: []
|
78
134
|
files:
|
135
|
+
- ".github/dependabot.yml"
|
136
|
+
- ".github/workflows/rspec_and_release.yml"
|
79
137
|
- ".gitignore"
|
80
|
-
- ".travis.yml"
|
81
138
|
- Gemfile
|
139
|
+
- Gemfile.lock
|
82
140
|
- Guardfile
|
83
141
|
- LICENSE
|
84
142
|
- README.md
|
@@ -86,6 +144,7 @@ files:
|
|
86
144
|
- bin/yq
|
87
145
|
- lib/yq.rb
|
88
146
|
- lib/yq/version.rb
|
147
|
+
- release.config.js
|
89
148
|
- spec/spec_helper.rb
|
90
149
|
- spec/yq_bin_spec.rb
|
91
150
|
- spec/yq_spec.rb
|
@@ -110,8 +169,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
110
169
|
- !ruby/object:Gem::Version
|
111
170
|
version: '0'
|
112
171
|
requirements: []
|
113
|
-
|
114
|
-
rubygems_version: 2.4.3
|
172
|
+
rubygems_version: 3.1.6
|
115
173
|
signing_key:
|
116
174
|
specification_version: 4
|
117
175
|
summary: A JQ wrapper for YAML
|