fix: watch cwds of dependencies#10054
Conversation
When I changed watch mode to also watch dependencies' sources, I didn't
take into account the fact that the `sources` will be used _as-is_ (i.e.
not resolved to anything).
This meant the following would happen:
- `build:a` has `["src/*.ts"]`
- `build:b` has `["lib/*.js"]` and depends on `build:a`
- We pass `["src/*.ts", "lib/*.js"]` to watchexec _in the directory of
`build:b`_
This made `lib/*.js` basically no-op, or worse, watch the wrong files.
This change resolves the paths to their owning directory so we end up
with `["wherever-builda-lives/src/*.ts",
"wherever-buildb-lives/lib/*.js"]`.
**Notable Changes:**
- Instead of passing relative globs to watchexec, we now pass resolved
ones (relative to the root)
- We now pass `--project-origin` to watchexec which comes with some perf
gains but also means globs are now relative to it
- We pass `--watch {cwd}` for the cwd of each dependency
- This new `resolve_source` function is basically turning a source glob
into a relative-to-the-root glob while retaining negations
There was a problem hiding this comment.
Code Review
This pull request introduces logic to calculate a "filter anchor" for watchexec by determining the common ancestor of task working directories, ensuring glob filters are correctly interpreted relative to a project origin. It adds utility functions for finding common path ancestors and resolving source patterns, including support for negations and escaped characters. Review feedback focused on optimizing the common_ancestor function by using AsRef to avoid unnecessary cloning and reducing memory allocations during path component comparisons.
Greptile SummaryThis PR fixes watch mode so that source globs belonging to dependency tasks are resolved relative to each task's own working directory before being passed to watchexec, rather than being handed to watchexec unchanged (and thus interpreted relative to the wrong cwd). It introduces
Confidence Score: 4/5The change is a meaningful correctness fix for watch mode; safe to merge with the two edge cases noted. The new helpers are well-exercised by unit tests. Two narrow edge cases remain: src/cli/watch.rs — Important Files Changed
Reviews (4): Last reviewed commit: "feat: handle empy sets of sources" | Re-trigger Greptile |
When I changed watch mode to also watch dependencies' sources, I didn't
take into account the fact that the
sourceswill be used as-is (i.e.not resolved to anything).
This meant the following would happen:
build:ahas["src/*.ts"]build:bhas["lib/*.js"]and depends onbuild:a["src/*.ts", "lib/*.js"]to watchexec in the directory ofbuild:bThis made
lib/*.jsbasically no-op, or worse, watch the wrong files.This change resolves the paths to their owning directory so we end up
with
["wherever-builda-lives/src/*.ts", "wherever-buildb-lives/lib/*.js"].Notable Changes:
ones (relative to the root)
--project-originto watchexec which comes with some perfgains but also means globs are now relative to it
--watch {cwd}for the cwd of each dependencyresolve_sourcefunction is basically turning a source globinto a relative-to-the-root glob while retaining negations
common_ancestorfunction tries to find the common ancestor of two directoriescc @jdx i don't usually delve into rust so i'd love some help here if you can.
especially if there's a better way to find the common ancestor, or if you think we should deal with that differently.
basically, watchexec doesn't seem to support absolute paths, so we have to set the
project-originto something above all globs. which is why this new function tries to find a common root (if not the configured one)