check_please 0.4.1 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +3 -1
- data/Gemfile.lock +1 -1
- data/README.md +284 -24
- data/Rakefile +46 -3
- data/bin/gh-md-toc +350 -0
- data/lib/check_please.rb +41 -25
- data/lib/check_please/comparison.rb +75 -14
- data/lib/check_please/diffs.rb +4 -0
- data/lib/check_please/error.rb +20 -0
- data/lib/check_please/flag.rb +13 -3
- data/lib/check_please/path.rb +121 -14
- data/lib/check_please/path_segment.rb +88 -0
- data/lib/check_please/reification.rb +50 -0
- data/lib/check_please/version.rb +1 -1
- data/usage_examples.rb +8 -2
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fe333e55fbfdb89d0ea68b3f9ceefde98f3aa4b798792e9dd13745b76757a499
|
4
|
+
data.tar.gz: cf8cfc0205d3b8d7a3d10ec1c0c5487ac140dd7bc41c0c640eb2d72ec3d1e3f7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 918e8b6edec715a8096872c46fa12adc029244b886525c704e9b769fecae6595d38d0b658ebe64a53ebe3474d6ddba76f7d8222baefbef582da4c7dec27e686e
|
7
|
+
data.tar.gz: 4e0da6a791cc4e539ed75f893a3950336bcf5703e6dbb6435e02bac23f94e3207c06dca5cf13551a4a81980474e4e796a911ea333bfec42b5d97aa1e6ef0f3c8
|
data/.gitignore
CHANGED
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -3,7 +3,36 @@
|
|
3
3
|
Check for differences between two JSON documents, YAML documents, or Ruby data
|
4
4
|
structures parsed from either of those.
|
5
5
|
|
6
|
-
|
6
|
+
<!-- start of auto-generated TOC; see https://github.com/ekalinin/github-markdown-toc -->
|
7
|
+
<!--ts-->
|
8
|
+
* [check_please](#check_please)
|
9
|
+
* [Installation](#installation)
|
10
|
+
* [Terminology](#terminology)
|
11
|
+
* [Usage](#usage)
|
12
|
+
* [From the Terminal / Command Line Interface (CLI)](#from-the-terminal--command-line-interface-cli)
|
13
|
+
* [From RSpec](#from-rspec)
|
14
|
+
* [From Ruby](#from-ruby)
|
15
|
+
* [Understanding the Output](#understanding-the-output)
|
16
|
+
* [Diff Types](#diff-types)
|
17
|
+
* [Paths](#paths)
|
18
|
+
* [Output Formats](#output-formats)
|
19
|
+
* [Flags](#flags)
|
20
|
+
* [Setting Flags in the CLI](#setting-flags-in-the-cli)
|
21
|
+
* [Setting Flags in Ruby](#setting-flags-in-ruby)
|
22
|
+
* ["Reentrant" Flags](#reentrant-flags)
|
23
|
+
* [Expanded Documentation for Specific Flags](#expanded-documentation-for-specific-flags)
|
24
|
+
* [Flag: match_by_key](#flag-match_by_key)
|
25
|
+
* [TODO (maybe)](#todo-maybe)
|
26
|
+
* [Development](#development)
|
27
|
+
* [Contributing](#contributing)
|
28
|
+
* [License](#license)
|
29
|
+
* [Code of Conduct](#code-of-conduct)
|
30
|
+
|
31
|
+
|
32
|
+
<!--te-->
|
33
|
+
<!-- end of auto-generated TOC -->
|
34
|
+
|
35
|
+
# Installation
|
7
36
|
|
8
37
|
Add this line to your application's Gemfile:
|
9
38
|
|
@@ -19,7 +48,7 @@ Or install it yourself as:
|
|
19
48
|
|
20
49
|
$ gem install check_please
|
21
50
|
|
22
|
-
|
51
|
+
# Terminology
|
23
52
|
|
24
53
|
I know, you just want to see how to use this thing. Feel free to scroll down,
|
25
54
|
but be aware that CheckPlease uses a few words in a jargony way:
|
@@ -35,9 +64,14 @@ but be aware that CheckPlease uses a few words in a jargony way:
|
|
35
64
|
**reference** and the **candidate**. More on this in "Understanding the Output",
|
36
65
|
below.
|
37
66
|
|
38
|
-
|
67
|
+
Also, even though this gem was born from a need to compare JSON documents, I'll
|
68
|
+
be talking about "hashes" instead of "objects", because I assume this will
|
69
|
+
mostly be used by Ruby developers. Feel free to substitute "object" wherever
|
70
|
+
you see "hash" if that's easier for you. :)
|
39
71
|
|
40
|
-
|
72
|
+
# Usage
|
73
|
+
|
74
|
+
## From the Terminal / Command Line Interface (CLI)
|
41
75
|
|
42
76
|
Use the `bin/check_please` executable. (To get started, run it with the '-h' flag.)
|
43
77
|
|
@@ -48,7 +82,7 @@ of giving it a second filename as the argument. (This is especially useful if
|
|
48
82
|
you're copying an XHR response out of a web browser's dev tools and have a tool
|
49
83
|
like MacOS's `pbpaste` utility.)
|
50
84
|
|
51
|
-
|
85
|
+
## From RSpec
|
52
86
|
|
53
87
|
See [check_please_rspec_matcher](https://github.com/RealGeeks/check_please_rspec_matcher).
|
54
88
|
|
@@ -57,7 +91,7 @@ like to provide custom logic for diffing your own classes, you might be better
|
|
57
91
|
served by the [super_diff](https://github.com/mcmire/super_diff) gem. Check it
|
58
92
|
out!
|
59
93
|
|
60
|
-
|
94
|
+
## From Ruby
|
61
95
|
|
62
96
|
See also: [./usage_examples.rb](usage_examples.rb).
|
63
97
|
|
@@ -69,7 +103,7 @@ Or, if you'd like to inspect the diffs in your own way, use `CheckPlease.diff`
|
|
69
103
|
instead. You'll get back a `CheckPlease::Diffs` custom collection that
|
70
104
|
contains `CheckPlease::Diff` instances.
|
71
105
|
|
72
|
-
|
106
|
+
## Understanding the Output
|
73
107
|
|
74
108
|
CheckPlease follows the Unix philosophy of "no news is good news". If your
|
75
109
|
**candidate** matches your **reference**, you'll get an empty message.
|
@@ -123,7 +157,7 @@ mismatch | /meta/foo | spam | foo
|
|
123
157
|
|
124
158
|
Let's start with the leftmost column...
|
125
159
|
|
126
|
-
|
160
|
+
### Diff Types
|
127
161
|
|
128
162
|
The above example is intended to illustrate every possible type of diff that
|
129
163
|
CheckPlease defines:
|
@@ -136,13 +170,14 @@ CheckPlease defines:
|
|
136
170
|
and it stops when it encounters a type mismatch in order to avoid producing a
|
137
171
|
lot of "garbage" diff output.)_
|
138
172
|
* **mismatch** means that both the **reference** and the **candidate** had a
|
139
|
-
value at the given path, and neither value was an Array or a Hash
|
173
|
+
value at the given path, and neither value was an Array or a Hash, and the
|
174
|
+
two values were not equal.
|
140
175
|
* **extra** means that, inside an Array or a Hash, the **candidate** contained
|
141
|
-
|
176
|
+
elements that were not found in the **reference**.
|
142
177
|
* **missing** is the opposite of **extra**: inside an Array or a Hash, the
|
143
|
-
**reference** contained
|
178
|
+
**reference** contained elements that were not found in the **candidate**.
|
144
179
|
|
145
|
-
|
180
|
+
### Paths
|
146
181
|
|
147
182
|
The second column contains a path expression. This is extremely lo-fi:
|
148
183
|
|
@@ -157,18 +192,242 @@ _**Being primarily a Ruby developer, I'm quite ignorant of conventions in the
|
|
157
192
|
JS community; if there's an existing convention for paths, please open an
|
158
193
|
issue!**_
|
159
194
|
|
160
|
-
|
195
|
+
### Output Formats
|
161
196
|
|
162
197
|
CheckPlease produces tabular output by default. (It leans heavily on the
|
163
198
|
amazing [table_print](http://tableprintgem.com) gem for this.)
|
164
199
|
|
165
200
|
If you want to incorporate CheckPlease into some other toolchain, it can also
|
166
|
-
print diffs as JSON to facilitate parsing.
|
167
|
-
|
201
|
+
print diffs as JSON to facilitate parsing. How you do this depends on whether
|
202
|
+
you're using CheckPlease from the command line or in Ruby, which is a good time
|
203
|
+
to talk about...
|
204
|
+
|
205
|
+
## Flags
|
206
|
+
|
207
|
+
CheckPlease has several flags that control its behavior.
|
208
|
+
|
209
|
+
For quick help on which flags are available, as well as some terse help text,
|
210
|
+
you can run the `check_please` executable with no arguments (or the `-h` or
|
211
|
+
`--help` flags if that makes you feel better).
|
212
|
+
|
213
|
+
While of course we aspire to keep this README up to date, it's probably best to
|
214
|
+
believe things in the following priority order:
|
215
|
+
|
216
|
+
* observed behavior
|
217
|
+
* the code (start from `./lib/check_please.rb` and search for `Flags.define`,
|
218
|
+
then trace through as needed)
|
219
|
+
* the tests (`spec/check_please/flags_spec.rb` describes how the flags work;
|
220
|
+
from there, you'll have to search on the flag's name to see how it shows up
|
221
|
+
in code)
|
222
|
+
* the output of `check_please --help`
|
223
|
+
* this README :)
|
224
|
+
|
225
|
+
All flags have exactly one "Ruby name" and one or more "CLI names". When the
|
226
|
+
CLI runs, it parses the values in `ARGV` (using Ruby's native `OptionParser`)
|
227
|
+
and uses that information to build a `CheckPlease::Flags` instance. After that
|
228
|
+
point, a flag will be referred to within the CheckPlease code exclusively by
|
229
|
+
its "Ruby name".
|
230
|
+
|
231
|
+
For example, the flag that controls the format in which diffs are displayed has
|
232
|
+
a Ruby name of `format`, and CLI names of `-f` and `--format`.
|
233
|
+
|
234
|
+
### Setting Flags in the CLI
|
235
|
+
|
236
|
+
This should behave more or less as an experienced Unix CLI user might expect.
|
237
|
+
|
238
|
+
As such, you can specify, e.g., that you want output in JSON format using
|
239
|
+
either `--format json` or `-f json`.
|
240
|
+
|
241
|
+
(I might expand this section some day. In the meantime, if you are not yet an
|
242
|
+
experienced Unix CLI user, feel free to ask for help! You can either open an
|
243
|
+
issue or look for emails in the `.gemspec` file...)
|
244
|
+
|
245
|
+
### Setting Flags in Ruby
|
246
|
+
|
247
|
+
All external API entry points allow you to specify flags using their Ruby names
|
248
|
+
in the idiomatic "options Hash at the end of the argument list" that should be
|
249
|
+
familiar to most Rubyists. (Again, I assume that, if you're using this tool, I
|
250
|
+
don't need to explain this further, but feel free to ask for help if you need
|
251
|
+
it.)
|
252
|
+
|
253
|
+
(Internally, CheckPlease immediately converts that options hash into a
|
254
|
+
`CheckPlease::Flags` object, but that should be considered an implementation
|
255
|
+
detail unless you're interested in hacking on CheckPlease itself.)
|
256
|
+
|
257
|
+
For example, to get back a String containing the diffs between two data
|
258
|
+
structures in JSON format, you might do:
|
259
|
+
|
260
|
+
```
|
261
|
+
reference = { "foo" => "wibble" }
|
262
|
+
candidate = { "bar" => "wibble" }
|
263
|
+
puts CheckPlease.render_diff(
|
264
|
+
reference,
|
265
|
+
candidate,
|
266
|
+
format: :json # <--- flags
|
267
|
+
)
|
268
|
+
```
|
269
|
+
|
270
|
+
### Repeatable Flags
|
271
|
+
|
272
|
+
Several flags **may** be specified more than once when invoking the CLI. I've
|
273
|
+
tried to make both the CLI and the Ruby API follow their respective
|
274
|
+
environment's conventions.
|
275
|
+
|
276
|
+
For example, if you want to specify a path to ignore using the
|
277
|
+
`--reject-paths` flag, you'd invoke the CLI like this:
|
278
|
+
|
279
|
+
* `[bundle exec] check_please reference.json candidate.json --select-paths /foo`
|
280
|
+
|
281
|
+
And if you want to specify more than one path, that would look like:
|
282
|
+
|
283
|
+
* `[bundle exec] check_please reference.json candidate.json --select-paths /foo --select-paths /bar`
|
284
|
+
|
285
|
+
In Ruby, you can specify this in the options hash as a single key with an Array
|
286
|
+
value:
|
287
|
+
|
288
|
+
* `CheckPlease.render_diff(reference, candidate, select_paths: [ "/foo", "/bar" ])`
|
289
|
+
|
290
|
+
_(NOTE TO MAINTAINERS: internally, the way `CheckPlease::CLI::Parser` uses
|
291
|
+
Ruby's `OptionParser` leads to some less than obvious behavior. Search
|
292
|
+
[./spec/check_please/flags_spec.rb](spec/check_please/flags_spec.rb) for the
|
293
|
+
word "surprising" for details.)_
|
294
|
+
|
295
|
+
### Expanded Documentation for Specific Flags
|
296
|
+
|
297
|
+
#### Flag: `match_by_key`
|
298
|
+
|
299
|
+
> **I know this looks like a LOT of information, but it's really not that
|
300
|
+
> bad!** This feature just requires specific examples to describe, and talking
|
301
|
+
> about it in English (rather than code) is hard. Take a moment for some deep
|
302
|
+
> breaths if you need it. :)
|
303
|
+
|
304
|
+
> _If you're comfortable reading RSpec and/or want to check out all the edge
|
305
|
+
> cases, go look in `./spec/check_please/comparison_spec.rb` and check out the
|
306
|
+
> `describe` block labeled `"comparing arrays by keys"`._
|
307
|
+
|
308
|
+
The `match_by_key` flag allows you to match up arrays of hashes using the value
|
309
|
+
of a single key that is treated as the identifier for each hash.
|
310
|
+
|
311
|
+
There's a lot going on in that sentence, so let's unpack it a bit.
|
312
|
+
|
313
|
+
Imagine you're comparing two documents that contain the same data, but in
|
314
|
+
different orders. To use a contrived example, let's say that both documents
|
315
|
+
consist of a single array of two simple hashes, but the reference array and the
|
316
|
+
candidate array are reversed:
|
317
|
+
|
318
|
+
```ruby
|
319
|
+
# REFERENCE
|
320
|
+
[ { "id" => 1, "foo" => "bar" }, { "id" => 2, "foo" => "spam" } ]
|
321
|
+
|
322
|
+
# CANDIDATE
|
323
|
+
[ { "id" => 2, "foo" => "spam" }, { "id" => 1, "foo" => "bar" } ]
|
324
|
+
```
|
325
|
+
|
326
|
+
By default, CheckPlease will match up array elements by their position in the
|
327
|
+
array, resulting in a diff report like this:
|
328
|
+
|
329
|
+
```
|
330
|
+
TYPE | PATH | REFERENCE | CANDIDATE
|
331
|
+
---------|--------|-----------|----------
|
332
|
+
mismatch | /1/id | 1 | 2
|
333
|
+
mismatch | /1/foo | "bar" | "bat"
|
334
|
+
mismatch | /2/id | 2 | 1
|
335
|
+
mismatch | /2/foo | "bat" | "bar"
|
336
|
+
```
|
337
|
+
|
338
|
+
To solve this problem, CheckPlease adds a **key expression** to its (very
|
339
|
+
simple) path syntax that lets you specify a **key** to use to match up elements
|
340
|
+
in both lists, rather than simply comparing elements by position.
|
341
|
+
|
342
|
+
Continuing with the above example, if we give `match_by_key` a value of
|
343
|
+
`["/:id"]`, it will use the "id" value in both hashes (remember, A's `id` is
|
344
|
+
`1` and B's `id` is `2`) to identify every element in both the reference array
|
345
|
+
and the candidate array, and correctly match A and B, giving you an empty list
|
346
|
+
of diffs.
|
347
|
+
|
348
|
+
Please note that the CLI and Ruby implementations of these are a bit different
|
349
|
+
(see "Setting Flags in the CLI" versus "Setting Flags in Ruby"), so if you're
|
350
|
+
doing this from the command line, it'll look like: `--match-by-key /:id`
|
351
|
+
|
352
|
+
Here, have another example. If you want to specify a match_by_key expression
|
353
|
+
below the root of the document, you can put the **key expression** further down
|
354
|
+
the path: `/books/:isbn`
|
355
|
+
|
356
|
+
This would correctly match up the following documents:
|
357
|
+
|
358
|
+
```ruby
|
359
|
+
# REFERENCE
|
360
|
+
{
|
361
|
+
"books" => [
|
362
|
+
{ "isbn" => "12345", "title" => "Who Am I, Really?" },
|
363
|
+
{ "isbn" => "67890", "title" => "Who Are Any Of Us, Really?" },
|
364
|
+
]
|
365
|
+
}
|
366
|
+
|
367
|
+
# CANDIDATE
|
368
|
+
{
|
369
|
+
"books" => [
|
370
|
+
{ "isbn" => "67890", "title" => "Who Are Any Of Us, Really?" },
|
371
|
+
{ "isbn" => "12345", "title" => "Who Am I, Really?" },
|
372
|
+
]
|
373
|
+
}
|
374
|
+
```
|
375
|
+
|
376
|
+
Finally, if you have deeply nested data with arrays of hashes at multiple
|
377
|
+
levels, you can specify more than one **key expression** in a single path,
|
378
|
+
like: `/authors/:id/books/:isbn`
|
379
|
+
|
380
|
+
This would correctly match up the following documents:
|
381
|
+
|
382
|
+
```ruby
|
383
|
+
# REFERENCE
|
384
|
+
{
|
385
|
+
"authors" => [
|
386
|
+
{
|
387
|
+
"id" => 1,
|
388
|
+
"name" => "Anne Onymous",
|
389
|
+
"books" => [
|
390
|
+
{ "isbn" => "12345", "title" => "Who Am I, Really?" },
|
391
|
+
{ "isbn" => "67890", "title" => "Who Are Any Of Us, Really?" },
|
392
|
+
]
|
393
|
+
},
|
394
|
+
]
|
395
|
+
}
|
396
|
+
|
397
|
+
# CANDIDATE
|
398
|
+
{
|
399
|
+
"authors" => [
|
400
|
+
{
|
401
|
+
"id" => 1,
|
402
|
+
"name" => "Anne Onymous",
|
403
|
+
"books" => [
|
404
|
+
{ "isbn" => "67890", "title" => "Who Are Any Of Us, Really?" },
|
405
|
+
{ "isbn" => "12345", "title" => "Who Am I, Really?" },
|
406
|
+
]
|
407
|
+
},
|
408
|
+
]
|
409
|
+
}
|
410
|
+
```
|
411
|
+
|
412
|
+
Finally, if there are any diffs to report, CheckPlease uses a **key/value
|
413
|
+
expression** to report mismatches.
|
414
|
+
|
415
|
+
Using the last example above (the one with `/authors/:id/books/:isbn`), if the
|
416
|
+
reference had Anne Onymous' book title as "Who Am I, Really?" and the candidate
|
417
|
+
listed it as "Who The Heck Am I?", CheckPlease would show the mismatch using
|
418
|
+
the following path expression: `/authors/id=1/books/isbn=12345`
|
168
419
|
|
169
|
-
|
420
|
+
**This syntax is intended to be readable by humans first.** If you need to
|
421
|
+
build tooling that consumes it... well, I'm open to suggestions. :)
|
170
422
|
|
423
|
+
-----
|
424
|
+
|
425
|
+
# TODO (maybe)
|
426
|
+
|
427
|
+
* document flags for rspec matcher
|
171
428
|
* command line flags for :allthethings:!
|
429
|
+
* change display width for table format
|
430
|
+
(for example, "2020-07-16T19:42:41.312978" gets cut off)
|
172
431
|
* sort by path?
|
173
432
|
* detect timestamps and compare after parsing?
|
174
433
|
* ignore sub-second precision (option / CLI flag)?
|
@@ -189,7 +448,9 @@ print diffs as JSON to facilitate parsing. In Ruby, pass `format: :json` to
|
|
189
448
|
* but this may not actually be worth the time and complexity to implement, so
|
190
449
|
think about this first...
|
191
450
|
|
192
|
-
|
451
|
+
-----
|
452
|
+
|
453
|
+
# Development
|
193
454
|
|
194
455
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run
|
195
456
|
`rake spec` to run the tests. You can also run `bin/console` for an interactive
|
@@ -201,22 +462,21 @@ release a new version, update the version number in `version.rb`, and then run
|
|
201
462
|
git commits and tags, and push the `.gem` file to
|
202
463
|
[rubygems.org](https://rubygems.org).
|
203
464
|
|
204
|
-
|
465
|
+
# Contributing
|
205
466
|
|
206
467
|
Bug reports and pull requests are welcome on GitHub at
|
207
|
-
https://github.com/
|
468
|
+
https://github.com/RealGeeks/check_please. This project is intended to be a
|
208
469
|
safe, welcoming space for collaboration, and contributors are expected to
|
209
470
|
adhere to the [code of
|
210
|
-
conduct](https://github.com/
|
211
|
-
|
471
|
+
conduct](https://github.com/RealGeeks/check_please/blob/master/CODE_OF_CONDUCT.md).
|
212
472
|
|
213
|
-
|
473
|
+
# License
|
214
474
|
|
215
475
|
The gem is available as open source under the terms of the [MIT
|
216
476
|
License](https://opensource.org/licenses/MIT).
|
217
477
|
|
218
|
-
|
478
|
+
# Code of Conduct
|
219
479
|
|
220
480
|
Everyone interacting in the CheckPlease project's codebases, issue trackers,
|
221
481
|
chat rooms and mailing lists is expected to follow the [code of
|
222
|
-
conduct](https://github.com/
|
482
|
+
conduct](https://github.com/RealGeeks/check_please/blob/master/CODE_OF_CONDUCT.md).
|
data/Rakefile
CHANGED
@@ -1,21 +1,64 @@
|
|
1
1
|
require "bundler/gem_tasks"
|
2
2
|
require "rspec/core/rake_task"
|
3
|
+
require "pathname"
|
4
|
+
require "tempfile"
|
3
5
|
|
4
|
-
namespace :spec do
|
5
|
-
RSpec::Core::RakeTask.new(:all)
|
6
6
|
|
7
|
+
PROJECT_ROOT = Pathname.new(File.dirname(__FILE__))
|
8
|
+
|
9
|
+
|
10
|
+
namespace :spec do
|
11
|
+
desc "All tests *except* those that exercise the executable CLI"
|
7
12
|
RSpec::Core::RakeTask.new(:not_cli) do |t|
|
8
13
|
t.rspec_opts = "--tag ~cli"
|
9
14
|
end
|
15
|
+
|
16
|
+
desc "fast tests only"
|
10
17
|
task fast: :not_cli
|
11
18
|
|
12
19
|
# These are much slower than the rest, since they use Kernel#`
|
20
|
+
desc "Only tests that exercise the executable CLI (slower)"
|
13
21
|
RSpec::Core::RakeTask.new(:cli) do |t|
|
14
22
|
t.rspec_opts = "--tag cli"
|
15
23
|
end
|
24
|
+
|
25
|
+
desc "approve changes to the CLI's `--help` output"
|
26
|
+
task :approve_cli_help_output do
|
27
|
+
output = `exe/check_please`
|
28
|
+
File.open(PROJECT_ROOT.join("spec/fixtures/cli-help-output"), "w") do |f|
|
29
|
+
f << output
|
30
|
+
end
|
31
|
+
end
|
16
32
|
end
|
17
33
|
|
18
34
|
# By default, `rake spec` should run fast specs first, then cli if those all pass
|
19
|
-
|
35
|
+
desc "Run all tests (fast tests first, then the slower CLI ones)"
|
36
|
+
task :spec => [ "spec:fast", "spec:cli" ]
|
20
37
|
|
21
38
|
task :default => :spec
|
39
|
+
|
40
|
+
|
41
|
+
|
42
|
+
|
43
|
+
desc "Generate TOC for the README"
|
44
|
+
task :toc do
|
45
|
+
# the `--no-backup` flag skips the creation of README.md.* backup files,
|
46
|
+
# WHICH IS FINE because we're using Git
|
47
|
+
puts "generating TOC..."
|
48
|
+
`bin/gh-md-toc --no-backup README.md`
|
49
|
+
|
50
|
+
# Now, strip out the 'Added by:` line so we can detect if there were actual changes
|
51
|
+
# Use a tempfile just in case sed barfs, I guess?
|
52
|
+
tmp = Tempfile.new('check-please-readme')
|
53
|
+
begin
|
54
|
+
`sed '/Added by: /d' README.md > #{tmp.path}`
|
55
|
+
FileUtils.mv tmp.path, PROJECT_ROOT.join("README.md")
|
56
|
+
ensure
|
57
|
+
tmp.close
|
58
|
+
tmp.unlink
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
# By making TOC generation a prerequisite of release, we *should* at least be
|
63
|
+
# forced to update the TOC whenever we publish a new version of the gem...
|
64
|
+
task :release => :toc
|