watchcat 0.3.0 → 0.6.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/CHANGELOG.md +28 -0
- data/Cargo.lock +33 -109
- data/Cargo.toml +1 -1
- data/Gemfile +1 -1
- data/README.md +188 -2
- data/cli_example.yml +14 -0
- data/exe/watchcat +14 -0
- data/ext/watchcat/Cargo.toml +3 -4
- data/ext/watchcat/src/gvl_helpers.rs +1 -1
- data/ext/watchcat/src/lib.rs +170 -109
- data/lib/watchcat/cli/action_executor.rb +44 -0
- data/lib/watchcat/cli/config.rb +76 -0
- data/lib/watchcat/cli/watcher.rb +83 -0
- data/lib/watchcat/cli.rb +52 -0
- data/lib/watchcat/debouncer.rb +41 -0
- data/lib/watchcat/event.rb +37 -0
- data/lib/watchcat/event_handler.rb +29 -0
- data/lib/watchcat/executor.rb +64 -13
- data/lib/watchcat/kind.rb +8 -0
- data/lib/watchcat/version.rb +1 -1
- data/lib/watchcat.rb +15 -5
- metadata +46 -7
- data/Gemfile.lock +0 -84
- data/watchcat.gemspec +0 -37
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 6edf147a9999a757920046f26d3fadb4e8790f3acda6cb86787af3b6e5e31cce
|
|
4
|
+
data.tar.gz: 56ab8e22e361774d92df290073b46a25ee3ae4f8024a1c2e82340d7b8b4617b4
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: bf284e712f64ef2f69efce857c08dfb572a134e31857bd6a8d17afbdecd9d3d356609fae7fbf58cd8074cc49464f36f7390f7a897b132ac9626096416dd15b43
|
|
7
|
+
data.tar.gz: 66524cb293557d7c6b8a33739ed5d9c41b5d5b62dac5ada964d6b8d97df35d44e526ada232bfecee8375d1cc5cd2c4895c60fe3b0e6b5924eaef7f2005835ad8
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,31 @@
|
|
|
1
|
+
## Unreleased
|
|
2
|
+
|
|
3
|
+
## 0.6.0
|
|
4
|
+
|
|
5
|
+
* Add `#watch`, `#unwatch`, and `#watched` to the watcher returned by `Watchcat.watch` for dynamically managing watched paths.
|
|
6
|
+
* Add `Watchcat::EventHandler` for handling events with callback methods.
|
|
7
|
+
* Add `Watchcat::Event#src_path` and `Watchcat::Event#dest_path` for move/rename events.
|
|
8
|
+
* Add `patterns`, `ignore_patterns`, and `ignore_directories` options to `Watchcat.watch`.
|
|
9
|
+
* Fix `Watchcat::Executor#stop` so that it is a no-op in a forked child process, and make it idempotent.
|
|
10
|
+
|
|
11
|
+
## 0.5.2
|
|
12
|
+
|
|
13
|
+
* Support Ruby 4.0
|
|
14
|
+
|
|
15
|
+
## 0.5.1
|
|
16
|
+
|
|
17
|
+
* Fix missing executable files
|
|
18
|
+
|
|
19
|
+
## 0.5.0
|
|
20
|
+
|
|
21
|
+
* Rework the debounce feature. Now all events are debounced.
|
|
22
|
+
* Add `init` option to CLI
|
|
23
|
+
|
|
24
|
+
## 0.4.0
|
|
25
|
+
|
|
26
|
+
* Add CLI
|
|
27
|
+
* Add filters option
|
|
28
|
+
|
|
1
29
|
## 0.3.0
|
|
2
30
|
|
|
3
31
|
* Support Windows
|
data/Cargo.lock
CHANGED
|
@@ -13,16 +13,14 @@ dependencies = [
|
|
|
13
13
|
|
|
14
14
|
[[package]]
|
|
15
15
|
name = "bindgen"
|
|
16
|
-
version = "0.
|
|
16
|
+
version = "0.72.1"
|
|
17
17
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
18
|
-
checksum = "
|
|
18
|
+
checksum = "993776b509cfb49c750f11b8f07a46fa23e0a1386ffc01fb1e7d343efc387895"
|
|
19
19
|
dependencies = [
|
|
20
20
|
"bitflags 2.8.0",
|
|
21
21
|
"cexpr",
|
|
22
22
|
"clang-sys",
|
|
23
|
-
"
|
|
24
|
-
"lazycell",
|
|
25
|
-
"peeking_take_while",
|
|
23
|
+
"itertools",
|
|
26
24
|
"proc-macro2",
|
|
27
25
|
"quote",
|
|
28
26
|
"regex",
|
|
@@ -71,9 +69,9 @@ dependencies = [
|
|
|
71
69
|
|
|
72
70
|
[[package]]
|
|
73
71
|
name = "crossbeam-channel"
|
|
74
|
-
version = "0.5.
|
|
72
|
+
version = "0.5.16"
|
|
75
73
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
76
|
-
checksum = "
|
|
74
|
+
checksum = "d85363c37faeca707aef026efa9f3b34d077bce547e48f770770625c6013679e"
|
|
77
75
|
dependencies = [
|
|
78
76
|
"crossbeam-utils",
|
|
79
77
|
]
|
|
@@ -88,20 +86,10 @@ dependencies = [
|
|
|
88
86
|
]
|
|
89
87
|
|
|
90
88
|
[[package]]
|
|
91
|
-
name = "
|
|
92
|
-
version = "
|
|
89
|
+
name = "either"
|
|
90
|
+
version = "1.15.0"
|
|
93
91
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
94
|
-
checksum = "
|
|
95
|
-
dependencies = [
|
|
96
|
-
"libc",
|
|
97
|
-
"windows-sys 0.52.0",
|
|
98
|
-
]
|
|
99
|
-
|
|
100
|
-
[[package]]
|
|
101
|
-
name = "fastrand"
|
|
102
|
-
version = "2.1.1"
|
|
103
|
-
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
104
|
-
checksum = "e8c02a5121d4ea3eb16a80748c74f5549a5665e4c21333c6098f283870fbdea6"
|
|
92
|
+
checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719"
|
|
105
93
|
|
|
106
94
|
[[package]]
|
|
107
95
|
name = "fsevent-sys"
|
|
@@ -144,6 +132,15 @@ dependencies = [
|
|
|
144
132
|
"libc",
|
|
145
133
|
]
|
|
146
134
|
|
|
135
|
+
[[package]]
|
|
136
|
+
name = "itertools"
|
|
137
|
+
version = "0.13.0"
|
|
138
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
139
|
+
checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186"
|
|
140
|
+
dependencies = [
|
|
141
|
+
"either",
|
|
142
|
+
]
|
|
143
|
+
|
|
147
144
|
[[package]]
|
|
148
145
|
name = "kqueue"
|
|
149
146
|
version = "1.1.1"
|
|
@@ -170,12 +167,6 @@ version = "1.4.0"
|
|
|
170
167
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
171
168
|
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
|
172
169
|
|
|
173
|
-
[[package]]
|
|
174
|
-
name = "lazycell"
|
|
175
|
-
version = "1.3.0"
|
|
176
|
-
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
177
|
-
checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
|
|
178
|
-
|
|
179
170
|
[[package]]
|
|
180
171
|
name = "libc"
|
|
181
172
|
version = "0.2.161"
|
|
@@ -192,12 +183,6 @@ dependencies = [
|
|
|
192
183
|
"winapi",
|
|
193
184
|
]
|
|
194
185
|
|
|
195
|
-
[[package]]
|
|
196
|
-
name = "linux-raw-sys"
|
|
197
|
-
version = "0.4.14"
|
|
198
|
-
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
199
|
-
checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89"
|
|
200
|
-
|
|
201
186
|
[[package]]
|
|
202
187
|
name = "log"
|
|
203
188
|
version = "0.4.17"
|
|
@@ -209,9 +194,9 @@ dependencies = [
|
|
|
209
194
|
|
|
210
195
|
[[package]]
|
|
211
196
|
name = "magnus"
|
|
212
|
-
version = "0.
|
|
197
|
+
version = "0.8.2"
|
|
213
198
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
214
|
-
checksum = "
|
|
199
|
+
checksum = "3b36a5b126bbe97eb0d02d07acfeb327036c6319fd816139a49824a83b7f9012"
|
|
215
200
|
dependencies = [
|
|
216
201
|
"magnus-macros",
|
|
217
202
|
"rb-sys",
|
|
@@ -221,9 +206,9 @@ dependencies = [
|
|
|
221
206
|
|
|
222
207
|
[[package]]
|
|
223
208
|
name = "magnus-macros"
|
|
224
|
-
version = "0.
|
|
209
|
+
version = "0.8.0"
|
|
225
210
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
226
|
-
checksum = "
|
|
211
|
+
checksum = "47607461fd8e1513cb4f2076c197d8092d921a1ea75bd08af97398f593751892"
|
|
227
212
|
dependencies = [
|
|
228
213
|
"proc-macro2",
|
|
229
214
|
"quote",
|
|
@@ -267,9 +252,9 @@ dependencies = [
|
|
|
267
252
|
|
|
268
253
|
[[package]]
|
|
269
254
|
name = "notify"
|
|
270
|
-
version = "8.
|
|
255
|
+
version = "8.2.0"
|
|
271
256
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
272
|
-
checksum = "
|
|
257
|
+
checksum = "4d3d07927151ff8575b7087f245456e549fea62edf0ec4e565a5ee50c8402bc3"
|
|
273
258
|
dependencies = [
|
|
274
259
|
"bitflags 2.8.0",
|
|
275
260
|
"crossbeam-channel",
|
|
@@ -284,42 +269,17 @@ dependencies = [
|
|
|
284
269
|
"windows-sys 0.60.2",
|
|
285
270
|
]
|
|
286
271
|
|
|
287
|
-
[[package]]
|
|
288
|
-
name = "notify-debouncer-mini"
|
|
289
|
-
version = "0.6.0"
|
|
290
|
-
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
291
|
-
checksum = "a689eb4262184d9a1727f9087cd03883ea716682ab03ed24efec57d7716dccb8"
|
|
292
|
-
dependencies = [
|
|
293
|
-
"crossbeam-channel",
|
|
294
|
-
"log",
|
|
295
|
-
"notify",
|
|
296
|
-
"notify-types",
|
|
297
|
-
"tempfile",
|
|
298
|
-
]
|
|
299
|
-
|
|
300
272
|
[[package]]
|
|
301
273
|
name = "notify-types"
|
|
302
274
|
version = "2.0.0"
|
|
303
275
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
304
276
|
checksum = "5e0826a989adedc2a244799e823aece04662b66609d96af8dff7ac6df9a8925d"
|
|
305
277
|
|
|
306
|
-
[[package]]
|
|
307
|
-
name = "once_cell"
|
|
308
|
-
version = "1.20.2"
|
|
309
|
-
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
310
|
-
checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775"
|
|
311
|
-
|
|
312
|
-
[[package]]
|
|
313
|
-
name = "peeking_take_while"
|
|
314
|
-
version = "0.1.2"
|
|
315
|
-
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
316
|
-
checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099"
|
|
317
|
-
|
|
318
278
|
[[package]]
|
|
319
279
|
name = "proc-macro2"
|
|
320
|
-
version = "1.0.
|
|
280
|
+
version = "1.0.106"
|
|
321
281
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
322
|
-
checksum = "
|
|
282
|
+
checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934"
|
|
323
283
|
dependencies = [
|
|
324
284
|
"unicode-ident",
|
|
325
285
|
]
|
|
@@ -335,18 +295,18 @@ dependencies = [
|
|
|
335
295
|
|
|
336
296
|
[[package]]
|
|
337
297
|
name = "rb-sys"
|
|
338
|
-
version = "0.9.
|
|
298
|
+
version = "0.9.128"
|
|
339
299
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
340
|
-
checksum = "
|
|
300
|
+
checksum = "45ca28513560e56cfb79a62b1fce363c73af170a182024ce880c77ee9429920a"
|
|
341
301
|
dependencies = [
|
|
342
302
|
"rb-sys-build",
|
|
343
303
|
]
|
|
344
304
|
|
|
345
305
|
[[package]]
|
|
346
306
|
name = "rb-sys-build"
|
|
347
|
-
version = "0.9.
|
|
307
|
+
version = "0.9.128"
|
|
348
308
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
349
|
-
checksum = "
|
|
309
|
+
checksum = "ce04b2c55eff3a21aaa623fcc655d94373238e72cac6b3e1a3641ff31649f99a"
|
|
350
310
|
dependencies = [
|
|
351
311
|
"bindgen",
|
|
352
312
|
"lazy_static",
|
|
@@ -359,9 +319,9 @@ dependencies = [
|
|
|
359
319
|
|
|
360
320
|
[[package]]
|
|
361
321
|
name = "rb-sys-env"
|
|
362
|
-
version = "0.
|
|
322
|
+
version = "0.2.2"
|
|
363
323
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
364
|
-
checksum = "
|
|
324
|
+
checksum = "08f8d2924cf136a1315e2b4c7460a39f62ef11ee5d522df9b2750fab55b868b6"
|
|
365
325
|
|
|
366
326
|
[[package]]
|
|
367
327
|
name = "regex"
|
|
@@ -382,22 +342,9 @@ checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848"
|
|
|
382
342
|
|
|
383
343
|
[[package]]
|
|
384
344
|
name = "rustc-hash"
|
|
385
|
-
version = "
|
|
345
|
+
version = "2.1.2"
|
|
386
346
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
387
|
-
checksum = "
|
|
388
|
-
|
|
389
|
-
[[package]]
|
|
390
|
-
name = "rustix"
|
|
391
|
-
version = "0.38.38"
|
|
392
|
-
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
393
|
-
checksum = "aa260229e6538e52293eeb577aabd09945a09d6d9cc0fc550ed7529056c2e32a"
|
|
394
|
-
dependencies = [
|
|
395
|
-
"bitflags 2.8.0",
|
|
396
|
-
"errno",
|
|
397
|
-
"libc",
|
|
398
|
-
"linux-raw-sys",
|
|
399
|
-
"windows-sys 0.52.0",
|
|
400
|
-
]
|
|
347
|
+
checksum = "94300abf3f1ae2e2b8ffb7b58043de3d399c73fa6f4b73826402a5c457614dbe"
|
|
401
348
|
|
|
402
349
|
[[package]]
|
|
403
350
|
name = "same-file"
|
|
@@ -437,19 +384,6 @@ dependencies = [
|
|
|
437
384
|
"unicode-ident",
|
|
438
385
|
]
|
|
439
386
|
|
|
440
|
-
[[package]]
|
|
441
|
-
name = "tempfile"
|
|
442
|
-
version = "3.13.0"
|
|
443
|
-
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
444
|
-
checksum = "f0f2c9fc62d0beef6951ccffd757e241266a2c833136efbe35af6cd2567dca5b"
|
|
445
|
-
dependencies = [
|
|
446
|
-
"cfg-if",
|
|
447
|
-
"fastrand",
|
|
448
|
-
"once_cell",
|
|
449
|
-
"rustix",
|
|
450
|
-
"windows-sys 0.59.0",
|
|
451
|
-
]
|
|
452
|
-
|
|
453
387
|
[[package]]
|
|
454
388
|
name = "unicode-ident"
|
|
455
389
|
version = "1.0.7"
|
|
@@ -479,7 +413,6 @@ dependencies = [
|
|
|
479
413
|
"crossbeam-channel",
|
|
480
414
|
"magnus",
|
|
481
415
|
"notify",
|
|
482
|
-
"notify-debouncer-mini",
|
|
483
416
|
"rb-sys",
|
|
484
417
|
]
|
|
485
418
|
|
|
@@ -529,15 +462,6 @@ dependencies = [
|
|
|
529
462
|
"windows-targets 0.52.6",
|
|
530
463
|
]
|
|
531
464
|
|
|
532
|
-
[[package]]
|
|
533
|
-
name = "windows-sys"
|
|
534
|
-
version = "0.59.0"
|
|
535
|
-
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
536
|
-
checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
|
|
537
|
-
dependencies = [
|
|
538
|
-
"windows-targets 0.52.6",
|
|
539
|
-
]
|
|
540
|
-
|
|
541
465
|
[[package]]
|
|
542
466
|
name = "windows-sys"
|
|
543
467
|
version = "0.60.2"
|
data/Cargo.toml
CHANGED
data/Gemfile
CHANGED
data/README.md
CHANGED
|
@@ -8,7 +8,10 @@ This gem uses [Notify](https://github.com/notify-rs/notify) to get notifications
|
|
|
8
8
|
|
|
9
9
|
## Platforms
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
- Linux: inotify
|
|
12
|
+
- macOS: FSEvents
|
|
13
|
+
- Windows: ReadDirectoryChangesW
|
|
14
|
+
- All platforms: polling (via `force_polling` option)
|
|
12
15
|
|
|
13
16
|
## Installation
|
|
14
17
|
|
|
@@ -84,7 +87,6 @@ sleep
|
|
|
84
87
|
|
|
85
88
|
**CAUTION** The `watchcat` doesn't normalize the events. So the result might change per the platform.
|
|
86
89
|
|
|
87
|
-
|
|
88
90
|
### Options
|
|
89
91
|
|
|
90
92
|
| Name | Description | Default |
|
|
@@ -94,6 +96,190 @@ sleep
|
|
|
94
96
|
| **debounce** | Debounce events for the same file. | `-1` |
|
|
95
97
|
|
|
96
98
|
|
|
99
|
+
### Filters Option
|
|
100
|
+
|
|
101
|
+
You can use the `filters` option to ignore specific event types:
|
|
102
|
+
|
|
103
|
+
| Key | Description |
|
|
104
|
+
|-----------------|-----------------------------------|
|
|
105
|
+
| ignore_remove | Ignore remove (delete) events |
|
|
106
|
+
| ignore_access | Ignore access events |
|
|
107
|
+
| ignore_create | Ignore create events |
|
|
108
|
+
| ignore_modify | Ignore modify events |
|
|
109
|
+
|
|
110
|
+
Example usage:
|
|
111
|
+
|
|
112
|
+
```ruby
|
|
113
|
+
Watchcat.watch("/tmp/test", filters: { ignore_remove: true, ignore_access: true }) do |e|
|
|
114
|
+
pp e.paths, e.kind
|
|
115
|
+
end
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### Pattern Options
|
|
119
|
+
|
|
120
|
+
You can use the `patterns`, `ignore_patterns`, and `ignore_directories` options to filter events by path or type, using `File.fnmatch` glob patterns:
|
|
121
|
+
|
|
122
|
+
| Name | Description | Default |
|
|
123
|
+
| --------------------- | ------------------------------------------------------------------------| ------- |
|
|
124
|
+
| **patterns** | Only dispatch events where at least one path matches one of the patterns | `[]` |
|
|
125
|
+
| **ignore_patterns** | Skip events where at least one path matches one of the patterns | `[]` |
|
|
126
|
+
| **ignore_directories**| Skip events for directories | `false` |
|
|
127
|
+
|
|
128
|
+
**CAUTION** For `access`/`modify`/`rename` events, notify doesn't tell whether the path is a file or a directory, so `ignore_directories` falls back to a live `File.directory?` check on the path (best-effort; e.g. it can't tell for a path that no longer exists).
|
|
129
|
+
|
|
130
|
+
Example usage:
|
|
131
|
+
|
|
132
|
+
```ruby
|
|
133
|
+
Watchcat.watch(
|
|
134
|
+
"/tmp/test",
|
|
135
|
+
patterns: ["*.rb", "*.yml"],
|
|
136
|
+
ignore_patterns: ["*.tmp"],
|
|
137
|
+
ignore_directories: true
|
|
138
|
+
) do |e|
|
|
139
|
+
pp e.paths, e.kind
|
|
140
|
+
end
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
### Move (Rename) Events
|
|
144
|
+
|
|
145
|
+
For move/rename events (`e.kind.modify?` and `e.kind.modify.rename?`),
|
|
146
|
+
`Watchcat::Event#src_path` and `#dest_path` give the old and new path without
|
|
147
|
+
having to interpret the raw `paths` array and `RenameMode` yourself:
|
|
148
|
+
|
|
149
|
+
```ruby
|
|
150
|
+
Watchcat.watch("/tmp/test") do |e|
|
|
151
|
+
if e.kind.modify? && e.kind.modify.rename?
|
|
152
|
+
puts "moved: #{e.src_path} -> #{e.dest_path}"
|
|
153
|
+
end
|
|
154
|
+
end
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
Platform differences affect what is available:
|
|
158
|
+
|
|
159
|
+
- **Linux**: a `both` event fires with both paths, so `src_path` and
|
|
160
|
+
`dest_path` are both set.
|
|
161
|
+
- **Windows**: `from` and `to` fire as separate events, each with only one
|
|
162
|
+
side set (`src_path` on `from`, `dest_path` on `to`).
|
|
163
|
+
- **macOS**: FSEvents can't distinguish old/new paths, so both `src_path` and
|
|
164
|
+
`dest_path` are `nil`.
|
|
165
|
+
|
|
166
|
+
For non-rename events, both accessors return `nil`.
|
|
167
|
+
|
|
168
|
+
### Event Handler
|
|
169
|
+
|
|
170
|
+
Instead of writing a single block and branching on `event.kind` yourself, you
|
|
171
|
+
can subclass `Watchcat::EventHandler` and override just the callbacks you
|
|
172
|
+
need:
|
|
173
|
+
|
|
174
|
+
```ruby
|
|
175
|
+
class MyHandler < Watchcat::EventHandler
|
|
176
|
+
def on_create(event)
|
|
177
|
+
puts "created: #{event.paths[0]}"
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
def on_rename(event)
|
|
181
|
+
puts "moved: #{event.src_path} -> #{event.dest_path}"
|
|
182
|
+
end
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
Watchcat.watch("/tmp/test", handler: MyHandler.new)
|
|
186
|
+
sleep
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
Pass an instance via the `handler:` keyword instead of a block. `Watchcat::EventHandler` provides the following no-op callbacks to override:
|
|
190
|
+
|
|
191
|
+
| Callback | Description |
|
|
192
|
+
| --------------- | ----------------------------------------------------- |
|
|
193
|
+
| `on_any_event` | Called for every event, before the type-specific callback |
|
|
194
|
+
| `on_create` | Called for create events |
|
|
195
|
+
| `on_modify` | Called for modify events (excluding renames) |
|
|
196
|
+
| `on_remove` | Called for remove events |
|
|
197
|
+
| `on_rename` | Called for rename/move events (`src_path`/`dest_path` available) |
|
|
198
|
+
| `on_access` | Called for access events |
|
|
199
|
+
|
|
200
|
+
### Dynamically Adding / Removing Paths
|
|
201
|
+
|
|
202
|
+
The watcher returned by `Watchcat.watch` can have paths added or removed while
|
|
203
|
+
it's running:
|
|
204
|
+
|
|
205
|
+
```ruby
|
|
206
|
+
w = Watchcat.watch("/tmp/a") { |e| pp e.paths, e.kind }
|
|
207
|
+
|
|
208
|
+
w.watch("/tmp/b") # also watch /tmp/b
|
|
209
|
+
w.watch("/tmp/c", recursive: false) # non-recursive
|
|
210
|
+
w.unwatch("/tmp/a") # stop watching /tmp/a
|
|
211
|
+
w.watched # => current watched paths
|
|
212
|
+
|
|
213
|
+
sleep
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
All watched paths share the single callback/handler passed to `Watchcat.watch`
|
|
217
|
+
(and the same `filters`/`patterns`/`debounce` settings). `recursive:` on `watch`
|
|
218
|
+
defaults to the value passed to `Watchcat.watch`. `watch` raises `ArgumentError`
|
|
219
|
+
immediately if a path does not exist. Applying `unwatch` is asynchronous, so
|
|
220
|
+
its exact timing (and behavior) can differ per platform, notably on macOS
|
|
221
|
+
(FSEvents). Both `watch` and `unwatch` accept a single path or an array of
|
|
222
|
+
paths.
|
|
223
|
+
|
|
224
|
+
## CLI
|
|
225
|
+
|
|
226
|
+
`watchcat` comes with a command-line interface that allows you to watch files and execute commands when changes occur.
|
|
227
|
+
|
|
228
|
+
### Usage
|
|
229
|
+
|
|
230
|
+
```
|
|
231
|
+
# Run watchcat with a config file
|
|
232
|
+
$ watchcat -C config.yml
|
|
233
|
+
|
|
234
|
+
# Generate a template config file
|
|
235
|
+
$ watchcat --init config.yml
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
### Configuration File
|
|
239
|
+
|
|
240
|
+
The configuration file should be in YAML format. Here's an example:
|
|
241
|
+
|
|
242
|
+
```yaml
|
|
243
|
+
watches:
|
|
244
|
+
- path: "./lib"
|
|
245
|
+
recursive: true
|
|
246
|
+
debounce: 300
|
|
247
|
+
filters:
|
|
248
|
+
ignore_access: true
|
|
249
|
+
patterns:
|
|
250
|
+
- "*.rb"
|
|
251
|
+
- "*.yml"
|
|
252
|
+
actions:
|
|
253
|
+
- command: "echo 'Ruby/YAML file changed: {{file_name}}'"
|
|
254
|
+
- command: "rubocop {{file_path}}"
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
### Configuration Options
|
|
258
|
+
|
|
259
|
+
Each watch entry supports the following options:
|
|
260
|
+
|
|
261
|
+
| Option | Description | Default |
|
|
262
|
+
|-------------|--------------------------------------------------------|---------|
|
|
263
|
+
| path | Directory or file path to watch (required) | - |
|
|
264
|
+
| recursive | Watch a directory recursively or not | `true` |
|
|
265
|
+
| debounce | Debounce events for the same file (in milliseconds) | `-1` |
|
|
266
|
+
| filters | Event filters (same as library filters option) | `{}` |
|
|
267
|
+
| patterns | File patterns to match (using File.fnmatch) | `[]` |
|
|
268
|
+
| actions | Commands to execute when files change | `[]` |
|
|
269
|
+
|
|
270
|
+
### Available Variables for Commands
|
|
271
|
+
|
|
272
|
+
When specifying commands, you can use the following variables:
|
|
273
|
+
|
|
274
|
+
| Variable | Description | Example |
|
|
275
|
+
|----------------|------------------------------------------|--------------------------|
|
|
276
|
+
| {{file_path}} | Full path of the changed file | `/home/user/app/file.rb` |
|
|
277
|
+
| {{file_dir}} | Directory containing the file | `/home/user/app` |
|
|
278
|
+
| {{file_name}} | File name with extension | `file.rb` |
|
|
279
|
+
| {{file_base}} | File name without extension | `file` |
|
|
280
|
+
| {{file_ext}} | File extension | `.rb` |
|
|
281
|
+
| {{event_type}} | Type of event | `create` |
|
|
282
|
+
|
|
97
283
|
## Contributing
|
|
98
284
|
|
|
99
285
|
Bug reports and pull requests are welcome on GitHub at https://github.com/y-yagi/watchcat.
|
data/cli_example.yml
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# Watchcat Configuration File
|
|
2
|
+
|
|
3
|
+
watches:
|
|
4
|
+
- path: "./lib"
|
|
5
|
+
recursive: true
|
|
6
|
+
debounce: 300
|
|
7
|
+
filters:
|
|
8
|
+
ignore_access: true
|
|
9
|
+
patterns:
|
|
10
|
+
- "*.rb"
|
|
11
|
+
- "*.yml"
|
|
12
|
+
actions:
|
|
13
|
+
- command: "echo 'Ruby/YAML file changed: {{file_name}}'"
|
|
14
|
+
- command: "rubocop {{file_path}}"
|
data/exe/watchcat
ADDED
data/ext/watchcat/Cargo.toml
CHANGED
|
@@ -9,7 +9,6 @@ crate-type = ["cdylib"]
|
|
|
9
9
|
|
|
10
10
|
[dependencies]
|
|
11
11
|
crossbeam-channel = "0.5.15"
|
|
12
|
-
magnus = "0.
|
|
13
|
-
notify = { version = "8.
|
|
14
|
-
|
|
15
|
-
rb-sys = "0.9.116"
|
|
12
|
+
magnus = "0.8"
|
|
13
|
+
notify = { version = "8.2.0", features = ["crossbeam-channel"] }
|
|
14
|
+
rb-sys = "0.9.128"
|