check_please 0.1.0 → 0.2.0
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 +4 -4
- data/Gemfile.lock +1 -1
- data/README.md +129 -3
- data/bin/check_please +1 -67
- data/lib/check_please.rb +5 -3
- data/lib/check_please/cli.rb +29 -0
- data/lib/check_please/cli/flag.rb +39 -0
- data/lib/check_please/cli/parser.rb +58 -0
- data/lib/check_please/cli/runner.rb +79 -0
- data/lib/check_please/error.rb +9 -0
- data/lib/check_please/printers.rb +2 -2
- data/lib/check_please/version.rb +3 -1
- metadata +7 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1c16110449be99d5ff509c720c4365b2fe6f176f23094784628db2de0e5f3bf9
|
4
|
+
data.tar.gz: b45c9d1b7dea9b4405f4ca80dbce5f04d0aec14ad50e4e919802e09b469c86c8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 023b9fdd6f227f8381dfba06a82d30961adab9b2ab5a2b5a0d820c8b8697d300f59d416c801808e88e7e625720776f1cec4cf0a6f57d1eec07e6cb656881d4b8
|
7
|
+
data.tar.gz: eca955971798d00dd45bf5e068779aebeb33b304fe592d84534081d0068eaa981f6b765fd5c4ea9a30e7d65b2edd456ed9093c039964e3691c646e0c7d23b2b0
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
#
|
1
|
+
# check_please
|
2
2
|
|
3
3
|
Check for differences between two JSON strings (or Ruby data structures parsed from them).
|
4
4
|
|
@@ -20,24 +20,150 @@ Or install it yourself as:
|
|
20
20
|
|
21
21
|
## Usage
|
22
22
|
|
23
|
+
### Terminology
|
24
|
+
|
25
|
+
CheckPlease uses a few words in a jargony way:
|
26
|
+
|
27
|
+
* **Reference** is always used to refer to the "target" or "source of truth."
|
28
|
+
We assume you're comparing two things because you want one of them to be like
|
29
|
+
the other; the **reference** is what you're aiming for.
|
30
|
+
* **Candidate** is always used to refer to some JSON you'd like to compare
|
31
|
+
against the **reference**. _(We could've also used "sample," but it turns
|
32
|
+
out that "reference" and "candidate" are the same length, which makes code
|
33
|
+
line up neatly in a monospaced font...)_
|
34
|
+
* A **diff** is what CheckPlease calls an individual discrepancy between the
|
35
|
+
**reference** and the **candidate**. More on this in "Understanding the Output",
|
36
|
+
below.
|
37
|
+
|
23
38
|
### CLI
|
24
39
|
|
25
40
|
Use the `bin/check_please` executable. (To get started, run it with the '-h' flag.)
|
26
41
|
|
42
|
+
Note that the executable assumes you've saved your **reference** to a file.
|
43
|
+
Once that's done, you can either save the **candidate** to a file as well if
|
44
|
+
that fits your workflow, **or** you can pipe it to `bin/check_please` in lieu
|
45
|
+
of giving it a second filename as the argument. (This is especially useful if
|
46
|
+
you're copying an XHR response out of a web browser's dev tools and have a tool
|
47
|
+
like MacOS's `pbpaste` utility.)
|
48
|
+
|
49
|
+
### RSpec Matcher
|
50
|
+
|
51
|
+
See [check_please_rspec_matcher](https://github.com/RealGeeks/check_please_rspec_matcher).
|
52
|
+
|
27
53
|
### From Within Ruby
|
28
54
|
|
29
55
|
Create two JSON strings and pass them to `CheckPlease.render_diff`. You'll get
|
30
56
|
back a third string containing a nicely formatted report of all the differences
|
31
|
-
CheckPlease found in the two JSON strings. (See also: ./usage_examples.rb.)
|
57
|
+
CheckPlease found in the two JSON strings. (See also: [./usage_examples.rb](usage_examples.rb).)
|
32
58
|
|
33
59
|
(You can also parse the JSON strings yourself and pass the resulting data
|
34
60
|
structures in, if you're into that. I mean, I wrote this to help compare JSON
|
35
61
|
data that's too big and complicated to scan through visually, but you do you!
|
36
62
|
|
63
|
+
### Understanding the Output
|
64
|
+
|
65
|
+
CheckPlease follows the Unix philosophy of "no news is good news". If your
|
66
|
+
**candidate** matches your **reference**, you'll get an empty message.
|
67
|
+
|
68
|
+
But let's be honest: how often is that going to happen? No, you're using this
|
69
|
+
tool because you want a human-friendly summary of all the places that your
|
70
|
+
**candidate** fell short.
|
71
|
+
|
72
|
+
When CheckPlease compares your two samples, it generates a list of diffs to
|
73
|
+
describe any discrepancies it encounters. (By default, it prints that list in a
|
74
|
+
tabular format, but if you want to incorporate this into another toolchain,
|
75
|
+
CheckPlease can also print these diffs as JSON to facilitate parsing.)
|
76
|
+
|
77
|
+
An example would probably help here.
|
78
|
+
|
79
|
+
_(NOTE: these examples may fall out of date with the code. They're swiped
|
80
|
+
from [the CLI integration spec](spec/cli_integration_spec.rb), so please
|
81
|
+
consider that more authoritative than this README. If you do spot a
|
82
|
+
difference, please feel free to open an issue!)_
|
83
|
+
|
84
|
+
Given the following **reference** JSON:
|
85
|
+
```
|
86
|
+
{
|
87
|
+
"id": 42,
|
88
|
+
"name": "The Answer",
|
89
|
+
"words": [ "what", "do", "you", "get", "when", "you", "multiply", "six", "by", "nine" ],
|
90
|
+
"meta": { "foo": "spam", "bar": "eggs", "yak": "bacon" }
|
91
|
+
}
|
92
|
+
```
|
93
|
+
|
94
|
+
And the following **candidate** JSON:
|
95
|
+
```
|
96
|
+
{
|
97
|
+
"id": 42,
|
98
|
+
"name": [ "I am large, and contain multitudes." ],
|
99
|
+
"words": [ "what", "do", "we", "get", "when", "I", "multiply", "six", "by", "nine", "dude" ],
|
100
|
+
"meta": { "foo": "foo", "yak": "bacon" }
|
101
|
+
}
|
102
|
+
```
|
103
|
+
|
104
|
+
CheckPlease should produce the following output:
|
105
|
+
|
106
|
+
```
|
107
|
+
TYPE | PATH | REFERENCE | CANDIDATE
|
108
|
+
--------------|-----------|------------|-------------------------------
|
109
|
+
type_mismatch | /name | The Answer | ["I am large, and contain m...
|
110
|
+
mismatch | /words/3 | you | we
|
111
|
+
mismatch | /words/6 | you | I
|
112
|
+
extra | /words/11 | | dude
|
113
|
+
missing | /meta/bar | eggs |
|
114
|
+
mismatch | /meta/foo | spam | foo
|
115
|
+
```
|
116
|
+
|
117
|
+
Let's start with the leftmost column...
|
118
|
+
|
119
|
+
#### Diff Types
|
120
|
+
|
121
|
+
The above example is intended to illustrate every possible type of diff that
|
122
|
+
CheckPlease defines:
|
123
|
+
|
124
|
+
* **type_mismatch** means that both the **reference** and the **candidate** had
|
125
|
+
a value at the given path, but one value was an Array or a Hash and the other
|
126
|
+
was not. **When CheckPlease encounters a type mismatch, it does not compare
|
127
|
+
anything "below" the given path.** producing a lot of "garbage" diffs.
|
128
|
+
_(Technical note: CheckPlease uses a "recursive descent" strategy to
|
129
|
+
traverse the **reference** data structure, and it stops when it encounters a
|
130
|
+
type mismatch in order to avoid producing a lot of "garbage" diff output.
|
131
|
+
Also, the way these get displayed is likely to change.)_
|
132
|
+
* **mismatch** means that both the **reference** and the **candidate** had a
|
133
|
+
value at the given path, and neither value was an Array or a Hash.
|
134
|
+
* "**extra**" means that, inside an Array or a Hash, the **candidate**
|
135
|
+
contained values that were not found in the **reference**.
|
136
|
+
* "**missing**" is the opposite of **extra**: inside an Array or a Hash, the
|
137
|
+
**reference** contained values that were not found in the **candidate**.
|
138
|
+
|
139
|
+
#### Paths
|
140
|
+
|
141
|
+
The second column contains a path expression. This is extremely basic:
|
142
|
+
|
143
|
+
* The first element in the data structure is defined as "/".
|
144
|
+
* If an element in the data structure is an array, its child elements will have
|
145
|
+
a **one-based** index appended to their parent's path.
|
146
|
+
* If an element in the data structure is an object ("Hash" in Ruby), the key
|
147
|
+
for each element will be appended to their parent's path, and the values will
|
148
|
+
be compared.
|
149
|
+
|
150
|
+
_**Being primarily a Ruby developer, I'm quite ignorant of conventions in the
|
151
|
+
JS community; if there's an existing convention for paths, please open an
|
152
|
+
issue!**_
|
153
|
+
|
154
|
+
#### Output Formats
|
155
|
+
|
156
|
+
CheckPlease produces tabular output by default. (It leans heavily on the
|
157
|
+
amazing [table_print](http://tableprintgem.com) gem for this.)
|
158
|
+
|
159
|
+
If you want to incorporate CheckPlease into some other toolchain, it can also
|
160
|
+
print diffs as JSON to facilitate parsing. In Ruby, pass `format: :json` to
|
161
|
+
`CheckPlease.render_diff`; in the CLI, use the `-f`/`--format` switch.
|
162
|
+
|
37
163
|
## TODO
|
38
164
|
|
39
|
-
* rspec custom matcher (separate gem?)
|
40
165
|
* command line flags for :allthethings:!
|
166
|
+
* --fail-fast
|
41
167
|
* limit to first N
|
42
168
|
* sort by path?
|
43
169
|
* max depth (for iterative refinement?)
|
data/bin/check_please
CHANGED
@@ -1,70 +1,4 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
|
-
require 'optparse'
|
4
|
-
|
5
3
|
require_relative '../lib/check_please'
|
6
|
-
|
7
|
-
argv = ARGV.dup
|
8
|
-
|
9
|
-
ref_file = argv.shift
|
10
|
-
can_file = argv.shift
|
11
|
-
diff_opts = {}
|
12
|
-
|
13
|
-
@parser = OptionParser.new do |opts|
|
14
|
-
opts.banner = <<~EOF
|
15
|
-
Usage: #{__FILE__} <reference> <candidate> <options>
|
16
|
-
|
17
|
-
Tool for parsing and diffing two JSON files.
|
18
|
-
|
19
|
-
Arguments:
|
20
|
-
<reference> is the name of a file to use as the reference.
|
21
|
-
<candidate> is the name of a file to compare against the reference.
|
22
|
-
|
23
|
-
NOTE: If the <candidate> arg is omitted, stdin will be used instead.
|
24
|
-
This allows you to copy candidate JSON to the clipboard and (on a Mac) do:
|
25
|
-
|
26
|
-
$ pbpaste | #{__FILE__} <reference>
|
27
|
-
|
28
|
-
<options>:
|
29
|
-
EOF
|
30
|
-
|
31
|
-
formats = CheckPlease::Printers::FORMATS.join(", ")
|
32
|
-
|
33
|
-
opts.on("-f FORMAT", "--format FORMAT", "specify the format (available options: [#{formats}]") do |val|
|
34
|
-
diff_opts[:format] = val
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
def print_help_and_exit
|
41
|
-
@parser.parse(%w[--help])
|
42
|
-
exit # technically redundant but helps me feel better
|
43
|
-
end
|
44
|
-
|
45
|
-
def read_file(filename)
|
46
|
-
return nil if filename.to_s =~ /^\s*$/
|
47
|
-
File.read(filename)
|
48
|
-
rescue Errno::ENOENT
|
49
|
-
# no such file, buddy
|
50
|
-
return nil
|
51
|
-
end
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
# First off, try to read in the files the user told us about...
|
56
|
-
reference = read_file(ref_file)
|
57
|
-
candidate = read_file(can_file) || $stdin.read
|
58
|
-
|
59
|
-
print_help_and_exit if reference.to_s =~ /^\s*$/
|
60
|
-
print_help_and_exit if candidate.to_s =~ /^\s*$/
|
61
|
-
|
62
|
-
begin
|
63
|
-
@parser.parse(argv)
|
64
|
-
rescue OptionParser::InvalidOption, OptionParser::AmbiguousOption => e
|
65
|
-
puts "\n>>> #{e.message}\n\n"
|
66
|
-
print_help_and_exit
|
67
|
-
end
|
68
|
-
|
69
|
-
report = CheckPlease.render_diff(reference, candidate, **diff_opts)
|
70
|
-
puts report
|
4
|
+
CheckPlease::CLI.run(__FILE__)
|
data/lib/check_please.rb
CHANGED
@@ -1,12 +1,14 @@
|
|
1
1
|
require_relative "check_please/version"
|
2
|
+
require_relative "check_please/error"
|
2
3
|
require_relative "check_please/path"
|
3
4
|
require_relative "check_please/comparison"
|
4
5
|
require_relative "check_please/diff"
|
5
6
|
require_relative "check_please/diffs"
|
6
7
|
require_relative "check_please/printers"
|
8
|
+
require_relative "check_please/cli"
|
7
9
|
|
8
10
|
module CheckPlease
|
9
|
-
|
11
|
+
ELEVATOR_PITCH = "Tool for parsing and diffing two JSON documents."
|
10
12
|
|
11
13
|
def self.diff(reference, candidate)
|
12
14
|
reference = maybe_parse(reference)
|
@@ -14,9 +16,9 @@ module CheckPlease
|
|
14
16
|
Comparison.perform(reference, candidate)
|
15
17
|
end
|
16
18
|
|
17
|
-
def self.render_diff(reference, candidate,
|
19
|
+
def self.render_diff(reference, candidate, options = {})
|
18
20
|
diffs = diff(reference, candidate)
|
19
|
-
Printers.render(diffs,
|
21
|
+
Printers.render(diffs, options)
|
20
22
|
end
|
21
23
|
|
22
24
|
class << self
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require_relative 'cli/flag'
|
2
|
+
# require_relative 'cli/flags'
|
3
|
+
require_relative 'cli/parser'
|
4
|
+
require_relative 'cli/runner'
|
5
|
+
|
6
|
+
module CheckPlease
|
7
|
+
|
8
|
+
module CLI
|
9
|
+
def self.run(exe_file_name)
|
10
|
+
Runner.new(__FILE__).run(*ARGV.dup)
|
11
|
+
end
|
12
|
+
|
13
|
+
|
14
|
+
|
15
|
+
FLAGS = []
|
16
|
+
def self.flag(*args, &block)
|
17
|
+
flag = Flag.new(*args, &block)
|
18
|
+
FLAGS << flag
|
19
|
+
end
|
20
|
+
|
21
|
+
##### Define CLI flags here #####
|
22
|
+
|
23
|
+
flag "-f FORMAT", "--format FORMAT" do |f|
|
24
|
+
f.desc = "format in which to present diffs (available options: [#{CheckPlease::Printers::FORMATS.join(", ")}])"
|
25
|
+
f.set_key :format, :to_sym
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module CheckPlease
|
2
|
+
module CLI
|
3
|
+
|
4
|
+
class Flag
|
5
|
+
ATTR_NAMES = %i[ short long desc key block ]
|
6
|
+
attr_accessor(*ATTR_NAMES)
|
7
|
+
|
8
|
+
def initialize(*args)
|
9
|
+
self.short = args.shift if args.any?
|
10
|
+
self.long = args.shift if args.any?
|
11
|
+
|
12
|
+
yield self if block_given?
|
13
|
+
|
14
|
+
missing = ATTR_NAMES.select { |e| self.send(e).nil? }
|
15
|
+
if missing.any?
|
16
|
+
raise ArgumentError, "Missing attributes: #{missing.join(', ')}"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def visit_option_parser(parser, options)
|
21
|
+
parser.on(short, long, desc) do |value|
|
22
|
+
block.call options, value
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def set_key(key, message = nil, &b)
|
27
|
+
raise ArgumentError if message && b
|
28
|
+
raise ArgumentError if !message && !b
|
29
|
+
|
30
|
+
self.key = key
|
31
|
+
self.block = ->(options, value) {
|
32
|
+
b ||= message.to_sym.to_proc
|
33
|
+
options[key] = b.call(value)
|
34
|
+
}
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require 'optparse'
|
2
|
+
|
3
|
+
module CheckPlease
|
4
|
+
module CLI
|
5
|
+
|
6
|
+
class Parser
|
7
|
+
class UnrecognizedOption < StandardError
|
8
|
+
include CheckPlease::Error
|
9
|
+
end
|
10
|
+
|
11
|
+
def initialize(exe_file_name)
|
12
|
+
@exe_file_name = exe_file_name
|
13
|
+
@optparse = OptionParser.new
|
14
|
+
@optparse.banner = banner
|
15
|
+
|
16
|
+
@options = {} # yuck
|
17
|
+
CheckPlease::CLI::FLAGS.each do |flag|
|
18
|
+
flag.visit_option_parser(@optparse, @options)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
# Unfortunately, OptionParser *really* wants to use closures.
|
23
|
+
# I haven't yet figured out how to get around this...
|
24
|
+
def consume_flags!(args)
|
25
|
+
@optparse.parse!(args) # removes recognized flags from `args`
|
26
|
+
return @options
|
27
|
+
rescue OptionParser::InvalidOption, OptionParser::AmbiguousOption => e
|
28
|
+
raise UnrecognizedOption, e.message, cause: e
|
29
|
+
end
|
30
|
+
|
31
|
+
def help
|
32
|
+
@optparse.help
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
def banner
|
38
|
+
<<~EOF
|
39
|
+
Usage: #{@exe_file_name} <reference> <candidate> [FLAGS]
|
40
|
+
|
41
|
+
#{CheckPlease::ELEVATOR_PITCH}
|
42
|
+
|
43
|
+
Arguments:
|
44
|
+
<reference> is the name of a file to use as, well, the reference.
|
45
|
+
<candidate> is the name of a file to compare against the reference.
|
46
|
+
|
47
|
+
NOTE: If you have a utility like MacOS's `pbpaste`, you MAY omit
|
48
|
+
the <candidate> arg, and pipe the second document instead, like:
|
49
|
+
|
50
|
+
$ pbpaste | #{@exe_file_name} <reference>
|
51
|
+
|
52
|
+
FLAGS:
|
53
|
+
EOF
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
module CheckPlease
|
2
|
+
module CLI
|
3
|
+
|
4
|
+
class Runner
|
5
|
+
def initialize(exe_file_name)
|
6
|
+
@parser = Parser.new(exe_file_name)
|
7
|
+
end
|
8
|
+
|
9
|
+
# NOTE: unusually for me, I'm using Ruby's `or` keyword in this method.
|
10
|
+
# `or` short circuits just like `||`, but has lower precedence, which
|
11
|
+
# enables some shenanigans...
|
12
|
+
def run(*args)
|
13
|
+
args.flatten!
|
14
|
+
print_help_and_exit if args.empty?
|
15
|
+
|
16
|
+
begin
|
17
|
+
options = @parser.consume_flags!(args)
|
18
|
+
rescue Parser::UnrecognizedOption => e
|
19
|
+
print_help_and_exit e.message
|
20
|
+
end
|
21
|
+
|
22
|
+
# The reference MUST be the first arg...
|
23
|
+
reference = \
|
24
|
+
read_file(args.shift) \
|
25
|
+
or print_help_and_exit "Missing <reference> argument"
|
26
|
+
|
27
|
+
# The candidate MAY be the second arg, or it might have been piped in...
|
28
|
+
candidate = \
|
29
|
+
read_file(args.shift) \
|
30
|
+
|| read_piped_stdin \
|
31
|
+
or print_help_and_exit "Missing <candidate> argument, AND nothing was piped in"
|
32
|
+
|
33
|
+
# Looks like we're good to go!
|
34
|
+
diff_view = CheckPlease.render_diff(reference, candidate, options)
|
35
|
+
puts diff_view
|
36
|
+
end
|
37
|
+
|
38
|
+
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
def print_help_and_exit(message = nil)
|
43
|
+
puts "\n>>> #{message}\n\n" if message
|
44
|
+
puts @parser.help
|
45
|
+
exit
|
46
|
+
end
|
47
|
+
|
48
|
+
def read_file(filename)
|
49
|
+
return nil if filename.nil?
|
50
|
+
File.read(filename)
|
51
|
+
rescue Errno::ENOENT
|
52
|
+
return nil
|
53
|
+
end
|
54
|
+
|
55
|
+
# Unfortunately, ARGF won't help us here because it doesn't seem to want to
|
56
|
+
# read from stdin after it's already pulled a file out of ARGV. So, we
|
57
|
+
# have to read from stdin ourselves.
|
58
|
+
#
|
59
|
+
# BUT THAT'S NOT ALL! If the user didn't actually pipe any data,
|
60
|
+
# $stdin.read will block until they manually send EOF or hit Ctrl+C.
|
61
|
+
#
|
62
|
+
# Fortunately, we can detect whether $stdin.read will block by checking to
|
63
|
+
# see if it is a TTY. (Wait, what century is this again?)
|
64
|
+
#
|
65
|
+
# For fun and posterity, here's an experiment you can use to demonstrate this:
|
66
|
+
#
|
67
|
+
# $ ruby -e 'puts $stdin.tty? ? "YES YOU ARE A TTY" : "nope, no tty here"'
|
68
|
+
# YES YOU ARE A TTY
|
69
|
+
#
|
70
|
+
# $ cat foo | ruby -e 'puts $stdin.tty? ? "YES YOU ARE A TTY" : "nope, no tty here"'
|
71
|
+
# nope, no tty here
|
72
|
+
def read_piped_stdin
|
73
|
+
return nil if $stdin.tty?
|
74
|
+
return $stdin.read
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
79
|
+
end
|
@@ -12,8 +12,8 @@ module CheckPlease
|
|
12
12
|
FORMATS = PRINTERS_BY_FORMAT.keys.sort
|
13
13
|
DEFAULT_FORMAT = :table
|
14
14
|
|
15
|
-
def self.render(diffs,
|
16
|
-
format
|
15
|
+
def self.render(diffs, options = {})
|
16
|
+
format = options[:format] || DEFAULT_FORMAT
|
17
17
|
printer = PRINTERS_BY_FORMAT[format.to_sym]
|
18
18
|
printer.render(diffs)
|
19
19
|
end
|
data/lib/check_please/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: check_please
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sam Livingston-Gray
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-11-
|
11
|
+
date: 2020-11-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: table_print
|
@@ -74,9 +74,14 @@ files:
|
|
74
74
|
- bin/setup
|
75
75
|
- check_please.gemspec
|
76
76
|
- lib/check_please.rb
|
77
|
+
- lib/check_please/cli.rb
|
78
|
+
- lib/check_please/cli/flag.rb
|
79
|
+
- lib/check_please/cli/parser.rb
|
80
|
+
- lib/check_please/cli/runner.rb
|
77
81
|
- lib/check_please/comparison.rb
|
78
82
|
- lib/check_please/diff.rb
|
79
83
|
- lib/check_please/diffs.rb
|
84
|
+
- lib/check_please/error.rb
|
80
85
|
- lib/check_please/path.rb
|
81
86
|
- lib/check_please/printers.rb
|
82
87
|
- lib/check_please/printers/base.rb
|