mirror of
https://github.com/watchexec/watchexec.git
synced 2024-09-29 22:51:33 +02:00
Compare commits
19 Commits
project-or
...
main
Author | SHA1 | Date | |
---|---|---|---|
|
6c245d3aff | ||
|
08367c6db7 | ||
|
2cc7743677 | ||
|
2c1388e678 | ||
|
b0125bc113 | ||
|
510dd625d1 | ||
|
6e981fd8ab | ||
|
24df7a4f45 | ||
|
9f1f2e9d04 | ||
|
0e393c25cf | ||
|
2026c52abd | ||
|
72f069a847 | ||
|
4affed6fff | ||
|
e0084e69f8 | ||
|
592b712c95 | ||
|
c9a3b9df00 | ||
|
e63d37f601 | ||
|
14e6294f5a | ||
|
234d606563 |
13
.github/workflows/release-cli.yml
vendored
13
.github/workflows/release-cli.yml
vendored
@ -104,10 +104,10 @@ jobs:
|
|||||||
experimental: false
|
experimental: false
|
||||||
|
|
||||||
- name: mac-arm64
|
- name: mac-arm64
|
||||||
os: macos-11.0
|
os: macos-latest
|
||||||
target: aarch64-apple-darwin
|
target: aarch64-apple-darwin
|
||||||
cross: true
|
cross: true
|
||||||
experimental: true
|
experimental: false
|
||||||
|
|
||||||
- name: windows-x86-64
|
- name: windows-x86-64
|
||||||
os: windows-latest
|
os: windows-latest
|
||||||
@ -197,9 +197,15 @@ jobs:
|
|||||||
tool: cross
|
tool: cross
|
||||||
|
|
||||||
- name: Build
|
- name: Build
|
||||||
run: ${{ matrix.cross && 'cross' || 'cargo' }} build --package watchexec-cli --release --locked --target ${{ matrix.target }}
|
shell: bash
|
||||||
|
run: |
|
||||||
|
${{ matrix.cross && 'cross' || 'cargo' }} build \
|
||||||
|
-p watchexec-cli \
|
||||||
|
--release --locked \
|
||||||
|
--target ${{ matrix.target }}
|
||||||
|
|
||||||
- name: Make manpage
|
- name: Make manpage
|
||||||
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
cargo run -p watchexec-cli \
|
cargo run -p watchexec-cli \
|
||||||
${{ (!matrix.cross) && '--release --target' || '' }} \
|
${{ (!matrix.cross) && '--release --target' || '' }} \
|
||||||
@ -207,6 +213,7 @@ jobs:
|
|||||||
--locked -- --manual > doc/watchexec.1
|
--locked -- --manual > doc/watchexec.1
|
||||||
|
|
||||||
- name: Make completions
|
- name: Make completions
|
||||||
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
bin/completions \
|
bin/completions \
|
||||||
${{ (!matrix.cross) && '--release --target' || '' }} \
|
${{ (!matrix.cross) && '--release --target' || '' }} \
|
||||||
|
@ -3,8 +3,8 @@ message: |
|
|||||||
If you use this software, please cite it using these metadata.
|
If you use this software, please cite it using these metadata.
|
||||||
title: "Watchexec: a tool to react to filesystem changes, and a crate ecosystem to power it"
|
title: "Watchexec: a tool to react to filesystem changes, and a crate ecosystem to power it"
|
||||||
|
|
||||||
version: "2.0.0"
|
version: "2.1.2"
|
||||||
date-released: 2024-04-20
|
date-released: 2024-06-30
|
||||||
|
|
||||||
repository-code: https://github.com/watchexec/watchexec
|
repository-code: https://github.com/watchexec/watchexec
|
||||||
license: Apache-2.0
|
license: Apache-2.0
|
||||||
|
51
Cargo.lock
generated
51
Cargo.lock
generated
@ -488,7 +488,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bosion"
|
name = "bosion"
|
||||||
version = "1.0.3"
|
version = "1.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"gix",
|
"gix",
|
||||||
"time",
|
"time",
|
||||||
@ -1317,6 +1317,7 @@ dependencies = [
|
|||||||
"gix-glob",
|
"gix-glob",
|
||||||
"gix-hash",
|
"gix-hash",
|
||||||
"gix-hashtable",
|
"gix-hashtable",
|
||||||
|
"gix-index",
|
||||||
"gix-lock",
|
"gix-lock",
|
||||||
"gix-macros",
|
"gix-macros",
|
||||||
"gix-object",
|
"gix-object",
|
||||||
@ -1354,6 +1355,15 @@ dependencies = [
|
|||||||
"winnow 0.6.6",
|
"winnow 0.6.6",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "gix-bitmap"
|
||||||
|
version = "0.2.11"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a371db66cbd4e13f0ed9dc4c0fea712d7276805fccc877f77e96374d317e87ae"
|
||||||
|
dependencies = [
|
||||||
|
"thiserror",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "gix-chunk"
|
name = "gix-chunk"
|
||||||
version = "0.4.8"
|
version = "0.4.8"
|
||||||
@ -1513,6 +1523,33 @@ dependencies = [
|
|||||||
"parking_lot",
|
"parking_lot",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "gix-index"
|
||||||
|
version = "0.32.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "881ab3b1fa57f497601a5add8289e72a7ae09471fc0b9bbe483b628ae8e418a1"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags 2.5.0",
|
||||||
|
"bstr",
|
||||||
|
"filetime",
|
||||||
|
"fnv",
|
||||||
|
"gix-bitmap",
|
||||||
|
"gix-features",
|
||||||
|
"gix-fs",
|
||||||
|
"gix-hash",
|
||||||
|
"gix-lock",
|
||||||
|
"gix-object",
|
||||||
|
"gix-traverse",
|
||||||
|
"gix-utils",
|
||||||
|
"hashbrown 0.14.3",
|
||||||
|
"itoa",
|
||||||
|
"libc",
|
||||||
|
"memmap2",
|
||||||
|
"rustix",
|
||||||
|
"smallvec",
|
||||||
|
"thiserror",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "gix-lock"
|
name = "gix-lock"
|
||||||
version = "13.1.1"
|
version = "13.1.1"
|
||||||
@ -1988,7 +2025,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ignore-files"
|
name = "ignore-files"
|
||||||
version = "3.0.0"
|
version = "3.0.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"dunce",
|
"dunce",
|
||||||
"futures",
|
"futures",
|
||||||
@ -4007,7 +4044,7 @@ checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "watchexec"
|
name = "watchexec"
|
||||||
version = "4.0.0"
|
version = "4.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-priority-channel",
|
"async-priority-channel",
|
||||||
"async-recursion",
|
"async-recursion",
|
||||||
@ -4032,7 +4069,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "watchexec-cli"
|
name = "watchexec-cli"
|
||||||
version = "2.0.0"
|
version = "2.1.2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ahash",
|
"ahash",
|
||||||
"argfile",
|
"argfile",
|
||||||
@ -4048,6 +4085,7 @@ dependencies = [
|
|||||||
"console-subscriber",
|
"console-subscriber",
|
||||||
"dashmap",
|
"dashmap",
|
||||||
"dirs 5.0.1",
|
"dirs 5.0.1",
|
||||||
|
"dunce",
|
||||||
"embed-resource",
|
"embed-resource",
|
||||||
"eyra",
|
"eyra",
|
||||||
"futures",
|
"futures",
|
||||||
@ -4097,10 +4135,11 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "watchexec-filterer-globset"
|
name = "watchexec-filterer-globset"
|
||||||
version = "4.0.0"
|
version = "4.0.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ignore",
|
"ignore",
|
||||||
"ignore-files",
|
"ignore-files",
|
||||||
|
"tempfile",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tracing",
|
"tracing",
|
||||||
"tracing-subscriber",
|
"tracing-subscriber",
|
||||||
@ -4111,7 +4150,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "watchexec-filterer-ignore"
|
name = "watchexec-filterer-ignore"
|
||||||
version = "4.0.0"
|
version = "4.0.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"dunce",
|
"dunce",
|
||||||
"ignore",
|
"ignore",
|
||||||
|
@ -19,7 +19,7 @@ _watchexec() {
|
|||||||
|
|
||||||
case "${cmd}" in
|
case "${cmd}" in
|
||||||
watchexec)
|
watchexec)
|
||||||
opts="-w -W -c -o -r -s -d -p -n -E -1 -N -q -e -f -j -i -v -h -V --watch --watch-non-recursive --clear --on-busy-update --restart --signal --stop-signal --stop-timeout --map-signal --debounce --stdin-quit --no-vcs-ignore --no-project-ignore --no-global-ignore --no-default-ignore --no-discover-ignore --ignore-nothing --postpone --delay-run --poll --shell --no-environment --emit-events-to --only-emit-events --env --no-process-group --wrap-process --notify --color --timings --quiet --bell --project-origin --workdir --exts --filter --filter-file --filter-prog --ignore --ignore-file --fs-events --no-meta --print-events --manual --completions --verbose --log-file --help --version [COMMAND]..."
|
opts="-w -W -F -c -o -r -s -d -p -n -E -1 -N -q -e -f -j -i -v -h -V --watch --watch-non-recursive --watch-file --clear --on-busy-update --restart --signal --stop-signal --stop-timeout --map-signal --debounce --stdin-quit --no-vcs-ignore --no-project-ignore --no-global-ignore --no-default-ignore --no-discover-ignore --ignore-nothing --postpone --delay-run --poll --shell --no-environment --emit-events-to --only-emit-events --env --no-process-group --wrap-process --notify --color --timings --quiet --bell --project-origin --workdir --exts --filter --filter-file --filter-prog --ignore --ignore-file --fs-events --no-meta --print-events --manual --completions --verbose --log-file --help --version [COMMAND]..."
|
||||||
if [[ ${cur} == -* || ${COMP_CWORD} -eq 1 ]] ; then
|
if [[ ${cur} == -* || ${COMP_CWORD} -eq 1 ]] ; then
|
||||||
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
|
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
|
||||||
return 0
|
return 0
|
||||||
@ -41,6 +41,14 @@ _watchexec() {
|
|||||||
COMPREPLY=($(compgen -f "${cur}"))
|
COMPREPLY=($(compgen -f "${cur}"))
|
||||||
return 0
|
return 0
|
||||||
;;
|
;;
|
||||||
|
--watch-file)
|
||||||
|
COMPREPLY=($(compgen -f "${cur}"))
|
||||||
|
return 0
|
||||||
|
;;
|
||||||
|
-F)
|
||||||
|
COMPREPLY=($(compgen -f "${cur}"))
|
||||||
|
return 0
|
||||||
|
;;
|
||||||
--clear)
|
--clear)
|
||||||
COMPREPLY=($(compgen -W "clear reset" -- "${cur}"))
|
COMPREPLY=($(compgen -W "clear reset" -- "${cur}"))
|
||||||
return 0
|
return 0
|
||||||
|
@ -22,6 +22,8 @@ set edit:completion:arg-completer[watchexec] = {|@words|
|
|||||||
cand --watch 'Watch a specific file or directory'
|
cand --watch 'Watch a specific file or directory'
|
||||||
cand -W 'Watch a specific directory, non-recursively'
|
cand -W 'Watch a specific directory, non-recursively'
|
||||||
cand --watch-non-recursive 'Watch a specific directory, non-recursively'
|
cand --watch-non-recursive 'Watch a specific directory, non-recursively'
|
||||||
|
cand -F 'Watch files and directories from a file'
|
||||||
|
cand --watch-file 'Watch files and directories from a file'
|
||||||
cand -c 'Clear screen before running command'
|
cand -c 'Clear screen before running command'
|
||||||
cand --clear 'Clear screen before running command'
|
cand --clear 'Clear screen before running command'
|
||||||
cand -o 'What to do when receiving events while the command is running'
|
cand -o 'What to do when receiving events while the command is running'
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
complete -c watchexec -s w -l watch -d 'Watch a specific file or directory' -r -F
|
complete -c watchexec -s w -l watch -d 'Watch a specific file or directory' -r -F
|
||||||
complete -c watchexec -s W -l watch-non-recursive -d 'Watch a specific directory, non-recursively' -r -F
|
complete -c watchexec -s W -l watch-non-recursive -d 'Watch a specific directory, non-recursively' -r -F
|
||||||
|
complete -c watchexec -s F -l watch-file -d 'Watch files and directories from a file' -r -F
|
||||||
complete -c watchexec -s c -l clear -d 'Clear screen before running command' -r -f -a "{clear '',reset ''}"
|
complete -c watchexec -s c -l clear -d 'Clear screen before running command' -r -f -a "{clear '',reset ''}"
|
||||||
complete -c watchexec -s o -l on-busy-update -d 'What to do when receiving events while the command is running' -r -f -a "{queue '',do-nothing '',restart '',signal ''}"
|
complete -c watchexec -s o -l on-busy-update -d 'What to do when receiving events while the command is running' -r -f -a "{queue '',do-nothing '',restart '',signal ''}"
|
||||||
complete -c watchexec -s s -l signal -d 'Send a signal to the process when it\'s still running' -r
|
complete -c watchexec -s s -l signal -d 'Send a signal to the process when it\'s still running' -r
|
||||||
|
@ -33,6 +33,7 @@ module completions {
|
|||||||
...command: string # Command to run on changes
|
...command: string # Command to run on changes
|
||||||
--watch(-w): string # Watch a specific file or directory
|
--watch(-w): string # Watch a specific file or directory
|
||||||
--watch-non-recursive(-W): string # Watch a specific directory, non-recursively
|
--watch-non-recursive(-W): string # Watch a specific directory, non-recursively
|
||||||
|
--watch-file(-F): string # Watch files and directories from a file
|
||||||
--clear(-c): string@"nu-complete watchexec screen_clear" # Clear screen before running command
|
--clear(-c): string@"nu-complete watchexec screen_clear" # Clear screen before running command
|
||||||
--on-busy-update(-o): string@"nu-complete watchexec on_busy_update" # What to do when receiving events while the command is running
|
--on-busy-update(-o): string@"nu-complete watchexec on_busy_update" # What to do when receiving events while the command is running
|
||||||
--restart(-r) # Restart the process if it's still running
|
--restart(-r) # Restart the process if it's still running
|
||||||
|
@ -25,6 +25,8 @@ Register-ArgumentCompleter -Native -CommandName 'watchexec' -ScriptBlock {
|
|||||||
[CompletionResult]::new('--watch', 'watch', [CompletionResultType]::ParameterName, 'Watch a specific file or directory')
|
[CompletionResult]::new('--watch', 'watch', [CompletionResultType]::ParameterName, 'Watch a specific file or directory')
|
||||||
[CompletionResult]::new('-W', 'W ', [CompletionResultType]::ParameterName, 'Watch a specific directory, non-recursively')
|
[CompletionResult]::new('-W', 'W ', [CompletionResultType]::ParameterName, 'Watch a specific directory, non-recursively')
|
||||||
[CompletionResult]::new('--watch-non-recursive', 'watch-non-recursive', [CompletionResultType]::ParameterName, 'Watch a specific directory, non-recursively')
|
[CompletionResult]::new('--watch-non-recursive', 'watch-non-recursive', [CompletionResultType]::ParameterName, 'Watch a specific directory, non-recursively')
|
||||||
|
[CompletionResult]::new('-F', 'F ', [CompletionResultType]::ParameterName, 'Watch files and directories from a file')
|
||||||
|
[CompletionResult]::new('--watch-file', 'watch-file', [CompletionResultType]::ParameterName, 'Watch files and directories from a file')
|
||||||
[CompletionResult]::new('-c', 'c', [CompletionResultType]::ParameterName, 'Clear screen before running command')
|
[CompletionResult]::new('-c', 'c', [CompletionResultType]::ParameterName, 'Clear screen before running command')
|
||||||
[CompletionResult]::new('--clear', 'clear', [CompletionResultType]::ParameterName, 'Clear screen before running command')
|
[CompletionResult]::new('--clear', 'clear', [CompletionResultType]::ParameterName, 'Clear screen before running command')
|
||||||
[CompletionResult]::new('-o', 'o', [CompletionResultType]::ParameterName, 'What to do when receiving events while the command is running')
|
[CompletionResult]::new('-o', 'o', [CompletionResultType]::ParameterName, 'What to do when receiving events while the command is running')
|
||||||
|
@ -19,6 +19,8 @@ _watchexec() {
|
|||||||
'*--watch=[Watch a specific file or directory]:PATH:_files' \
|
'*--watch=[Watch a specific file or directory]:PATH:_files' \
|
||||||
'*-W+[Watch a specific directory, non-recursively]:PATH:_files' \
|
'*-W+[Watch a specific directory, non-recursively]:PATH:_files' \
|
||||||
'*--watch-non-recursive=[Watch a specific directory, non-recursively]:PATH:_files' \
|
'*--watch-non-recursive=[Watch a specific directory, non-recursively]:PATH:_files' \
|
||||||
|
'-F+[Watch files and directories from a file]:PATH:_files' \
|
||||||
|
'--watch-file=[Watch files and directories from a file]:PATH:_files' \
|
||||||
'-c+[Clear screen before running command]' \
|
'-c+[Clear screen before running command]' \
|
||||||
'--clear=[Clear screen before running command]' \
|
'--clear=[Clear screen before running command]' \
|
||||||
'-o+[What to do when receiving events while the command is running]:MODE:(queue do-nothing restart signal)' \
|
'-o+[What to do when receiving events while the command is running]:MODE:(queue do-nothing restart signal)' \
|
||||||
|
@ -2,6 +2,10 @@
|
|||||||
|
|
||||||
## Next (YYYY-MM-DD)
|
## Next (YYYY-MM-DD)
|
||||||
|
|
||||||
|
## v1.1.0 (2024-05-16)
|
||||||
|
|
||||||
|
- Add `git-describe` support (#832, by @lu-zero)
|
||||||
|
|
||||||
## v1.0.3 (2024-04-20)
|
## v1.0.3 (2024-04-20)
|
||||||
|
|
||||||
- Deps: gix 0.62
|
- Deps: gix 0.62
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "bosion"
|
name = "bosion"
|
||||||
version = "1.0.3"
|
version = "1.1.0"
|
||||||
|
|
||||||
authors = ["Félix Saparelli <felix@passcod.name>"]
|
authors = ["Félix Saparelli <felix@passcod.name>"]
|
||||||
license = "Apache-2.0 OR MIT"
|
license = "Apache-2.0 OR MIT"
|
||||||
@ -22,6 +22,7 @@ features = ["macros", "formatting"]
|
|||||||
version = "0.62.0"
|
version = "0.62.0"
|
||||||
optional = true
|
optional = true
|
||||||
default-features = false
|
default-features = false
|
||||||
|
features = ["revision"]
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["git", "reproducible", "std"]
|
default = ["git", "reproducible", "std"]
|
||||||
|
@ -15,7 +15,7 @@ In your `Cargo.toml`:
|
|||||||
|
|
||||||
```toml
|
```toml
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
bosion = "1.0.3"
|
bosion = "1.1.0"
|
||||||
```
|
```
|
||||||
|
|
||||||
In your `build.rs`:
|
In your `build.rs`:
|
||||||
|
105
crates/bosion/examples/clap/Cargo.lock
generated
105
crates/bosion/examples/clap/Cargo.lock
generated
@ -8,6 +8,24 @@ version = "1.0.2"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
|
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ahash"
|
||||||
|
version = "0.8.11"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"once_cell",
|
||||||
|
"version_check",
|
||||||
|
"zerocopy",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "allocator-api2"
|
||||||
|
version = "0.2.18"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "anstream"
|
name = "anstream"
|
||||||
version = "0.6.13"
|
version = "0.6.13"
|
||||||
@ -82,7 +100,7 @@ checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bosion"
|
name = "bosion"
|
||||||
version = "1.0.2"
|
version = "1.0.3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"gix",
|
"gix",
|
||||||
"time",
|
"time",
|
||||||
@ -211,6 +229,18 @@ version = "2.0.2"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "658bd65b1cf4c852a3cc96f18a8ce7b5640f6b703f905c7d74532294c2a63984"
|
checksum = "658bd65b1cf4c852a3cc96f18a8ce7b5640f6b703f905c7d74532294c2a63984"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "filetime"
|
||||||
|
version = "0.2.23"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1ee447700ac8aa0b2f2bd7bc4462ad686ba06baa6727ac149a2d6277f0d240fd"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"libc",
|
||||||
|
"redox_syscall",
|
||||||
|
"windows-sys",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "flate2"
|
name = "flate2"
|
||||||
version = "1.0.28"
|
version = "1.0.28"
|
||||||
@ -221,6 +251,12 @@ dependencies = [
|
|||||||
"miniz_oxide",
|
"miniz_oxide",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "fnv"
|
||||||
|
version = "1.0.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "form_urlencoded"
|
name = "form_urlencoded"
|
||||||
version = "1.2.1"
|
version = "1.2.1"
|
||||||
@ -247,6 +283,7 @@ dependencies = [
|
|||||||
"gix-glob",
|
"gix-glob",
|
||||||
"gix-hash",
|
"gix-hash",
|
||||||
"gix-hashtable",
|
"gix-hashtable",
|
||||||
|
"gix-index",
|
||||||
"gix-lock",
|
"gix-lock",
|
||||||
"gix-macros",
|
"gix-macros",
|
||||||
"gix-object",
|
"gix-object",
|
||||||
@ -284,6 +321,15 @@ dependencies = [
|
|||||||
"winnow",
|
"winnow",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "gix-bitmap"
|
||||||
|
version = "0.2.11"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a371db66cbd4e13f0ed9dc4c0fea712d7276805fccc877f77e96374d317e87ae"
|
||||||
|
dependencies = [
|
||||||
|
"thiserror",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "gix-chunk"
|
name = "gix-chunk"
|
||||||
version = "0.4.8"
|
version = "0.4.8"
|
||||||
@ -443,6 +489,33 @@ dependencies = [
|
|||||||
"parking_lot",
|
"parking_lot",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "gix-index"
|
||||||
|
version = "0.32.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "881ab3b1fa57f497601a5add8289e72a7ae09471fc0b9bbe483b628ae8e418a1"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags 2.5.0",
|
||||||
|
"bstr",
|
||||||
|
"filetime",
|
||||||
|
"fnv",
|
||||||
|
"gix-bitmap",
|
||||||
|
"gix-features",
|
||||||
|
"gix-fs",
|
||||||
|
"gix-hash",
|
||||||
|
"gix-lock",
|
||||||
|
"gix-object",
|
||||||
|
"gix-traverse",
|
||||||
|
"gix-utils",
|
||||||
|
"hashbrown",
|
||||||
|
"itoa",
|
||||||
|
"libc",
|
||||||
|
"memmap2",
|
||||||
|
"rustix",
|
||||||
|
"smallvec",
|
||||||
|
"thiserror",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "gix-lock"
|
name = "gix-lock"
|
||||||
version = "13.1.1"
|
version = "13.1.1"
|
||||||
@ -702,6 +775,10 @@ name = "hashbrown"
|
|||||||
version = "0.14.3"
|
version = "0.14.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604"
|
checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604"
|
||||||
|
dependencies = [
|
||||||
|
"ahash",
|
||||||
|
"allocator-api2",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "heck"
|
name = "heck"
|
||||||
@ -1076,6 +1153,12 @@ version = "0.2.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a"
|
checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "version_check"
|
||||||
|
version = "0.9.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "walkdir"
|
name = "walkdir"
|
||||||
version = "2.5.0"
|
version = "2.5.0"
|
||||||
@ -1255,3 +1338,23 @@ checksum = "f0c976aaaa0e1f90dbb21e9587cdaf1d9679a1cde8875c0d6bd83ab96a208352"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"memchr",
|
"memchr",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "zerocopy"
|
||||||
|
version = "0.7.34"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ae87e3fcd617500e5d106f0380cf7b77f3c6092aae37191433159dda23cfb087"
|
||||||
|
dependencies = [
|
||||||
|
"zerocopy-derive",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "zerocopy-derive"
|
||||||
|
version = "0.7.34"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "15e934569e47891f7d9411f1a451d947a60e000ab3bd24fbb970f000387d1b3b"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
@ -13,6 +13,9 @@ struct Args {
|
|||||||
|
|
||||||
#[clap(long)]
|
#[clap(long)]
|
||||||
dates: bool,
|
dates: bool,
|
||||||
|
|
||||||
|
#[clap(long)]
|
||||||
|
describe: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
@ -23,17 +26,15 @@ fn main() {
|
|||||||
"{}",
|
"{}",
|
||||||
Bosion::long_version_with(&[("extra", "field"), ("custom", "1.2.3"),])
|
Bosion::long_version_with(&[("extra", "field"), ("custom", "1.2.3"),])
|
||||||
);
|
);
|
||||||
} else
|
} else if args.features {
|
||||||
|
|
||||||
if args.features {
|
|
||||||
println!("Features: {}", Bosion::CRATE_FEATURE_STRING);
|
println!("Features: {}", Bosion::CRATE_FEATURE_STRING);
|
||||||
} else
|
} else if args.dates {
|
||||||
|
|
||||||
if args.dates {
|
|
||||||
println!("commit date: {}", Bosion::GIT_COMMIT_DATE);
|
println!("commit date: {}", Bosion::GIT_COMMIT_DATE);
|
||||||
println!("commit datetime: {}", Bosion::GIT_COMMIT_DATETIME);
|
println!("commit datetime: {}", Bosion::GIT_COMMIT_DATETIME);
|
||||||
println!("build date: {}", Bosion::BUILD_DATE);
|
println!("build date: {}", Bosion::BUILD_DATE);
|
||||||
println!("build datetime: {}", Bosion::BUILD_DATETIME);
|
println!("build datetime: {}", Bosion::BUILD_DATETIME);
|
||||||
|
} else if args.describe {
|
||||||
|
println!("commit description: {}", Bosion::GIT_COMMIT_DESCRIPTION);
|
||||||
} else {
|
} else {
|
||||||
println!("{}", Bosion::LONG_VERSION);
|
println!("{}", Bosion::LONG_VERSION);
|
||||||
}
|
}
|
||||||
|
@ -145,6 +145,9 @@ pub struct GitInfo {
|
|||||||
|
|
||||||
/// The datetime of the current commit, in the format `YYYY-MM-DD HH:MM:SS`, at UTC.
|
/// The datetime of the current commit, in the format `YYYY-MM-DD HH:MM:SS`, at UTC.
|
||||||
pub git_datetime: String,
|
pub git_datetime: String,
|
||||||
|
|
||||||
|
/// The `git describe` equivalent output
|
||||||
|
pub git_description: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "git")]
|
#[cfg(feature = "git")]
|
||||||
@ -163,6 +166,7 @@ impl GitInfo {
|
|||||||
git_shorthash: head.short_id().err_string()?.to_string(),
|
git_shorthash: head.short_id().err_string()?.to_string(),
|
||||||
git_date: timestamp.format(DATE_FORMAT).err_string()?,
|
git_date: timestamp.format(DATE_FORMAT).err_string()?,
|
||||||
git_datetime: timestamp.format(DATETIME_FORMAT).err_string()?,
|
git_datetime: timestamp.format(DATETIME_FORMAT).err_string()?,
|
||||||
|
git_description: head.describe().format().err_string()?.to_string(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -74,6 +74,7 @@ pub fn gather_to(filename: &str, structname: &str, public: bool) {
|
|||||||
git_shorthash,
|
git_shorthash,
|
||||||
git_date,
|
git_date,
|
||||||
git_datetime,
|
git_datetime,
|
||||||
|
git_description,
|
||||||
..
|
..
|
||||||
}) = git
|
}) = git
|
||||||
{
|
{
|
||||||
@ -104,6 +105,11 @@ pub fn gather_to(filename: &str, structname: &str, public: bool) {
|
|||||||
/// This is the date and time (`YYYY-MM-DD HH:MM:SS`) of the commit that was built. Same
|
/// This is the date and time (`YYYY-MM-DD HH:MM:SS`) of the commit that was built. Same
|
||||||
/// caveats as with `GIT_COMMIT_HASH` apply.
|
/// caveats as with `GIT_COMMIT_HASH` apply.
|
||||||
pub const GIT_COMMIT_DATETIME: &'static str = {git_datetime:?};
|
pub const GIT_COMMIT_DATETIME: &'static str = {git_datetime:?};
|
||||||
|
|
||||||
|
/// The git description
|
||||||
|
///
|
||||||
|
/// This is the string equivalent to what `git describe` would output
|
||||||
|
pub const GIT_COMMIT_DESCRIPTION: &'static str = {git_description:?};
|
||||||
"
|
"
|
||||||
), format!("{crate_version} ({git_shorthash} {git_date}) {crate_feature_string}\ncommit-hash: {git_hash}\ncommit-date: {git_date}\nbuild-date: {build_date}\nrelease: {crate_version}\nfeatures: {crate_feature_list}"))
|
), format!("{crate_version} ({git_shorthash} {git_date}) {crate_feature_string}\ncommit-hash: {git_hash}\ncommit-date: {git_date}\nbuild-date: {build_date}\nrelease: {crate_version}\nfeatures: {crate_feature_list}"))
|
||||||
} else {
|
} else {
|
||||||
@ -244,6 +250,7 @@ pub fn gather_to_env_with_prefix(prefix: &str) {
|
|||||||
git_shorthash,
|
git_shorthash,
|
||||||
git_date,
|
git_date,
|
||||||
git_datetime,
|
git_datetime,
|
||||||
|
git_description,
|
||||||
..
|
..
|
||||||
}) = git
|
}) = git
|
||||||
{
|
{
|
||||||
@ -251,5 +258,6 @@ pub fn gather_to_env_with_prefix(prefix: &str) {
|
|||||||
println!("cargo:rustc-env={prefix}GIT_COMMIT_SHORTHASH={git_shorthash}");
|
println!("cargo:rustc-env={prefix}GIT_COMMIT_SHORTHASH={git_shorthash}");
|
||||||
println!("cargo:rustc-env={prefix}GIT_COMMIT_DATE={git_date}");
|
println!("cargo:rustc-env={prefix}GIT_COMMIT_DATE={git_date}");
|
||||||
println!("cargo:rustc-env={prefix}GIT_COMMIT_DATETIME={git_datetime}");
|
println!("cargo:rustc-env={prefix}GIT_COMMIT_DATETIME={git_datetime}");
|
||||||
|
println!("cargo:rustc-env={prefix}GIT_COMMIT_DESCRIPTION={git_description}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "watchexec-cli"
|
name = "watchexec-cli"
|
||||||
version = "2.0.0"
|
version = "2.1.2"
|
||||||
|
|
||||||
authors = ["Félix Saparelli <felix@passcod.name>", "Matt Green <mattgreenrocks@gmail.com>"]
|
authors = ["Félix Saparelli <felix@passcod.name>", "Matt Green <mattgreenrocks@gmail.com>"]
|
||||||
license = "Apache-2.0"
|
license = "Apache-2.0"
|
||||||
@ -29,6 +29,7 @@ clap_mangen = "0.2.15"
|
|||||||
clearscreen = "3.0.0"
|
clearscreen = "3.0.0"
|
||||||
dashmap = "5.4.0"
|
dashmap = "5.4.0"
|
||||||
dirs = "5.0.0"
|
dirs = "5.0.0"
|
||||||
|
dunce = "1.0.4"
|
||||||
futures = "0.3.29"
|
futures = "0.3.29"
|
||||||
humantime = "2.1.0"
|
humantime = "2.1.0"
|
||||||
indexmap = "2.2.6" # needs to be in sync with jaq's
|
indexmap = "2.2.6" # needs to be in sync with jaq's
|
||||||
@ -69,7 +70,7 @@ features = ["log", "env_logger"]
|
|||||||
optional = true
|
optional = true
|
||||||
|
|
||||||
[dependencies.ignore-files]
|
[dependencies.ignore-files]
|
||||||
version = "3.0.0"
|
version = "3.0.1"
|
||||||
path = "../ignore-files"
|
path = "../ignore-files"
|
||||||
|
|
||||||
[dependencies.miette]
|
[dependencies.miette]
|
||||||
@ -85,7 +86,7 @@ version = "1.4.0"
|
|||||||
path = "../project-origins"
|
path = "../project-origins"
|
||||||
|
|
||||||
[dependencies.watchexec]
|
[dependencies.watchexec]
|
||||||
version = "4.0.0"
|
version = "4.1.0"
|
||||||
path = "../lib"
|
path = "../lib"
|
||||||
|
|
||||||
[dependencies.watchexec-events]
|
[dependencies.watchexec-events]
|
||||||
@ -98,7 +99,7 @@ version = "3.0.0"
|
|||||||
path = "../signals"
|
path = "../signals"
|
||||||
|
|
||||||
[dependencies.watchexec-filterer-globset]
|
[dependencies.watchexec-filterer-globset]
|
||||||
version = "4.0.0"
|
version = "4.0.1"
|
||||||
path = "../filterer/globset"
|
path = "../filterer/globset"
|
||||||
|
|
||||||
[dependencies.tokio]
|
[dependencies.tokio]
|
||||||
@ -130,7 +131,7 @@ mimalloc = "0.1.39"
|
|||||||
embed-resource = "2.4.0"
|
embed-resource = "2.4.0"
|
||||||
|
|
||||||
[build-dependencies.bosion]
|
[build-dependencies.bosion]
|
||||||
version = "1.0.3"
|
version = "1.1.0"
|
||||||
path = "../bosion"
|
path = "../bosion"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
@ -171,7 +172,7 @@ assets = [
|
|||||||
["../../target/release/watchexec", "usr/bin/watchexec", "755"],
|
["../../target/release/watchexec", "usr/bin/watchexec", "755"],
|
||||||
["README.md", "usr/share/doc/watchexec/README", "644"],
|
["README.md", "usr/share/doc/watchexec/README", "644"],
|
||||||
["../../doc/watchexec.1.md", "usr/share/doc/watchexec/watchexec.1.md", "644"],
|
["../../doc/watchexec.1.md", "usr/share/doc/watchexec/watchexec.1.md", "644"],
|
||||||
["../../doc/watchexec.1", "usr/share/man/man1/watchexec.1.html", "644"],
|
["../../doc/watchexec.1", "usr/share/man/man1/watchexec.1", "644"],
|
||||||
["../../completions/bash", "usr/share/bash-completion/completions/watchexec", "644"],
|
["../../completions/bash", "usr/share/bash-completion/completions/watchexec", "644"],
|
||||||
["../../completions/fish", "usr/share/fish/vendor_completions.d/watchexec.fish", "644"],
|
["../../completions/fish", "usr/share/fish/vendor_completions.d/watchexec.fish", "644"],
|
||||||
["../../completions/zsh", "usr/share/zsh/site-functions/_watchexec", "644"],
|
["../../completions/zsh", "usr/share/zsh/site-functions/_watchexec", "644"],
|
||||||
@ -183,7 +184,7 @@ assets = [
|
|||||||
{ source = "../../target/release/watchexec", dest = "/usr/bin/watchexec", mode = "755" },
|
{ source = "../../target/release/watchexec", dest = "/usr/bin/watchexec", mode = "755" },
|
||||||
{ source = "README.md", dest = "/usr/share/doc/watchexec/README", mode = "644", doc = true },
|
{ source = "README.md", dest = "/usr/share/doc/watchexec/README", mode = "644", doc = true },
|
||||||
{ source = "../../doc/watchexec.1.md", dest = "/usr/share/doc/watchexec/watchexec.1.md", mode = "644", doc = true },
|
{ source = "../../doc/watchexec.1.md", dest = "/usr/share/doc/watchexec/watchexec.1.md", mode = "644", doc = true },
|
||||||
{ source = "../../doc/watchexec.1", dest = "/usr/share/man/man1/watchexec.1.html", mode = "644" },
|
{ source = "../../doc/watchexec.1", dest = "/usr/share/man/man1/watchexec.1", mode = "644" },
|
||||||
{ source = "../../completions/bash", dest = "/usr/share/bash-completion/completions/watchexec", mode = "644" },
|
{ source = "../../completions/bash", dest = "/usr/share/bash-completion/completions/watchexec", mode = "644" },
|
||||||
{ source = "../../completions/fish", dest = "/usr/share/fish/vendor_completions.d/watchexec.fish", mode = "644" },
|
{ source = "../../completions/fish", dest = "/usr/share/fish/vendor_completions.d/watchexec.fish", mode = "644" },
|
||||||
{ source = "../../completions/zsh", dest = "/usr/share/zsh/site-functions/_watchexec", mode = "644" },
|
{ source = "../../completions/zsh", dest = "/usr/share/zsh/site-functions/_watchexec", mode = "644" },
|
||||||
|
@ -1,19 +1,23 @@
|
|||||||
use std::{
|
use std::{
|
||||||
collections::BTreeSet,
|
collections::BTreeSet,
|
||||||
ffi::{OsStr, OsString},
|
ffi::{OsStr, OsString},
|
||||||
fs::canonicalize,
|
|
||||||
mem::take,
|
mem::take,
|
||||||
path::{Path, PathBuf},
|
path::{Path, PathBuf},
|
||||||
str::FromStr,
|
str::FromStr,
|
||||||
time::Duration,
|
time::Duration,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use dunce::canonicalize;
|
||||||
|
|
||||||
use clap::{
|
use clap::{
|
||||||
builder::TypedValueParser, error::ErrorKind, Arg, Command, CommandFactory, Parser, ValueEnum,
|
builder::TypedValueParser, error::ErrorKind, Arg, Command, CommandFactory, Parser, ValueEnum,
|
||||||
ValueHint,
|
ValueHint,
|
||||||
};
|
};
|
||||||
use miette::{IntoDiagnostic, Result};
|
use miette::{IntoDiagnostic, Result};
|
||||||
use tokio::{fs::File, io::AsyncReadExt};
|
use tokio::{
|
||||||
|
fs::File,
|
||||||
|
io::{AsyncBufReadExt, AsyncReadExt, BufReader},
|
||||||
|
};
|
||||||
use tracing::{debug, info, trace, warn};
|
use tracing::{debug, info, trace, warn};
|
||||||
use tracing_appender::non_blocking::WorkerGuard;
|
use tracing_appender::non_blocking::WorkerGuard;
|
||||||
use watchexec::{paths::PATH_SEPARATOR, sources::fs::WatchedPath};
|
use watchexec::{paths::PATH_SEPARATOR, sources::fs::WatchedPath};
|
||||||
@ -151,6 +155,23 @@ pub struct Args {
|
|||||||
)]
|
)]
|
||||||
pub non_recursive_paths: Vec<PathBuf>,
|
pub non_recursive_paths: Vec<PathBuf>,
|
||||||
|
|
||||||
|
/// Watch files and directories from a file
|
||||||
|
///
|
||||||
|
/// Each line in the file will be interpreted as if given to '-w'.
|
||||||
|
///
|
||||||
|
/// For more complex uses (like watching non-recursively), use the argfile capability: build a
|
||||||
|
/// file containing command-line options and pass it to watchexec with `@path/to/argfile`.
|
||||||
|
///
|
||||||
|
/// The special value '-' will read from STDIN; this in incompatible with '--stdin-quit'.
|
||||||
|
#[arg(
|
||||||
|
short = 'F',
|
||||||
|
long,
|
||||||
|
help_heading = OPTSET_FILTERING,
|
||||||
|
value_hint = ValueHint::AnyPath,
|
||||||
|
value_name = "PATH",
|
||||||
|
)]
|
||||||
|
pub watch_file: Option<PathBuf>,
|
||||||
|
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
#[arg(skip)]
|
#[arg(skip)]
|
||||||
pub paths: Vec<WatchedPath>,
|
pub paths: Vec<WatchedPath>,
|
||||||
@ -1216,6 +1237,15 @@ pub async fn get_args() -> Result<(Args, Option<WorkerGuard>)> {
|
|||||||
.exit();
|
.exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if args.stdin_quit && args.watch_file == Some(PathBuf::from("-")) {
|
||||||
|
Args::command()
|
||||||
|
.error(
|
||||||
|
ErrorKind::InvalidValue,
|
||||||
|
"stdin-quit cannot be used when --watch-file=-",
|
||||||
|
)
|
||||||
|
.exit();
|
||||||
|
}
|
||||||
|
|
||||||
let workdir = if let Some(w) = take(&mut args.workdir) {
|
let workdir = if let Some(w) = take(&mut args.workdir) {
|
||||||
w
|
w
|
||||||
} else {
|
} else {
|
||||||
@ -1233,6 +1263,22 @@ pub async fn get_args() -> Result<(Args, Option<WorkerGuard>)> {
|
|||||||
info!(path=?project_origin, "effective project origin");
|
info!(path=?project_origin, "effective project origin");
|
||||||
args.project_origin = Some(project_origin.clone());
|
args.project_origin = Some(project_origin.clone());
|
||||||
|
|
||||||
|
if let Some(watch_file) = args.watch_file.as_ref() {
|
||||||
|
if watch_file == Path::new("-") {
|
||||||
|
let file = tokio::io::stdin();
|
||||||
|
let mut lines = BufReader::new(file).lines();
|
||||||
|
while let Ok(Some(line)) = lines.next_line().await {
|
||||||
|
args.recursive_paths.push(line.into());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
let file = File::open(watch_file).await.into_diagnostic()?;
|
||||||
|
let mut lines = BufReader::new(file).lines();
|
||||||
|
while let Ok(Some(line)) = lines.next_line().await {
|
||||||
|
args.recursive_paths.push(line.into());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
args.paths = take(&mut args.recursive_paths)
|
args.paths = take(&mut args.recursive_paths)
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|path| {
|
.map(|path| {
|
||||||
@ -1243,7 +1289,7 @@ pub async fn get_args() -> Result<(Args, Option<WorkerGuard>)> {
|
|||||||
canonicalize(project_origin.join(path)).into_diagnostic()
|
canonicalize(project_origin.join(path)).into_diagnostic()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.map(WatchedPath::non_recursive)
|
.map(WatchedPath::recursive)
|
||||||
})
|
})
|
||||||
.chain(take(&mut args.non_recursive_paths).into_iter().map(|path| {
|
.chain(take(&mut args.non_recursive_paths).into_iter().map(|path| {
|
||||||
{
|
{
|
||||||
|
@ -105,6 +105,12 @@ impl WatchexecFilterer {
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let whitelist = args
|
||||||
|
.paths
|
||||||
|
.iter()
|
||||||
|
.map(|p| p.into())
|
||||||
|
.filter(|p: &PathBuf| p.is_file());
|
||||||
|
|
||||||
let mut filters = args
|
let mut filters = args
|
||||||
.filter_patterns
|
.filter_patterns
|
||||||
.iter()
|
.iter()
|
||||||
@ -128,7 +134,14 @@ impl WatchexecFilterer {
|
|||||||
|
|
||||||
info!("initialising Globset filterer");
|
info!("initialising Globset filterer");
|
||||||
Ok(Arc::new(Self {
|
Ok(Arc::new(Self {
|
||||||
inner: GlobsetFilterer::new(project_origin, filters, ignores, ignore_files, exts)
|
inner: GlobsetFilterer::new(
|
||||||
|
project_origin,
|
||||||
|
filters,
|
||||||
|
ignores,
|
||||||
|
whitelist,
|
||||||
|
ignore_files,
|
||||||
|
exts,
|
||||||
|
)
|
||||||
.await
|
.await
|
||||||
.into_diagnostic()?,
|
.into_diagnostic()?,
|
||||||
fs_events: args.filter_fs_events.clone(),
|
fs_events: args.filter_fs_events.clone(),
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
<assemblyIdentity
|
<assemblyIdentity
|
||||||
type="win32"
|
type="win32"
|
||||||
name="Watchexec.Cli.watchexec"
|
name="Watchexec.Cli.watchexec"
|
||||||
version="2.0.0.0"
|
version="2.1.2.0"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<trustInfo>
|
<trustInfo>
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
## Next (YYYY-MM-DD)
|
## Next (YYYY-MM-DD)
|
||||||
|
|
||||||
|
## v4.0.1 (2024-04-28)
|
||||||
|
|
||||||
- Hide fmt::Debug spew from ignore crate, use `full_debug` feature to restore.
|
- Hide fmt::Debug spew from ignore crate, use `full_debug` feature to restore.
|
||||||
|
|
||||||
## v4.0.0 (2024-04-20)
|
## v4.0.0 (2024-04-20)
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "watchexec-filterer-globset"
|
name = "watchexec-filterer-globset"
|
||||||
version = "4.0.0"
|
version = "4.0.1"
|
||||||
|
|
||||||
authors = ["Matt Green <mattgreenrocks@gmail.com>", "Félix Saparelli <felix@passcod.name>"]
|
authors = ["Matt Green <mattgreenrocks@gmail.com>", "Félix Saparelli <felix@passcod.name>"]
|
||||||
license = "Apache-2.0"
|
license = "Apache-2.0"
|
||||||
@ -20,11 +20,11 @@ ignore = "0.4.18"
|
|||||||
tracing = "0.1.40"
|
tracing = "0.1.40"
|
||||||
|
|
||||||
[dependencies.ignore-files]
|
[dependencies.ignore-files]
|
||||||
version = "3.0.0"
|
version = "3.0.1"
|
||||||
path = "../../ignore-files"
|
path = "../../ignore-files"
|
||||||
|
|
||||||
[dependencies.watchexec]
|
[dependencies.watchexec]
|
||||||
version = "4.0.0"
|
version = "4.1.0"
|
||||||
path = "../../lib"
|
path = "../../lib"
|
||||||
|
|
||||||
[dependencies.watchexec-events]
|
[dependencies.watchexec-events]
|
||||||
@ -32,11 +32,12 @@ version = "3.0.0"
|
|||||||
path = "../../events"
|
path = "../../events"
|
||||||
|
|
||||||
[dependencies.watchexec-filterer-ignore]
|
[dependencies.watchexec-filterer-ignore]
|
||||||
version = "4.0.0"
|
version = "4.0.1"
|
||||||
path = "../ignore"
|
path = "../ignore"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
tracing-subscriber = "0.3.6"
|
tracing-subscriber = "0.3.6"
|
||||||
|
tempfile = "3"
|
||||||
|
|
||||||
[dev-dependencies.tokio]
|
[dev-dependencies.tokio]
|
||||||
version = "1.33.0"
|
version = "1.33.0"
|
||||||
|
@ -28,6 +28,7 @@ pub struct GlobsetFilterer {
|
|||||||
origin: PathBuf,
|
origin: PathBuf,
|
||||||
filters: Gitignore,
|
filters: Gitignore,
|
||||||
ignores: Gitignore,
|
ignores: Gitignore,
|
||||||
|
whitelist: Vec<PathBuf>,
|
||||||
ignore_files: IgnoreFilterer,
|
ignore_files: IgnoreFilterer,
|
||||||
extensions: Vec<OsString>,
|
extensions: Vec<OsString>,
|
||||||
}
|
}
|
||||||
@ -51,6 +52,8 @@ impl GlobsetFilterer {
|
|||||||
/// The first list is used to filter paths (only matching paths will pass the filter), the
|
/// The first list is used to filter paths (only matching paths will pass the filter), the
|
||||||
/// second is used to ignore paths (matching paths will fail the pattern). If the filter list is
|
/// second is used to ignore paths (matching paths will fail the pattern). If the filter list is
|
||||||
/// empty, only the ignore list will be used. If both lists are empty, the filter always passes.
|
/// empty, only the ignore list will be used. If both lists are empty, the filter always passes.
|
||||||
|
/// Whitelist is used to automatically accept files even if they would be filtered out
|
||||||
|
/// otherwise. It is passed as an absolute path to the file that should not be filtered.
|
||||||
///
|
///
|
||||||
/// Ignores and filters are passed as a tuple of the glob pattern as a string and an optional
|
/// Ignores and filters are passed as a tuple of the glob pattern as a string and an optional
|
||||||
/// path of the folder the pattern should apply in (e.g. the folder a gitignore file is in).
|
/// path of the folder the pattern should apply in (e.g. the folder a gitignore file is in).
|
||||||
@ -64,6 +67,7 @@ impl GlobsetFilterer {
|
|||||||
origin: impl AsRef<Path>,
|
origin: impl AsRef<Path>,
|
||||||
filters: impl IntoIterator<Item = (String, Option<PathBuf>)>,
|
filters: impl IntoIterator<Item = (String, Option<PathBuf>)>,
|
||||||
ignores: impl IntoIterator<Item = (String, Option<PathBuf>)>,
|
ignores: impl IntoIterator<Item = (String, Option<PathBuf>)>,
|
||||||
|
whitelist: impl IntoIterator<Item = PathBuf>,
|
||||||
ignore_files: impl IntoIterator<Item = IgnoreFile>,
|
ignore_files: impl IntoIterator<Item = IgnoreFile>,
|
||||||
extensions: impl IntoIterator<Item = OsString>,
|
extensions: impl IntoIterator<Item = OsString>,
|
||||||
) -> Result<Self, Error> {
|
) -> Result<Self, Error> {
|
||||||
@ -99,6 +103,8 @@ impl GlobsetFilterer {
|
|||||||
ignore_files.finish();
|
ignore_files.finish();
|
||||||
let ignore_files = IgnoreFilterer(ignore_files);
|
let ignore_files = IgnoreFilterer(ignore_files);
|
||||||
|
|
||||||
|
let whitelist = whitelist.into_iter().collect::<Vec<_>>();
|
||||||
|
|
||||||
debug!(
|
debug!(
|
||||||
?origin,
|
?origin,
|
||||||
num_filters=%filters.num_ignores(),
|
num_filters=%filters.num_ignores(),
|
||||||
@ -113,6 +119,7 @@ impl GlobsetFilterer {
|
|||||||
origin: origin.into(),
|
origin: origin.into(),
|
||||||
filters,
|
filters,
|
||||||
ignores,
|
ignores,
|
||||||
|
whitelist,
|
||||||
ignore_files,
|
ignore_files,
|
||||||
extensions,
|
extensions,
|
||||||
})
|
})
|
||||||
@ -126,6 +133,19 @@ impl Filterer for GlobsetFilterer {
|
|||||||
fn check_event(&self, event: &Event, priority: Priority) -> Result<bool, RuntimeError> {
|
fn check_event(&self, event: &Event, priority: Priority) -> Result<bool, RuntimeError> {
|
||||||
let _span = trace_span!("filterer_check").entered();
|
let _span = trace_span!("filterer_check").entered();
|
||||||
|
|
||||||
|
{
|
||||||
|
trace!("checking internal whitelist");
|
||||||
|
// Ideally check path equality backwards for better perf
|
||||||
|
// There could be long matching prefixes so we will exit late
|
||||||
|
if event
|
||||||
|
.paths()
|
||||||
|
.any(|(p, _)| self.whitelist.iter().any(|w| w == p))
|
||||||
|
{
|
||||||
|
trace!("internal whitelist filterer matched (success)");
|
||||||
|
return Ok(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
trace!("checking internal ignore filterer");
|
trace!("checking internal ignore filterer");
|
||||||
if !self
|
if !self
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
mod helpers;
|
mod helpers;
|
||||||
use helpers::globset::*;
|
use helpers::globset::*;
|
||||||
|
use std::io::Write;
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn empty_filter_passes_everything() {
|
async fn empty_filter_passes_everything() {
|
||||||
let filterer = filt(&[], &[], &[]).await;
|
let filterer = filt(&[], &[], &[], &[], &[]).await;
|
||||||
|
|
||||||
filterer.file_does_pass("Cargo.toml");
|
filterer.file_does_pass("Cargo.toml");
|
||||||
filterer.file_does_pass("Cargo.json");
|
filterer.file_does_pass("Cargo.json");
|
||||||
@ -23,7 +24,7 @@ async fn empty_filter_passes_everything() {
|
|||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn exact_filename() {
|
async fn exact_filename() {
|
||||||
let filterer = filt(&["Cargo.toml"], &[], &[]).await;
|
let filterer = filt(&["Cargo.toml"], &[], &[], &[], &[]).await;
|
||||||
|
|
||||||
filterer.file_does_pass("Cargo.toml");
|
filterer.file_does_pass("Cargo.toml");
|
||||||
filterer.file_does_pass("/test/foo/bar/Cargo.toml");
|
filterer.file_does_pass("/test/foo/bar/Cargo.toml");
|
||||||
@ -36,7 +37,7 @@ async fn exact_filename() {
|
|||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn exact_filename_in_folder() {
|
async fn exact_filename_in_folder() {
|
||||||
let filterer = filt(&["sub/Cargo.toml"], &[], &[]).await;
|
let filterer = filt(&["sub/Cargo.toml"], &[], &[], &[], &[]).await;
|
||||||
|
|
||||||
filterer.file_doesnt_pass("Cargo.toml");
|
filterer.file_doesnt_pass("Cargo.toml");
|
||||||
filterer.file_does_pass("sub/Cargo.toml");
|
filterer.file_does_pass("sub/Cargo.toml");
|
||||||
@ -50,7 +51,7 @@ async fn exact_filename_in_folder() {
|
|||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn exact_filename_in_hidden_folder() {
|
async fn exact_filename_in_hidden_folder() {
|
||||||
let filterer = filt(&[".sub/Cargo.toml"], &[], &[]).await;
|
let filterer = filt(&[".sub/Cargo.toml"], &[], &[], &[], &[]).await;
|
||||||
|
|
||||||
filterer.file_doesnt_pass("Cargo.toml");
|
filterer.file_doesnt_pass("Cargo.toml");
|
||||||
filterer.file_does_pass(".sub/Cargo.toml");
|
filterer.file_does_pass(".sub/Cargo.toml");
|
||||||
@ -64,7 +65,7 @@ async fn exact_filename_in_hidden_folder() {
|
|||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn exact_filenames_multiple() {
|
async fn exact_filenames_multiple() {
|
||||||
let filterer = filt(&["Cargo.toml", "package.json"], &[], &[]).await;
|
let filterer = filt(&["Cargo.toml", "package.json"], &[], &[], &[], &[]).await;
|
||||||
|
|
||||||
filterer.file_does_pass("Cargo.toml");
|
filterer.file_does_pass("Cargo.toml");
|
||||||
filterer.file_does_pass("/test/foo/bar/Cargo.toml");
|
filterer.file_does_pass("/test/foo/bar/Cargo.toml");
|
||||||
@ -81,7 +82,7 @@ async fn exact_filenames_multiple() {
|
|||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn glob_single_final_ext_star() {
|
async fn glob_single_final_ext_star() {
|
||||||
let filterer = filt(&["Cargo.*"], &[], &[]).await;
|
let filterer = filt(&["Cargo.*"], &[], &[], &[], &[]).await;
|
||||||
|
|
||||||
filterer.file_does_pass("Cargo.toml");
|
filterer.file_does_pass("Cargo.toml");
|
||||||
filterer.file_does_pass("Cargo.json");
|
filterer.file_does_pass("Cargo.json");
|
||||||
@ -93,7 +94,7 @@ async fn glob_single_final_ext_star() {
|
|||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn glob_star_trailing_slash() {
|
async fn glob_star_trailing_slash() {
|
||||||
let filterer = filt(&["Cargo.*/"], &[], &[]).await;
|
let filterer = filt(&["Cargo.*/"], &[], &[], &[], &[]).await;
|
||||||
|
|
||||||
filterer.file_doesnt_pass("Cargo.toml");
|
filterer.file_doesnt_pass("Cargo.toml");
|
||||||
filterer.file_doesnt_pass("Cargo.json");
|
filterer.file_doesnt_pass("Cargo.json");
|
||||||
@ -106,7 +107,7 @@ async fn glob_star_trailing_slash() {
|
|||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn glob_star_leading_slash() {
|
async fn glob_star_leading_slash() {
|
||||||
let filterer = filt(&["/Cargo.*"], &[], &[]).await;
|
let filterer = filt(&["/Cargo.*"], &[], &[], &[], &[]).await;
|
||||||
|
|
||||||
filterer.file_does_pass("Cargo.toml");
|
filterer.file_does_pass("Cargo.toml");
|
||||||
filterer.file_does_pass("Cargo.json");
|
filterer.file_does_pass("Cargo.json");
|
||||||
@ -118,7 +119,7 @@ async fn glob_star_leading_slash() {
|
|||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn glob_leading_double_star() {
|
async fn glob_leading_double_star() {
|
||||||
let filterer = filt(&["**/possum"], &[], &[]).await;
|
let filterer = filt(&["**/possum"], &[], &[], &[], &[]).await;
|
||||||
|
|
||||||
filterer.file_does_pass("possum");
|
filterer.file_does_pass("possum");
|
||||||
filterer.file_does_pass("foo/bar/possum");
|
filterer.file_does_pass("foo/bar/possum");
|
||||||
@ -133,7 +134,7 @@ async fn glob_leading_double_star() {
|
|||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn glob_trailing_double_star() {
|
async fn glob_trailing_double_star() {
|
||||||
let filterer = filt(&["possum/**"], &[], &[]).await;
|
let filterer = filt(&["possum/**"], &[], &[], &[], &[]).await;
|
||||||
|
|
||||||
// these do work by expectation and in v1
|
// these do work by expectation and in v1
|
||||||
filterer.file_does_pass("/test/possum/foo/bar");
|
filterer.file_does_pass("/test/possum/foo/bar");
|
||||||
@ -147,7 +148,7 @@ async fn glob_trailing_double_star() {
|
|||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn glob_middle_double_star() {
|
async fn glob_middle_double_star() {
|
||||||
let filterer = filt(&["apples/**/oranges"], &[], &[]).await;
|
let filterer = filt(&["apples/**/oranges"], &[], &[], &[], &[]).await;
|
||||||
|
|
||||||
filterer.dir_doesnt_pass("/a/folder");
|
filterer.dir_doesnt_pass("/a/folder");
|
||||||
filterer.file_does_pass("apples/carrots/oranges");
|
filterer.file_does_pass("apples/carrots/oranges");
|
||||||
@ -162,7 +163,7 @@ async fn glob_middle_double_star() {
|
|||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn glob_double_star_trailing_slash() {
|
async fn glob_double_star_trailing_slash() {
|
||||||
let filterer = filt(&["apples/**/oranges/"], &[], &[]).await;
|
let filterer = filt(&["apples/**/oranges/"], &[], &[], &[], &[]).await;
|
||||||
|
|
||||||
filterer.dir_doesnt_pass("/a/folder");
|
filterer.dir_doesnt_pass("/a/folder");
|
||||||
filterer.file_doesnt_pass("apples/carrots/oranges");
|
filterer.file_doesnt_pass("apples/carrots/oranges");
|
||||||
@ -180,7 +181,7 @@ async fn glob_double_star_trailing_slash() {
|
|||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn ignore_exact_filename() {
|
async fn ignore_exact_filename() {
|
||||||
let filterer = filt(&[], &["Cargo.toml"], &[]).await;
|
let filterer = filt(&[], &["Cargo.toml"], &[], &[], &[]).await;
|
||||||
|
|
||||||
filterer.file_doesnt_pass("Cargo.toml");
|
filterer.file_doesnt_pass("Cargo.toml");
|
||||||
filterer.file_doesnt_pass("/test/foo/bar/Cargo.toml");
|
filterer.file_doesnt_pass("/test/foo/bar/Cargo.toml");
|
||||||
@ -193,7 +194,7 @@ async fn ignore_exact_filename() {
|
|||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn ignore_exact_filename_in_folder() {
|
async fn ignore_exact_filename_in_folder() {
|
||||||
let filterer = filt(&[], &["sub/Cargo.toml"], &[]).await;
|
let filterer = filt(&[], &["sub/Cargo.toml"], &[], &[], &[]).await;
|
||||||
|
|
||||||
filterer.file_does_pass("Cargo.toml");
|
filterer.file_does_pass("Cargo.toml");
|
||||||
filterer.file_doesnt_pass("sub/Cargo.toml");
|
filterer.file_doesnt_pass("sub/Cargo.toml");
|
||||||
@ -207,7 +208,7 @@ async fn ignore_exact_filename_in_folder() {
|
|||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn ignore_exact_filename_in_hidden_folder() {
|
async fn ignore_exact_filename_in_hidden_folder() {
|
||||||
let filterer = filt(&[], &[".sub/Cargo.toml"], &[]).await;
|
let filterer = filt(&[], &[".sub/Cargo.toml"], &[], &[], &[]).await;
|
||||||
|
|
||||||
filterer.file_does_pass("Cargo.toml");
|
filterer.file_does_pass("Cargo.toml");
|
||||||
filterer.file_doesnt_pass(".sub/Cargo.toml");
|
filterer.file_doesnt_pass(".sub/Cargo.toml");
|
||||||
@ -221,7 +222,7 @@ async fn ignore_exact_filename_in_hidden_folder() {
|
|||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn ignore_exact_filenames_multiple() {
|
async fn ignore_exact_filenames_multiple() {
|
||||||
let filterer = filt(&[], &["Cargo.toml", "package.json"], &[]).await;
|
let filterer = filt(&[], &["Cargo.toml", "package.json"], &[], &[], &[]).await;
|
||||||
|
|
||||||
filterer.file_doesnt_pass("Cargo.toml");
|
filterer.file_doesnt_pass("Cargo.toml");
|
||||||
filterer.file_doesnt_pass("/test/foo/bar/Cargo.toml");
|
filterer.file_doesnt_pass("/test/foo/bar/Cargo.toml");
|
||||||
@ -238,7 +239,7 @@ async fn ignore_exact_filenames_multiple() {
|
|||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn ignore_glob_single_final_ext_star() {
|
async fn ignore_glob_single_final_ext_star() {
|
||||||
let filterer = filt(&[], &["Cargo.*"], &[]).await;
|
let filterer = filt(&[], &["Cargo.*"], &[], &[], &[]).await;
|
||||||
|
|
||||||
filterer.file_doesnt_pass("Cargo.toml");
|
filterer.file_doesnt_pass("Cargo.toml");
|
||||||
filterer.file_doesnt_pass("Cargo.json");
|
filterer.file_doesnt_pass("Cargo.json");
|
||||||
@ -250,7 +251,7 @@ async fn ignore_glob_single_final_ext_star() {
|
|||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn ignore_glob_star_trailing_slash() {
|
async fn ignore_glob_star_trailing_slash() {
|
||||||
let filterer = filt(&[], &["Cargo.*/"], &[]).await;
|
let filterer = filt(&[], &["Cargo.*/"], &[], &[], &[]).await;
|
||||||
|
|
||||||
filterer.file_does_pass("Cargo.toml");
|
filterer.file_does_pass("Cargo.toml");
|
||||||
filterer.file_does_pass("Cargo.json");
|
filterer.file_does_pass("Cargo.json");
|
||||||
@ -263,7 +264,7 @@ async fn ignore_glob_star_trailing_slash() {
|
|||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn ignore_glob_star_leading_slash() {
|
async fn ignore_glob_star_leading_slash() {
|
||||||
let filterer = filt(&[], &["/Cargo.*"], &[]).await;
|
let filterer = filt(&[], &["/Cargo.*"], &[], &[], &[]).await;
|
||||||
|
|
||||||
filterer.file_doesnt_pass("Cargo.toml");
|
filterer.file_doesnt_pass("Cargo.toml");
|
||||||
filterer.file_doesnt_pass("Cargo.json");
|
filterer.file_doesnt_pass("Cargo.json");
|
||||||
@ -275,7 +276,7 @@ async fn ignore_glob_star_leading_slash() {
|
|||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn ignore_glob_leading_double_star() {
|
async fn ignore_glob_leading_double_star() {
|
||||||
let filterer = filt(&[], &["**/possum"], &[]).await;
|
let filterer = filt(&[], &["**/possum"], &[], &[], &[]).await;
|
||||||
|
|
||||||
filterer.file_doesnt_pass("possum");
|
filterer.file_doesnt_pass("possum");
|
||||||
filterer.file_doesnt_pass("foo/bar/possum");
|
filterer.file_doesnt_pass("foo/bar/possum");
|
||||||
@ -290,7 +291,7 @@ async fn ignore_glob_leading_double_star() {
|
|||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn ignore_glob_trailing_double_star() {
|
async fn ignore_glob_trailing_double_star() {
|
||||||
let filterer = filt(&[], &["possum/**"], &[]).await;
|
let filterer = filt(&[], &["possum/**"], &[], &[], &[]).await;
|
||||||
|
|
||||||
filterer.file_does_pass("possum");
|
filterer.file_does_pass("possum");
|
||||||
filterer.file_doesnt_pass("possum/foo/bar");
|
filterer.file_doesnt_pass("possum/foo/bar");
|
||||||
@ -309,7 +310,7 @@ async fn ignore_glob_trailing_double_star() {
|
|||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn ignore_glob_middle_double_star() {
|
async fn ignore_glob_middle_double_star() {
|
||||||
let filterer = filt(&[], &["apples/**/oranges"], &[]).await;
|
let filterer = filt(&[], &["apples/**/oranges"], &[], &[], &[]).await;
|
||||||
|
|
||||||
filterer.dir_does_pass("/a/folder");
|
filterer.dir_does_pass("/a/folder");
|
||||||
filterer.file_doesnt_pass("apples/carrots/oranges");
|
filterer.file_doesnt_pass("apples/carrots/oranges");
|
||||||
@ -324,7 +325,7 @@ async fn ignore_glob_middle_double_star() {
|
|||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn ignore_glob_double_star_trailing_slash() {
|
async fn ignore_glob_double_star_trailing_slash() {
|
||||||
let filterer = filt(&[], &["apples/**/oranges/"], &[]).await;
|
let filterer = filt(&[], &["apples/**/oranges/"], &[], &[], &[]).await;
|
||||||
|
|
||||||
filterer.dir_does_pass("/a/folder");
|
filterer.dir_does_pass("/a/folder");
|
||||||
filterer.file_does_pass("apples/carrots/oranges");
|
filterer.file_does_pass("apples/carrots/oranges");
|
||||||
@ -342,7 +343,14 @@ async fn ignore_glob_double_star_trailing_slash() {
|
|||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn ignores_take_precedence() {
|
async fn ignores_take_precedence() {
|
||||||
let filterer = filt(&["*.docx", "*.toml", "*.json"], &["*.toml", "*.json"], &[]).await;
|
let filterer = filt(
|
||||||
|
&["*.docx", "*.toml", "*.json"],
|
||||||
|
&["*.toml", "*.json"],
|
||||||
|
&[],
|
||||||
|
&[],
|
||||||
|
&[],
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
|
||||||
filterer.file_doesnt_pass("Cargo.toml");
|
filterer.file_doesnt_pass("Cargo.toml");
|
||||||
filterer.file_doesnt_pass("/test/foo/bar/Cargo.toml");
|
filterer.file_doesnt_pass("/test/foo/bar/Cargo.toml");
|
||||||
@ -355,7 +363,7 @@ async fn ignores_take_precedence() {
|
|||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn extensions_fail_dirs() {
|
async fn extensions_fail_dirs() {
|
||||||
let filterer = filt(&[], &[], &["py"]).await;
|
let filterer = filt(&[], &[], &[], &["py"], &[]).await;
|
||||||
|
|
||||||
filterer.file_does_pass("Cargo.py");
|
filterer.file_does_pass("Cargo.py");
|
||||||
filterer.file_doesnt_pass("Cargo.toml");
|
filterer.file_doesnt_pass("Cargo.toml");
|
||||||
@ -366,7 +374,7 @@ async fn extensions_fail_dirs() {
|
|||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn extensions_fail_extensionless() {
|
async fn extensions_fail_extensionless() {
|
||||||
let filterer = filt(&[], &[], &["py"]).await;
|
let filterer = filt(&[], &[], &[], &["py"], &[]).await;
|
||||||
|
|
||||||
filterer.file_does_pass("Cargo.py");
|
filterer.file_does_pass("Cargo.py");
|
||||||
filterer.file_doesnt_pass("Cargo");
|
filterer.file_doesnt_pass("Cargo");
|
||||||
@ -377,7 +385,7 @@ async fn multipath_allow_on_any_one_pass() {
|
|||||||
use watchexec::filter::Filterer;
|
use watchexec::filter::Filterer;
|
||||||
use watchexec_events::{Event, FileType, Tag};
|
use watchexec_events::{Event, FileType, Tag};
|
||||||
|
|
||||||
let filterer = filt(&[], &[], &["py"]).await;
|
let filterer = filt(&[], &[], &[], &["py"], &[]).await;
|
||||||
let origin = tokio::fs::canonicalize(".").await.unwrap();
|
let origin = tokio::fs::canonicalize(".").await.unwrap();
|
||||||
|
|
||||||
let event = Event {
|
let event = Event {
|
||||||
@ -403,7 +411,7 @@ async fn multipath_allow_on_any_one_pass() {
|
|||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn extensions_and_filters_glob() {
|
async fn extensions_and_filters_glob() {
|
||||||
let filterer = filt(&["*/justfile"], &[], &["md", "css"]).await;
|
let filterer = filt(&["*/justfile"], &[], &[], &["md", "css"], &[]).await;
|
||||||
|
|
||||||
filterer.file_does_pass("foo/justfile");
|
filterer.file_does_pass("foo/justfile");
|
||||||
filterer.file_does_pass("bar.md");
|
filterer.file_does_pass("bar.md");
|
||||||
@ -417,7 +425,7 @@ async fn extensions_and_filters_glob() {
|
|||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn extensions_and_filters_slash() {
|
async fn extensions_and_filters_slash() {
|
||||||
let filterer = filt(&["/justfile"], &[], &["md", "css"]).await;
|
let filterer = filt(&["/justfile"], &[], &[], &["md", "css"], &[]).await;
|
||||||
|
|
||||||
filterer.file_does_pass("justfile");
|
filterer.file_does_pass("justfile");
|
||||||
filterer.file_does_pass("bar.md");
|
filterer.file_does_pass("bar.md");
|
||||||
@ -427,7 +435,7 @@ async fn extensions_and_filters_slash() {
|
|||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn leading_single_glob_file() {
|
async fn leading_single_glob_file() {
|
||||||
let filterer = filt(&["*/justfile"], &[], &[]).await;
|
let filterer = filt(&["*/justfile"], &[], &[], &[], &[]).await;
|
||||||
|
|
||||||
filterer.file_does_pass("foo/justfile");
|
filterer.file_does_pass("foo/justfile");
|
||||||
filterer.file_doesnt_pass("notfile");
|
filterer.file_doesnt_pass("notfile");
|
||||||
@ -443,7 +451,7 @@ async fn nonpath_event_passes() {
|
|||||||
use watchexec::filter::Filterer;
|
use watchexec::filter::Filterer;
|
||||||
use watchexec_events::{Event, Source, Tag};
|
use watchexec_events::{Event, Source, Tag};
|
||||||
|
|
||||||
let filterer = filt(&[], &[], &["py"]).await;
|
let filterer = filt(&[], &[], &[], &["py"], &[]).await;
|
||||||
|
|
||||||
assert!(filterer
|
assert!(filterer
|
||||||
.check_event(
|
.check_event(
|
||||||
@ -470,7 +478,7 @@ async fn nonpath_event_passes() {
|
|||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn ignore_folder_incorrectly_with_bare_match() {
|
async fn ignore_folder_incorrectly_with_bare_match() {
|
||||||
let filterer = filt(&[], &["prunes"], &[]).await;
|
let filterer = filt(&[], &["prunes"], &[], &[], &[]).await;
|
||||||
|
|
||||||
filterer.file_does_pass("apples");
|
filterer.file_does_pass("apples");
|
||||||
filterer.file_does_pass("apples/carrots/cauliflowers/oranges");
|
filterer.file_does_pass("apples/carrots/cauliflowers/oranges");
|
||||||
@ -501,7 +509,7 @@ async fn ignore_folder_incorrectly_with_bare_match() {
|
|||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn ignore_folder_incorrectly_with_bare_and_leading_slash() {
|
async fn ignore_folder_incorrectly_with_bare_and_leading_slash() {
|
||||||
let filterer = filt(&[], &["/prunes"], &[]).await;
|
let filterer = filt(&[], &["/prunes"], &[], &[], &[]).await;
|
||||||
|
|
||||||
filterer.file_does_pass("apples");
|
filterer.file_does_pass("apples");
|
||||||
filterer.file_does_pass("apples/carrots/cauliflowers/oranges");
|
filterer.file_does_pass("apples/carrots/cauliflowers/oranges");
|
||||||
@ -532,7 +540,7 @@ async fn ignore_folder_incorrectly_with_bare_and_leading_slash() {
|
|||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn ignore_folder_incorrectly_with_bare_and_trailing_slash() {
|
async fn ignore_folder_incorrectly_with_bare_and_trailing_slash() {
|
||||||
let filterer = filt(&[], &["prunes/"], &[]).await;
|
let filterer = filt(&[], &["prunes/"], &[], &[], &[]).await;
|
||||||
|
|
||||||
filterer.file_does_pass("apples");
|
filterer.file_does_pass("apples");
|
||||||
filterer.file_does_pass("apples/carrots/cauliflowers/oranges");
|
filterer.file_does_pass("apples/carrots/cauliflowers/oranges");
|
||||||
@ -563,7 +571,7 @@ async fn ignore_folder_incorrectly_with_bare_and_trailing_slash() {
|
|||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn ignore_folder_incorrectly_with_only_double_double_glob() {
|
async fn ignore_folder_incorrectly_with_only_double_double_glob() {
|
||||||
let filterer = filt(&[], &["**/prunes/**"], &[]).await;
|
let filterer = filt(&[], &["**/prunes/**"], &[], &[], &[]).await;
|
||||||
|
|
||||||
filterer.file_does_pass("apples");
|
filterer.file_does_pass("apples");
|
||||||
filterer.file_does_pass("apples/carrots/cauliflowers/oranges");
|
filterer.file_does_pass("apples/carrots/cauliflowers/oranges");
|
||||||
@ -594,7 +602,7 @@ async fn ignore_folder_incorrectly_with_only_double_double_glob() {
|
|||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn ignore_folder_correctly_with_double_and_double_double_globs() {
|
async fn ignore_folder_correctly_with_double_and_double_double_globs() {
|
||||||
let filterer = filt(&[], &["**/prunes", "**/prunes/**"], &[]).await;
|
let filterer = filt(&[], &["**/prunes", "**/prunes/**"], &[], &[], &[]).await;
|
||||||
|
|
||||||
filterer.file_does_pass("apples");
|
filterer.file_does_pass("apples");
|
||||||
filterer.file_does_pass("apples/carrots/cauliflowers/oranges");
|
filterer.file_does_pass("apples/carrots/cauliflowers/oranges");
|
||||||
@ -620,3 +628,94 @@ async fn ignore_folder_correctly_with_double_and_double_double_globs() {
|
|||||||
filterer.dir_doesnt_pass("prunes/carrots/cauliflowers/oranges");
|
filterer.dir_doesnt_pass("prunes/carrots/cauliflowers/oranges");
|
||||||
filterer.dir_doesnt_pass("prunes/carrots/cauliflowers/artichokes/oranges");
|
filterer.dir_doesnt_pass("prunes/carrots/cauliflowers/artichokes/oranges");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn whitelist_overrides_ignore() {
|
||||||
|
let filterer = filt(&[], &["**/prunes"], &["/prunes"], &[], &[]).await;
|
||||||
|
|
||||||
|
filterer.file_does_pass("apples");
|
||||||
|
filterer.file_does_pass("/prunes");
|
||||||
|
filterer.dir_does_pass("apples");
|
||||||
|
filterer.dir_does_pass("/prunes");
|
||||||
|
|
||||||
|
filterer.file_does_pass("raw-prunes");
|
||||||
|
filterer.dir_does_pass("raw-prunes");
|
||||||
|
|
||||||
|
filterer.file_doesnt_pass("apples/prunes");
|
||||||
|
filterer.file_doesnt_pass("raw/prunes");
|
||||||
|
filterer.dir_doesnt_pass("apples/prunes");
|
||||||
|
filterer.dir_doesnt_pass("raw/prunes");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn whitelist_overrides_ignore_files() {
|
||||||
|
let mut ignore_file = tempfile::NamedTempFile::new().unwrap();
|
||||||
|
let _ = ignore_file.write(b"prunes");
|
||||||
|
|
||||||
|
let origin = std::fs::canonicalize(".").unwrap();
|
||||||
|
let whitelist = origin.join("prunes").display().to_string();
|
||||||
|
|
||||||
|
let filterer = filt(
|
||||||
|
&[],
|
||||||
|
&[],
|
||||||
|
&[&whitelist],
|
||||||
|
&[],
|
||||||
|
&[ignore_file.path().to_path_buf()],
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
|
||||||
|
filterer.file_does_pass("apples");
|
||||||
|
filterer.file_does_pass("prunes");
|
||||||
|
filterer.dir_does_pass("apples");
|
||||||
|
filterer.dir_does_pass("prunes");
|
||||||
|
|
||||||
|
filterer.file_does_pass("raw-prunes");
|
||||||
|
filterer.dir_does_pass("raw-prunes");
|
||||||
|
|
||||||
|
filterer.file_doesnt_pass("apples/prunes");
|
||||||
|
filterer.file_doesnt_pass("raw/prunes");
|
||||||
|
filterer.dir_doesnt_pass("apples/prunes");
|
||||||
|
filterer.dir_doesnt_pass("raw/prunes");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn whitelist_overrides_ignore_files_nested() {
|
||||||
|
let mut ignore_file = tempfile::NamedTempFile::new().unwrap();
|
||||||
|
let _ = ignore_file.write(b"prunes\n");
|
||||||
|
|
||||||
|
let origin = std::fs::canonicalize(".").unwrap();
|
||||||
|
let whitelist = origin.join("prunes").join("target").display().to_string();
|
||||||
|
|
||||||
|
let filterer = filt(
|
||||||
|
&[],
|
||||||
|
&[],
|
||||||
|
&[&whitelist],
|
||||||
|
&[],
|
||||||
|
&[ignore_file.path().to_path_buf()],
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
|
||||||
|
filterer.file_does_pass("apples");
|
||||||
|
filterer.file_doesnt_pass("prunes");
|
||||||
|
filterer.dir_does_pass("apples");
|
||||||
|
filterer.dir_doesnt_pass("prunes");
|
||||||
|
|
||||||
|
filterer.file_does_pass("raw-prunes");
|
||||||
|
filterer.dir_does_pass("raw-prunes");
|
||||||
|
|
||||||
|
filterer.file_doesnt_pass("prunes/apples");
|
||||||
|
filterer.file_doesnt_pass("prunes/raw");
|
||||||
|
filterer.dir_doesnt_pass("prunes/apples");
|
||||||
|
filterer.dir_doesnt_pass("prunes/raw");
|
||||||
|
|
||||||
|
filterer.file_doesnt_pass("apples/prunes");
|
||||||
|
filterer.file_doesnt_pass("raw/prunes");
|
||||||
|
filterer.dir_doesnt_pass("apples/prunes");
|
||||||
|
filterer.dir_doesnt_pass("raw/prunes");
|
||||||
|
|
||||||
|
filterer.file_does_pass("prunes/target");
|
||||||
|
filterer.dir_does_pass("prunes/target");
|
||||||
|
|
||||||
|
filterer.file_doesnt_pass("prunes/nested/target");
|
||||||
|
filterer.dir_doesnt_pass("prunes/nested/target");
|
||||||
|
}
|
||||||
|
@ -3,6 +3,7 @@ use std::{
|
|||||||
path::{Path, PathBuf},
|
path::{Path, PathBuf},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use ignore_files::IgnoreFile;
|
||||||
use watchexec::{error::RuntimeError, filter::Filterer};
|
use watchexec::{error::RuntimeError, filter::Filterer};
|
||||||
use watchexec_events::{Event, FileType, Priority, Tag};
|
use watchexec_events::{Event, FileType, Priority, Tag};
|
||||||
use watchexec_filterer_globset::GlobsetFilterer;
|
use watchexec_filterer_globset::GlobsetFilterer;
|
||||||
@ -102,7 +103,9 @@ fn tracing_init() {
|
|||||||
pub async fn globset_filt(
|
pub async fn globset_filt(
|
||||||
filters: &[&str],
|
filters: &[&str],
|
||||||
ignores: &[&str],
|
ignores: &[&str],
|
||||||
|
whitelists: &[&str],
|
||||||
extensions: &[&str],
|
extensions: &[&str],
|
||||||
|
ignore_files: &[PathBuf],
|
||||||
) -> GlobsetFilterer {
|
) -> GlobsetFilterer {
|
||||||
let origin = tokio::fs::canonicalize(".").await.unwrap();
|
let origin = tokio::fs::canonicalize(".").await.unwrap();
|
||||||
tracing_init();
|
tracing_init();
|
||||||
@ -110,7 +113,12 @@ pub async fn globset_filt(
|
|||||||
origin,
|
origin,
|
||||||
filters.iter().map(|s| ((*s).to_string(), None)),
|
filters.iter().map(|s| ((*s).to_string(), None)),
|
||||||
ignores.iter().map(|s| ((*s).to_string(), None)),
|
ignores.iter().map(|s| ((*s).to_string(), None)),
|
||||||
vec![],
|
whitelists.iter().map(|s| (*s).into()),
|
||||||
|
ignore_files.iter().map(|path| IgnoreFile {
|
||||||
|
path: path.clone(),
|
||||||
|
applies_in: None,
|
||||||
|
applies_to: None,
|
||||||
|
}),
|
||||||
extensions.iter().map(OsString::from),
|
extensions.iter().map(OsString::from),
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
## Next (YYYY-MM-DD)
|
## Next (YYYY-MM-DD)
|
||||||
|
|
||||||
|
## v4.0.1 (2024-04-28)
|
||||||
|
|
||||||
## v4.0.0 (2024-04-20)
|
## v4.0.0 (2024-04-20)
|
||||||
|
|
||||||
- Deps: watchexec 4
|
- Deps: watchexec 4
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "watchexec-filterer-ignore"
|
name = "watchexec-filterer-ignore"
|
||||||
version = "4.0.0"
|
version = "4.0.1"
|
||||||
|
|
||||||
authors = ["Félix Saparelli <felix@passcod.name>"]
|
authors = ["Félix Saparelli <felix@passcod.name>"]
|
||||||
license = "Apache-2.0"
|
license = "Apache-2.0"
|
||||||
@ -22,11 +22,11 @@ normalize-path = "0.2.1"
|
|||||||
tracing = "0.1.40"
|
tracing = "0.1.40"
|
||||||
|
|
||||||
[dependencies.ignore-files]
|
[dependencies.ignore-files]
|
||||||
version = "3.0.0"
|
version = "3.0.1"
|
||||||
path = "../../ignore-files"
|
path = "../../ignore-files"
|
||||||
|
|
||||||
[dependencies.watchexec]
|
[dependencies.watchexec]
|
||||||
version = "4.0.0"
|
version = "4.1.0"
|
||||||
path = "../../lib"
|
path = "../../lib"
|
||||||
|
|
||||||
[dependencies.watchexec-events]
|
[dependencies.watchexec-events]
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
## Next (YYYY-MM-DD)
|
## Next (YYYY-MM-DD)
|
||||||
|
|
||||||
|
## v3.0.1 (2024-04-28)
|
||||||
|
|
||||||
- Hide fmt::Debug spew from ignore crate, use `full_debug` feature to restore.
|
- Hide fmt::Debug spew from ignore crate, use `full_debug` feature to restore.
|
||||||
|
|
||||||
## v3.0.0 (2024-04-20)
|
## v3.0.0 (2024-04-20)
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "ignore-files"
|
name = "ignore-files"
|
||||||
version = "3.0.0"
|
version = "3.0.1"
|
||||||
|
|
||||||
authors = ["Félix Saparelli <felix@passcod.name>"]
|
authors = ["Félix Saparelli <felix@passcod.name>"]
|
||||||
license = "Apache-2.0"
|
license = "Apache-2.0"
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
## Next (YYYY-MM-DD)
|
## Next (YYYY-MM-DD)
|
||||||
|
|
||||||
|
## v4.1.0 (2024-04-28)
|
||||||
|
|
||||||
- Feature: non-recursive watches with `WatchedPath::non_recursive()`
|
- Feature: non-recursive watches with `WatchedPath::non_recursive()`
|
||||||
- Fix: `config.pathset()` now preserves `WatchedPath` attributes
|
- Fix: `config.pathset()` now preserves `WatchedPath` attributes
|
||||||
- Refactor: move `WatchedPath` to the root of the crate (old path remains as re-export for now)
|
- Refactor: move `WatchedPath` to the root of the crate (old path remains as re-export for now)
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "watchexec"
|
name = "watchexec"
|
||||||
version = "4.0.0"
|
version = "4.1.0"
|
||||||
|
|
||||||
authors = ["Félix Saparelli <felix@passcod.name>", "Matt Green <mattgreenrocks@gmail.com>"]
|
authors = ["Félix Saparelli <felix@passcod.name>", "Matt Green <mattgreenrocks@gmail.com>"]
|
||||||
license = "Apache-2.0"
|
license = "Apache-2.0"
|
||||||
@ -43,7 +43,7 @@ version = "2.0.0"
|
|||||||
path = "../supervisor"
|
path = "../supervisor"
|
||||||
|
|
||||||
[dependencies.ignore-files]
|
[dependencies.ignore-files]
|
||||||
version = "3.0.0"
|
version = "3.0.1"
|
||||||
path = "../ignore-files"
|
path = "../ignore-files"
|
||||||
|
|
||||||
[dependencies.project-origins]
|
[dependencies.project-origins]
|
||||||
|
@ -74,8 +74,8 @@ mod watchexec;
|
|||||||
#[doc(inline)]
|
#[doc(inline)]
|
||||||
pub use crate::{
|
pub use crate::{
|
||||||
id::Id,
|
id::Id,
|
||||||
watchexec::{ErrorHook, Watchexec},
|
|
||||||
watched_path::WatchedPath,
|
watched_path::WatchedPath,
|
||||||
|
watchexec::{ErrorHook, Watchexec},
|
||||||
};
|
};
|
||||||
|
|
||||||
#[doc(no_inline)]
|
#[doc(no_inline)]
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
.ie \n(.g .ds Aq \(aq
|
.ie \n(.g .ds Aq \(aq
|
||||||
.el .ds Aq '
|
.el .ds Aq '
|
||||||
.TH watchexec 1 "watchexec 2.0.0"
|
.TH watchexec 1 "watchexec 2.1.2"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
watchexec \- Execute commands when watched files change
|
watchexec \- Execute commands when watched files change
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
\fBwatchexec\fR [\fB\-w\fR|\fB\-\-watch\fR] [\fB\-W\fR|\fB\-\-watch\-non\-recursive\fR] [\fB\-c\fR|\fB\-\-clear\fR] [\fB\-o\fR|\fB\-\-on\-busy\-update\fR] [\fB\-r\fR|\fB\-\-restart\fR] [\fB\-s\fR|\fB\-\-signal\fR] [\fB\-\-stop\-signal\fR] [\fB\-\-stop\-timeout\fR] [\fB\-\-map\-signal\fR] [\fB\-d\fR|\fB\-\-debounce\fR] [\fB\-\-stdin\-quit\fR] [\fB\-\-no\-vcs\-ignore\fR] [\fB\-\-no\-project\-ignore\fR] [\fB\-\-no\-global\-ignore\fR] [\fB\-\-no\-default\-ignore\fR] [\fB\-\-no\-discover\-ignore\fR] [\fB\-\-ignore\-nothing\fR] [\fB\-p\fR|\fB\-\-postpone\fR] [\fB\-\-delay\-run\fR] [\fB\-\-poll\fR] [\fB\-\-shell\fR] [\fB\-n \fR] [\fB\-\-emit\-events\-to\fR] [\fB\-\-only\-emit\-events\fR] [\fB\-E\fR|\fB\-\-env\fR] [\fB\-\-no\-process\-group\fR] [\fB\-\-wrap\-process\fR] [\fB\-N\fR|\fB\-\-notify\fR] [\fB\-\-color\fR] [\fB\-\-timings\fR] [\fB\-q\fR|\fB\-\-quiet\fR] [\fB\-\-bell\fR] [\fB\-\-project\-origin\fR] [\fB\-\-workdir\fR] [\fB\-e\fR|\fB\-\-exts\fR] [\fB\-f\fR|\fB\-\-filter\fR] [\fB\-\-filter\-file\fR] [\fB\-j\fR|\fB\-\-filter\-prog\fR] [\fB\-i\fR|\fB\-\-ignore\fR] [\fB\-\-ignore\-file\fR] [\fB\-\-fs\-events\fR] [\fB\-\-no\-meta\fR] [\fB\-\-print\-events\fR] [\fB\-\-manual\fR] [\fB\-\-completions\fR] [\fB\-v\fR|\fB\-\-verbose\fR]... [\fB\-\-log\-file\fR] [\fB\-h\fR|\fB\-\-help\fR] [\fB\-V\fR|\fB\-\-version\fR] [\fICOMMAND\fR]
|
\fBwatchexec\fR [\fB\-w\fR|\fB\-\-watch\fR] [\fB\-W\fR|\fB\-\-watch\-non\-recursive\fR] [\fB\-F\fR|\fB\-\-watch\-file\fR] [\fB\-c\fR|\fB\-\-clear\fR] [\fB\-o\fR|\fB\-\-on\-busy\-update\fR] [\fB\-r\fR|\fB\-\-restart\fR] [\fB\-s\fR|\fB\-\-signal\fR] [\fB\-\-stop\-signal\fR] [\fB\-\-stop\-timeout\fR] [\fB\-\-map\-signal\fR] [\fB\-d\fR|\fB\-\-debounce\fR] [\fB\-\-stdin\-quit\fR] [\fB\-\-no\-vcs\-ignore\fR] [\fB\-\-no\-project\-ignore\fR] [\fB\-\-no\-global\-ignore\fR] [\fB\-\-no\-default\-ignore\fR] [\fB\-\-no\-discover\-ignore\fR] [\fB\-\-ignore\-nothing\fR] [\fB\-p\fR|\fB\-\-postpone\fR] [\fB\-\-delay\-run\fR] [\fB\-\-poll\fR] [\fB\-\-shell\fR] [\fB\-n \fR] [\fB\-\-emit\-events\-to\fR] [\fB\-\-only\-emit\-events\fR] [\fB\-E\fR|\fB\-\-env\fR] [\fB\-\-no\-process\-group\fR] [\fB\-\-wrap\-process\fR] [\fB\-N\fR|\fB\-\-notify\fR] [\fB\-\-color\fR] [\fB\-\-timings\fR] [\fB\-q\fR|\fB\-\-quiet\fR] [\fB\-\-bell\fR] [\fB\-\-project\-origin\fR] [\fB\-\-workdir\fR] [\fB\-e\fR|\fB\-\-exts\fR] [\fB\-f\fR|\fB\-\-filter\fR] [\fB\-\-filter\-file\fR] [\fB\-j\fR|\fB\-\-filter\-prog\fR] [\fB\-i\fR|\fB\-\-ignore\fR] [\fB\-\-ignore\-file\fR] [\fB\-\-fs\-events\fR] [\fB\-\-no\-meta\fR] [\fB\-\-print\-events\fR] [\fB\-\-manual\fR] [\fB\-\-completions\fR] [\fB\-v\fR|\fB\-\-verbose\fR]... [\fB\-\-log\-file\fR] [\fB\-h\fR|\fB\-\-help\fR] [\fB\-V\fR|\fB\-\-version\fR] [\fICOMMAND\fR]
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
Execute commands when watched files change.
|
Execute commands when watched files change.
|
||||||
.PP
|
.PP
|
||||||
@ -55,6 +55,15 @@ Unlike \*(Aq\-w\*(Aq, folders watched with this option are not recursed into.
|
|||||||
|
|
||||||
This option can be specified multiple times to watch multiple directories non\-recursively.
|
This option can be specified multiple times to watch multiple directories non\-recursively.
|
||||||
.TP
|
.TP
|
||||||
|
\fB\-F\fR, \fB\-\-watch\-file\fR=\fIPATH\fR
|
||||||
|
Watch files and directories from a file
|
||||||
|
|
||||||
|
Each line in the file will be interpreted as if given to \*(Aq\-w\*(Aq.
|
||||||
|
|
||||||
|
For more complex uses (like watching non\-recursively), use the argfile capability: build a file containing command\-line options and pass it to watchexec with `@path/to/argfile`.
|
||||||
|
|
||||||
|
The special value \*(Aq\-\*(Aq will read from STDIN; this in incompatible with \*(Aq\-\-stdin\-quit\*(Aq.
|
||||||
|
.TP
|
||||||
\fB\-c\fR, \fB\-\-clear\fR=\fIMODE\fR
|
\fB\-c\fR, \fB\-\-clear\fR=\fIMODE\fR
|
||||||
Clear screen before running command
|
Clear screen before running command
|
||||||
|
|
||||||
@ -582,6 +591,6 @@ Use @argfile as first argument to load arguments from the file \*(Aqargfile\*(Aq
|
|||||||
|
|
||||||
Didn\*(Aqt expect this much output? Use the short \*(Aq\-h\*(Aq flag to get short help.
|
Didn\*(Aqt expect this much output? Use the short \*(Aq\-h\*(Aq flag to get short help.
|
||||||
.SH VERSION
|
.SH VERSION
|
||||||
v2.0.0
|
v2.1.2
|
||||||
.SH AUTHORS
|
.SH AUTHORS
|
||||||
Félix Saparelli <felix@passcod.name>, Matt Green <mattgreenrocks@gmail.com>
|
Félix Saparelli <felix@passcod.name>, Matt Green <mattgreenrocks@gmail.com>
|
||||||
|
@ -5,10 +5,11 @@ watchexec - Execute commands when watched files change
|
|||||||
# SYNOPSIS
|
# SYNOPSIS
|
||||||
|
|
||||||
**watchexec** \[**-w**\|**\--watch**\]
|
**watchexec** \[**-w**\|**\--watch**\]
|
||||||
\[**-W**\|**\--watch-non-recursive**\] \[**-c**\|**\--clear**\]
|
\[**-W**\|**\--watch-non-recursive**\] \[**-F**\|**\--watch-file**\]
|
||||||
\[**-o**\|**\--on-busy-update**\] \[**-r**\|**\--restart**\]
|
\[**-c**\|**\--clear**\] \[**-o**\|**\--on-busy-update**\]
|
||||||
\[**-s**\|**\--signal**\] \[**\--stop-signal**\] \[**\--stop-timeout**\]
|
\[**-r**\|**\--restart**\] \[**-s**\|**\--signal**\]
|
||||||
\[**\--map-signal**\] \[**-d**\|**\--debounce**\] \[**\--stdin-quit**\]
|
\[**\--stop-signal**\] \[**\--stop-timeout**\] \[**\--map-signal**\]
|
||||||
|
\[**-d**\|**\--debounce**\] \[**\--stdin-quit**\]
|
||||||
\[**\--no-vcs-ignore**\] \[**\--no-project-ignore**\]
|
\[**\--no-vcs-ignore**\] \[**\--no-project-ignore**\]
|
||||||
\[**\--no-global-ignore**\] \[**\--no-default-ignore**\]
|
\[**\--no-global-ignore**\] \[**\--no-default-ignore**\]
|
||||||
\[**\--no-discover-ignore**\] \[**\--ignore-nothing**\]
|
\[**\--no-discover-ignore**\] \[**\--ignore-nothing**\]
|
||||||
@ -92,6 +93,19 @@ Unlike -w, folders watched with this option are not recursed into.
|
|||||||
This option can be specified multiple times to watch multiple
|
This option can be specified multiple times to watch multiple
|
||||||
directories non-recursively.
|
directories non-recursively.
|
||||||
|
|
||||||
|
**-F**, **\--watch-file**=*PATH*
|
||||||
|
|
||||||
|
: Watch files and directories from a file
|
||||||
|
|
||||||
|
Each line in the file will be interpreted as if given to -w.
|
||||||
|
|
||||||
|
For more complex uses (like watching non-recursively), use the argfile
|
||||||
|
capability: build a file containing command-line options and pass it to
|
||||||
|
watchexec with \`@path/to/argfile\`.
|
||||||
|
|
||||||
|
The special value - will read from STDIN; this in incompatible with
|
||||||
|
\--stdin-quit.
|
||||||
|
|
||||||
**-c**, **\--clear**=*MODE*
|
**-c**, **\--clear**=*MODE*
|
||||||
|
|
||||||
: Clear screen before running command
|
: Clear screen before running command
|
||||||
@ -861,7 +875,7 @@ Didnt expect this much output? Use the short -h flag to get short help.
|
|||||||
|
|
||||||
# VERSION
|
# VERSION
|
||||||
|
|
||||||
v2.0.0
|
v2.1.2
|
||||||
|
|
||||||
# AUTHORS
|
# AUTHORS
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user