Detect other project types¶
DefaultMarkers targets Go projects (.gtb/manifest.yaml, go.mod, .git). For any
other ecosystem, pass your own marker slice — the walk is otherwise identical.
Supply your own markers¶
Both Detect and DetectFromCWD take the marker list as a plain []string:
// Node
ws, err := workspace.Detect(fs, startDir, []string{"package.json"})
// Rust
ws, err := workspace.Detect(fs, startDir, []string{"Cargo.toml"})
// Python
ws, err := workspace.Detect(fs, startDir, []string{"pyproject.toml", "setup.py"})
Each entry is joined onto the directory being checked and Stat-ed, so a marker can be a
nested path (.gtb/manifest.yaml) as well as a top-level file or directory (.git).
Order matters — first match wins¶
Within a single directory the markers are checked in the order you give them, and the first that exists wins. Put the most specific marker first:
// A generated-project manifest should outrank a bare git root.
markers := []string{".myapp/project.toml", ".git"}
This is exactly why DefaultMarkers lists .gtb/manifest.yaml before go.mod before
.git: a generated project is more specific than "any Go module", which is more specific
than "any git repo".
Stop at the first boundary you hit¶
The walk climbs one directory at a time and returns as soon as any marker matches at the
current level. In a monorepo where an inner package has its own go.mod and the repo root
has .git, detecting from inside the package with DefaultMarkers stops at the package's
go.mod — the nearest boundary — not the repo root. Choose the marker set that matches the
boundary you actually want.
Bound the climb¶
By default the walk gives up after DefaultMaxDepth (100) parents. Tighten it when you
only ever expect a shallow layout:
If no marker is found within the bound, you get workspace.ErrNotFound.