cargo-watch icon indicating copy to clipboard operation
cargo-watch copied to clipboard

Cargo-watch reacts to `IsFile` event, while it should not.

Open wdanilo opened this issue 2 years ago • 10 comments

Hi, I'm using cargo-watch 8.1.1 (because 8.3.0 does not work for me). Recently, our build script, which uses cargo-watch under the hood, started looping indefinitely. After debugging it turned out, that when using std::fs::copy("a.txt", "b.txt") on macOS, a file system event IsFile is sometimes emitted on the source file ("a.txt"). The term "sometimes" is better explained here. Our build script is copying some files to target directory, which causes the sources to emit this event, which causes cargo-watch to re-run the whole operation again.

System: macOS Monterey (12.0.1), M1 pro

wdanilo avatar Jan 22 '23 19:01 wdanilo

IsFile is a bit in the event mask, not an event type per se, similar to the IS_DIR bit in Linux. The event itself is probably a new possibly-undocumented one, so it doesn't appear in the fswatch handling, and passes through fsevents and notify to us.

This makes this bug platform version specific: it doesn't appear on Linux, and it doesn't appear on the old macbook air I have, which can't get upgraded to macOS 12.x

Fixing the issue is probably best done upstream in notify as by the time it gets handled here, it's already reduced to one of only five categories. However, cargo-watch 8.x uses watchexec 1.17, which uses notify 4.x (the latest version is 5.0.0)... but it might be possible to have a patch release made for that release branch. Ask there.

In the meantime, you can likely work around the issue by using --watch-when-idle.

passcod avatar Jan 22 '23 23:01 passcod

@passcod thanks for the explanation. I created an issue in the notify repo.

Regarding --watch-when-idle, unfortunately, it does not help. It still loops forever. Here are the logs with --why option. Please note that logs are interleaved with our build script logs:

out-2.txt

Is there anything I can do to help debugging it further?

wdanilo avatar Jan 23 '23 01:01 wdanilo

Wow I hadn't realised you were embedding cargo watch in your program. That's... not supported. I can't stop you, but this is not something that I would ever recommend doing. Use the libraries directly if you need to.

Regardless:

  • if you use watchexec with --print-events (like --why) and -p -1 (hidden testing flag, will stop at first event), and fswatch, you should be able to catch this new event, and see what watchexec interprets it as.
  • notify from your latest log displays it as Some((none)), which we should be able to catch and ignore in here. That's probably a good workaround until the event is properly caught.

passcod avatar Jan 23 '23 04:01 passcod

@passcod we are not embedding it. We have a build script which basically downloads fonts to a folder, then compiles some C binaries, etc., end then runs cargo-watch to watch for changes (it runs cargo-watch as cmd command cargo watch ...). Every time a change happens, we are just running cargo and also npm to build our JS app. I believe that this is just a normal usage of cargo-watch, wich does not stand in opposite to how this library is meant to be used. Am I correct?

Regarding the points that you mentioned:

  1. That's a very handy info, thank you! I'll try to dig deeper and check how watch exec interprets it.
  2. It would be amazing to ignore it and check out if it fixes things - do you think you'd be able to implement it?

wdanilo avatar Jan 23 '23 06:01 wdanilo

Not really interested in debating what exactly counts as embedding. This isn't a gotcha or invalidating a support contract or whatever. Interactive use is the intended use. If your setup works for you, fine.

  1. Sure. Can't guarantee when, though. Probably sometime next month? If you or anyone's interested in patching earlier, then start looking here.

passcod avatar Jan 23 '23 23:01 passcod

Hi @passcod, did you find time to take a look into this issue? :)

wdanilo avatar Feb 19 '23 02:02 wdanilo

No. Again, if you want it earlier, a PR is welcome.

passcod avatar Feb 19 '23 03:02 passcod

@passcod I totally understand it. Unfortunately, I don't have enough of time to contribute here, as it requires pretty in-depth debugging. While I find cargo-watch to be the right solution in long-term, as it's written purely in Rust, until it works properly on modern MacOS and covers all .gitignore syntax, we made another project that is a in-place replacement for cargo-watch - we made it just in 1 evening, as it uses well-tested JS libs under the hood – for anyone facing this issue, you can find it here: https://github.com/enso-org/cargo-watch-plus (it works well on all Mac, Linux, and Windows, and supports all .gitignore syntax).

wdanilo avatar Feb 21 '23 14:02 wdanilo

I'd say please don't use the name cargo-watch, but otherwise, best of luck

passcod avatar Feb 21 '23 19:02 passcod

I'm using cargo- prefix because this way it registers as cargo command. I was trying to be very explicit that cargo-watch is the go to tool when it will work fine on MacOS. TBH, I hope I'd be able to delete this project sooner than later, as soon as cargo-watch will again work on my system.

wdanilo avatar Feb 21 '23 22:02 wdanilo