Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

-i has confusing semantics #82

Closed
Boscop opened this issue Oct 7, 2017 · 22 comments
Closed

-i has confusing semantics #82

Boscop opened this issue Oct 7, 2017 · 22 comments

Comments

@Boscop
Copy link

Boscop commented Oct 7, 2017

Cargo watch doesn't ignore app.db even though I have it in .gitignore and even when I pass it to the command like:
cargo watch -i app.db -x "run -p mybin"
(I'm running this in a workspace where mybin is the binary I want to run.)

My .gitignore looks like this:

target
.env
app.db

I'm on Windows 8.1.
When my exe writes to app.db, it triggers cargo watch to restart the exe, why?

@passcod
Copy link
Member

passcod commented Oct 7, 2017

This is most probably an upstream issue. Ask on watchexec.

@mattgreen
Copy link

mattgreen commented Oct 7, 2017

I tried to replicate this with all combinations of macOS/Windows and cargo watch/watchexec. (Note that I tried it on Windows 10, I don't have an 8.1 machine around.)

So, can you add --debug to the CLI options, re-create the problem, and paste all of the output here?

@passcod
Copy link
Member

passcod commented Oct 7, 2017

Thanks for having a look @mattgreen :)

@Boscop
Copy link
Author

Boscop commented Mar 14, 2018

Any update on this? :)

@passcod
Copy link
Member

passcod commented Mar 14, 2018

@Boscop can you provide a --debug log for us?

@avkonst
Copy link

avkonst commented Mar 14, 2018

As requested here: rust-lang/cargo#5169 (comment)

I do not think it is watchexec issue as changes on file system are detected correctly. In my case .gitignore is observed by the cargo watch correctly. But it restarts forever a program under -x argument if CARGO_TARGET_DIR is not in .gitignore, even if I specify it with -i option

> set CARGO_TARGET_DIR=./target_watch
> cargo watch -i /target_watch/ --debug -x "run -- -v"
> cargo watch -i ./target_watch --debug -x "run -- -v"
> cargo watch -i target_watch --debug -x "run -- -v"

All the above cause the following infinite cyclic loop (when target_watch is not in gitignore):

    Finished dev [unoptimized + debuginfo] target(s) in 0.0 secs
     Running `target_watch\debug\adapter.exe -v`
*** Path updated: PathOp { path: "\\\\?\\C:\\Projects\\MyProj\\adapter\\target_watch\\debug\\adapter.d", op: Some(WRITE), cookie: None }
*** Waiting for process to exit...
*** Launching child process
*** Assembled command "cmd.exe" "/C" "echo [Running \'cargo run -- -v\'] && cargo run -- -v && echo [Finished running]"
*** Waiting for filesystem activity
[Running 'cargo run -- -v']
    Finished dev [unoptimized + debuginfo] target(s) in 0.0 secs
     Running `target_watch\debug\adapter.exe -v`
*** Path updated: PathOp { path: "\\\\?\\C:\\Projects\\MyProj\\adapter\\target_watch\\debug\\adapter.d", op: Some(WRITE), cookie: None }
*** Waiting for process to exit...
*** Launching child process
..... and so on repeated forever

Before the loop starts, it prints the following debug:

>>> Load Git/VCS ignores: true
>>> Default ignores: ["*\\.DS_Store", "*.swp", "*\\.hg\\**", "*\\.git\\**", "*\\.svn\\**", "*\\target\\**"]
>>> All ignores: ["*\\.DS_Store", "*.swp", "*\\.hg\\**", "*\\.git\\**", "*\\.svn\\**", "*\\target\\**", "./target_watch"]
>>> File updates debounce: 0.5 seconds
>>> Commands: ["cargo run -- -v"]
>>> Watches: ["."]
>>> Watchexec arguments: Args { cmd: "echo [Running \'cargo run -- -v\'] && cargo run -- -v && echo [Finished running]", paths: ["."], filters: [], ignores: ["*\\.DS_Store", "*.swp", "*\\.hg\\**", "*\\.git\\**", "*\\.svn\\**", "*\\target\\**", "./target_watch"], clear_screen: false, signal: None, restart: true, debounce: 500, debug: true, run_initially: true, no_shell: false, no_vcs_ignore: false, once: false, poll: false, poll_interval: 500 }
*** glob converted to regex: Glob { glob: "target/**", re: "(?-u)^target(?:/?|/.*)$", opts: GlobOptions { case_insensitive: false, literal_separator: true }, tokens: Tokens([Literal('t'), Literal('a'), Literal('r'), Literal('g'), Literal('e'), Literal('t'), RecursiveSuffix]) }
*** glob converted to regex: Glob { glob: "**/*.rs.bk/**", re: "(?-u)^(?:/?|.*/)[^/]*\\.rs\\.bk(?:/?|/.*)$", opts: GlobOptions { case_insensitive: false, literal_separator: true }, tokens: Tokens([RecursivePrefix, ZeroOrMore, Literal('.'), Literal('r'), Literal('s'), Literal('.'), Literal('b'), Literal('k'), RecursiveSuffix]) }
*** glob converted to regex: Glob { glob: ".idea/**", re: "(?-u)^\\.idea(?:/?|/.*)$", opts: GlobOptions { case_insensitive: false, literal_separator: true }, tokens: Tokens([Literal('.'), Literal('i'), Literal('d'), Literal('e'), Literal('a'), RecursiveSuffix]) }
*** glob converted to regex: Glob { glob: ".vscode/**", re: "(?-u)^\\.vscode(?:/?|/.*)$", opts: GlobOptions { case_insensitive: false, literal_separator: true }, tokens: Tokens([Literal('.'), Literal('v'), Literal('s'), Literal('c'), Literal('o'), Literal('d'), Literal('e'), RecursiveSuffix]) }
*** glob converted to regex: Glob { glob: "rust-exp.iml/**", re: "(?-u)^rust\\-exp\\.iml(?:/?|/.*)$", opts: GlobOptions { case_insensitive: false, literal_separator: true }, tokens: Tokens([Literal('r'), Literal('u'), Literal('s'), Literal('t'), Literal('-'), Literal('e'), Literal('x'), Literal('p'), Literal('.'), Literal('i'), Literal('m'), Literal('l'), RecursiveSuffix]) }
*** glob converted to regex: Glob { glob: "Cargo.lock.work/**", re: "(?-u)^Cargo\\.lock\\.work(?:/?|/.*)$", opts: GlobOptions { case_insensitive: false, literal_separator: true }, tokens: Tokens([Literal('C'), Literal('a'), Literal('r'), Literal('g'), Literal('o'), Literal('.'), Literal('l'), Literal('o'), Literal('c'), Literal('k'), Literal('.'), Literal('w'), Literal('o'), Literal('r'), Literal('k'), RecursiveSuffix]) }
*** built glob set; 0 literals, 0 basenames, 0 extensions, 0 prefixes, 0 suffixes, 0 required extensions, 6 regexes
*** Loaded "\\\\?\\C:\\Projects\\MyProj\\adapter\\.gitignore"
*** Adding ignore: "*\.DS_Store"
*** Adding ignore: "*.swp"
*** Adding ignore: "*\.hg\**"
*** Adding ignore: "*\.git\**"
*** Adding ignore: "*\.svn\**"
*** Adding ignore: "*\target\**"
*** Adding ignore: "**\./target_watch"
*** glob converted to regex: Glob { glob: "*\\.hg\\**", re: "(?-u)^.*/\\.hg(?:/?|/.*)$", opts: GlobOptions { case_insensitive: false, literal_separator: false }, tokens: Tokens([ZeroOrMore, Literal('/'), Literal('.'), Literal('h'), Literal('g'), RecursiveSuffix]) }
*** glob converted to regex: Glob { glob: "*\\.git\\**", re: "(?-u)^.*/\\.git(?:/?|/.*)$", opts: GlobOptions { case_insensitive: false, literal_separator: false }, tokens: Tokens([ZeroOrMore, Literal('/'), Literal('.'), Literal('g'), Literal('i'), Literal('t'), RecursiveSuffix]) }
*** glob converted to regex: Glob { glob: "*\\.svn\\**", re: "(?-u)^.*/\\.svn(?:/?|/.*)$", opts: GlobOptions { case_insensitive: false, literal_separator: false }, tokens: Tokens([ZeroOrMore, Literal('/'), Literal('.'), Literal('s'), Literal('v'), Literal('n'), RecursiveSuffix]) }
*** glob converted to regex: Glob { glob: "*\\target\\**", re: "(?-u)^.*/target(?:/?|/.*)$", opts: GlobOptions { case_insensitive: false, literal_separator: false }, tokens: Tokens([ZeroOrMore, Literal('/'), Literal('t'), Literal('a'), Literal('r'), Literal('g'), Literal('e'), Literal('t'), RecursiveSuffix]) }
*** built glob set; 1 literals, 0 basenames, 1 extensions, 0 prefixes, 2 suffixes, 0 required extensions, 4 regexes
*** Watching "\\\\?\\C:\\Projects\\MyProj\\adapter"
*** Assembled command "cmd.exe" "/C" "echo [Running \'cargo run -- -v\'] && cargo run -- -v && echo [Finished running]"
*** Waiting for filesystem activity
[Running 'cargo run -- -v']

However, I managed to find the right combination for -i argument to stop the infinite restart loop. The following works but value for -i option is strange to say at least:

> cargo watch -i *\target_watch\** --debug -x "run -- -v" 

@passcod
Copy link
Member

passcod commented Mar 15, 2018

Thank you, that should help!

@mattgreen
Copy link

Thank you for attaching log output. This line doesn't look right:

*** Adding ignore: "**\./target_watch"

There are two issues here:

  1. The path separators are not Windows-style, rendering the pattern useless.

  2. Paths starting with ./ aren't considered to be anchored currently, even though they should be.

I'll take a look. I have a backlog of bugs I need to move through and am evaluating a better design for watchexec currently anyway.

@mattgreen
Copy link

Actually, this doesn't involve gitignore at all.

-i is typically used to specify filename filters, and here it is being used to say, "everything under target_watch should be ignored," much like how gitignore filters work.

That is a reasonable thing to expect, but it isn't currently implemented.

@passcod
Copy link
Member

passcod commented Mar 16, 2018

I'll clarify this in readme and help message for cargo-watch.

To help: I think I could automatically translate / to \ if we're on Windows, but I don't think I can reasonably do "if pattern refers to a directory, add /** at the end" except for very simple cases.

@Boscop
Copy link
Author

Boscop commented Mar 17, 2018

Maybe this crate is useful for this?
https://github.com/udoprog/relative-path

@passcod
Copy link
Member

passcod commented Jul 13, 2018

Closing (reopen if it still occurs)

@passcod passcod closed this as completed Jul 13, 2018
@Boscop
Copy link
Author

Boscop commented Jul 23, 2018

This doesn't ignore the frontend folder's contents:
cargo watch -i frontend -x r
But this seems to work:
cargo watch -i "frontend/**/*" -x r

Why doesn't the first one work though? (It works with other tools that have a similar purpose..)

@passcod
Copy link
Member

passcod commented Jul 23, 2018

Yes, my bad, should still be open. See the last comment by matt green as to why this.

@passcod passcod reopened this Jul 23, 2018
@infogulch
Copy link
Contributor

infogulch commented Oct 22, 2018

Ignoring seems to be broken even for normal files in the root that are specified specifically by name.

@passcod
Copy link
Member

passcod commented Oct 22, 2018 via email

@infogulch
Copy link
Contributor

infogulch commented Oct 22, 2018

Absolutely. Sorry for not providing more details at first. Repro:

cargo new watchtest
cd watchtest
cargo watch -i test.txt -x run

# in parallel...
vim test.txt

Aaaand I just realized my case is probably related to the extra files that vim creates when saving. It also occurs when my app is running, which happens to use a sqlite db.... which also creates auxiliary files.

And after checking for and eliminating both of these cases cargo-watch is behaving as expected again. I should have used --debug first. Sorry!

@passcod
Copy link
Member

passcod commented Oct 22, 2018

I think a pull request covered the vim files recently, but just in case can you give their names/extensions? Also for the sqlite db ones, I think there would be benefit to adding those by default

@infogulch
Copy link
Contributor

infogulch commented Oct 22, 2018

For sqlite, in my case it was file.db-journal. -wal, -shm suffixes are also documented, and in some cases the -journal suffix is a directory.

Rerunning the vim test, it looks like vim was creating .text.txt.swp and .text.txt.swx which were successfully ignored, but the thing that triggered it was *** Path updated: PathOp { path: "/home/joe/projects/watchtest/4913", op: Some(CREATE), cookie: None }, that only happened on save (:w). Not sure what the number "4913" is, unfortunately it doesn't appear to be related to vim (it's not vim's pid at least) or the original ignored file. I'm using Vim 8 if it matters.

My fix for vim is to set backupdir and set directory to default to ~/.vim/tmp as per this suggestion.

EDIT: cargo watch --version == cargo-watch 7.0.5

@passcod
Copy link
Member

passcod commented Oct 29, 2018

The sqlite ignores are now in 7.0.7.

@passcod
Copy link
Member

passcod commented Oct 29, 2018

To clarify again, this issue is not technically about a code bug, but about the misinterpretation of what -i does. That in itself may or may not be a bug.

@passcod passcod changed the title Cargo watch is not ignoring files, neither in .gitignore, nor specified with -i -i has confusing semantics Oct 29, 2018
@passcod
Copy link
Member

passcod commented Apr 11, 2021

Closing in favour of upstream issue: watchexec/watchexec#188.

@passcod passcod closed this as completed Apr 11, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants