support repos with .cargo/config.toml but no Cargo.toml at root #205
Description
Feel free to mark this as too niche and close it.
I thought I'd share a slightly contrarian take on the xtask pattern for full-stack rust (the original pattern is described in https://github.com/matklad/cargo-xtask/ and a variation for embedded development is described at https://ferrous-systems.com/blog/test-embedded-app/):
4 workspaces:
- frontend/
- backend/
- xtask/
- crates/ (contains common code that is shared between frontend and backend)
No Cargo.toml
at the top level
A .cargo/config.toml
at the top level with this in:
[alias]
xtask = "run --timings --manifest-path=xtask/Cargo.toml"
xhelp = "xtask -- --help"
xfmt = "xtask -- fmt"
xcheck = "xtask -- check"
xtest = "xtask -- test"
xhost = "xtask -- host"
xbuild = "xtask -- build"
xdeploy = "xtask -- deploy"
xrollout = "xtask -- rollout"
[env]
TARGET_DIR = { value = "target", relative = true, force = true }
ROOT_DIR = { value = "", relative = true, force = true }
# ... and some other stuff around profiles etc.
This has the advantage that each workspace is isolated, and you can get away without workspace-hack
packages. It also means that all of your custom build commands work fine from the root of the repo.
Unfortunately, it also means that cargo watch
doesn't play ball at the root of the repo (and the xtask alias is fragile enough that it doesn't work anywhere other than the root of the repo).
$ cargo watch -x xcheck
error: project root does not exist
As I said in at the top, feel free to close this. I can't even think how cargo watch
would be able to make any sensible decision other than "watch the whole git repo" under this scheme.
The fix at the project level would be to merge the crates/
and backend/
workspaces, and promote them to the top level of the repo (following the structure in the ferrous-systems article, above), then be a bit more careful with feature flag interactions (probably using a workspace-hack package or similar). It is also possible to use watchexec
, as long as you add some workarounds for nested .gitignore problems (watchexec/watchexec#250)