Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion TASK_CACHE_PARITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ outside this tracker.
- [x] Explain which provider inferred each project, task, input, output, and dependency
- [x] Add Cargo workspace and path-dependency inference
- [x] Add uv workspace and local/path-dependency inference
- [ ] Add Go workspace discovery, with explicit dependency overrides where module metadata is
- [x] Add Go workspace discovery, with explicit dependency overrides where module metadata is
insufficient

## Affected project execution
Expand Down
21 changes: 21 additions & 0 deletions docs/tasks/monorepo.md
Original file line number Diff line number Diff line change
Expand Up @@ -411,6 +411,27 @@ external-workspace sources do not add projects or edges. Self-dependencies are i
cycles among projects are reported by `mise tasks graph` and can be corrected with project
overrides.

### Go Workspace Discovery

The Go provider discovers modules listed by `use` directives in the root `go.work`. Both individual
directives and `use` blocks are supported. Each listed directory must contain a `go.mod` with a
`module` directive; mise uses that stable module path to create an ID such as
`go:example.com/acme/api`. Modules listed outside the configured monorepo root are ignored because
project roots in the mise graph are always repository-relative.

Discovery parses `go.work` and `go.mod` directly and does not require the `go` executable. It does
not infer dependency edges from `require` or `replace`: those directives describe module selection,
not necessarily the source-level relationship needed by a task graph. Add the edges that matter to
your build with project overrides:

```toml
[monorepo.projects."go:example.com/acme/api"]
depends_add = ["go:example.com/acme/lib"]
```

Use `depends` to replace the complete dependency set, or `depends_add` and `depends_remove` for
targeted adjustments. The graph explanation attributes these configured edges to `configuration`.

### Node Workspace Discovery

The Node provider discovers npm, pnpm, Yarn, and Bun workspace packages from:
Expand Down
61 changes: 61 additions & 0 deletions e2e/tasks/test_task_go_workspace_graph
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
#!/usr/bin/env bash

export MISE_EXPERIMENTAL=1

cat <<'EOF' >mise.toml
monorepo_root = true

[monorepo.projects."go:example.com/acme/api"]
depends_add = ["go:example.com/acme/lib"]
EOF

cat <<'EOF' >go.work
go 1.25

use (
./cmd/api
./lib
)
EOF

mkdir -p cmd/api lib

cat <<'EOF' >cmd/api/go.mod
module example.com/acme/api

go 1.25

require example.com/acme/lib v0.0.0
EOF

cat <<'EOF' >lib/go.mod
module example.com/acme/lib

go 1.25
EOF

assert_contains "mise tasks graph" "go:example.com/acme/api"
assert_contains "mise tasks graph" "cmd/api"
assert_contains "mise tasks graph" '"workspace_source":"go.mod"'
assert_contains "mise tasks graph --explain" "Project: go:example.com/acme/api"
assert_contains "mise tasks graph --explain" "go:example.com/acme/lib — configuration"

assert_json "mise tasks graph --json | jq '.projects | map({id, root, dependencies})'" '[
{
"id": "go:example.com/acme/api",
"root": "cmd/api",
"dependencies": [
"go:example.com/acme/lib"
]
},
{
"id": "go:example.com/acme/lib",
"root": "lib",
"dependencies": []
}
]'

assert_json "mise tasks graph --json | jq '.projects[] | select(.id == \"go:example.com/acme/api\") | .provenance'" '{
"provider": "go",
"source": "cmd/api/go.mod"
}'
5 changes: 3 additions & 2 deletions src/config/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -506,18 +506,19 @@ impl Config {
.cloned()
.unwrap_or_default();
let cargo = crate::task::workspace::cargo::CargoWorkspaceProvider;
let go = crate::task::workspace::go::GoWorkspaceProvider;
let node = crate::task::workspace::node::NodeWorkspaceProvider;
let uv = crate::task::workspace::uv::UvWorkspaceProvider;

if skip_provider_errors {
crate::task::workspace::WorkspaceProjectGraph::discover_all_with_overrides_lenient(
&[&cargo, &node, &uv],
&[&cargo, &go, &node, &uv],
&monorepo_root,
&overrides,
)
} else {
crate::task::workspace::WorkspaceProjectGraph::discover_all_with_overrides(
&[&cargo, &node, &uv],
&[&cargo, &go, &node, &uv],
&monorepo_root,
&overrides,
)
Expand Down
1 change: 1 addition & 0 deletions src/task/workspace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use serde::{Deserialize, Serialize};
use super::{Task, TaskCacheConfig, task_sources::TaskOutputs};

pub mod cargo;
pub mod go;
pub mod node;
pub mod uv;

Expand Down
Loading
Loading