Skip to content
Closed
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
12 changes: 2 additions & 10 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,16 +72,8 @@ Run each of those a second time from `workcontext/` — it is a separate module
with its own `go.mod` and `go.sum`, so nothing at the root covers it. Lint finds
the root `.golangci.yaml` by walking up, so it needs no config of its own.

Coverage thresholds differ by module and are not interchangeable:

| Module | Gate | Where |
| --- | --- | --- |
| root | total ≥ 75%, per-file and per-package 0 | `.testcoverage.yaml` |
| `workcontext` | module total ≥ 75%, via `awk` in CI | `go.yml`, `coverage` job |

The `workcontext` gate is on the **module total** across both its packages, so
`grpctransport` sitting low is carried by the verifier. Read the total, not a
package line.
Coverage gates differ by module: the root's is `.testcoverage.yaml` (total ≥ 75%);
the `workcontext` module's is described in `workcontext/AGENTS.md`.

## Where things live

Expand Down
22 changes: 22 additions & 0 deletions endpoint_deployed_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -231,3 +231,25 @@ func TestLocalProcessWithoutAWorkspaceRefusesAMalformedCarrier(t *testing.T) {
}
}
}

// A module run from its own checkout inside a larger composition finds its
// repository's workspace on disk, which declares the module under its own name,
// not the name the composition gave it. That workspace is not the
// composition, so the process resolves from the carrier the composition's CLI
// injected, as a workspace-free process does, rather than refusing every
// endpoint because its repository does not know the composition's name.
func TestAComposedModuleRunFromItsOwnCheckoutResolvesItsCarrier(t *testing.T) {
prepareProcessWithoutWorkspace(t, "local")
checkout := t.TempDir()
require.NoError(t, os.WriteFile(checkout+"/workspace.codefly.yaml",
[]byte("name: module-own-dev\nlayout: modules\nmodules:\n - name: module-own-name\n"), 0o600))
t.Chdir(checkout)
workspace, err := resources.FindWorkspaceUp(context.Background())
require.NoError(t, err)
require.NotNil(t, workspace, "the test needs the module repository's own workspace on disk")
access := carrierFor("rest", "rest", "http://localhost:24601")
injectEndpointForTest(t, "runtime", access)
instance, err := queryCarriedService().API("rest").ResolveNetworkInstance()
require.NoError(t, err)
require.Equal(t, uint16(24601), instance.Port)
}
21 changes: 20 additions & 1 deletion for.go
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ func (q *Query) ResolveNetworkInstance() (*resources.NetworkInstance, error) {
if err != nil {
return nil, err
}
if workspace == nil {
if workspace == nil || !composes(workspace, q.module) {
return q.resolveFromAuthoritativeCarrier()
}
// The declaration decides eligibility before any carrier can supply an
Expand Down Expand Up @@ -155,6 +155,25 @@ func (q *Query) ResolveNetworkInstance() (*resources.NetworkInstance, error) {
return local, nil
}

// composes reports whether the workspace found on disk is the composition
// this process runs in: it declares the module the query names. A module run
// from its own checkout inside a larger composition finds its repository's
// workspace, which knows the module by its own name, not by the name the
// composition gave it; reading eligibility from it would refuse every
// endpoint. That process is answered as a workspace-free one is — from the
// carriers the composition's CLI judged and injected at run time.
func composes(workspace *resources.Workspace, module string) bool {
if workspace.Name == module {
return true
}
for _, declared := range workspace.ModulesNames() {
if declared == module {
return true
}
}
return false
}

// resolveFromAuthoritativeCarrier answers a workspace-free process from its carriers
// alone. The carrier is keyed by the query's canonical identity — the
// declaration is not on disk to supply any part of it — and nothing is judged
Expand Down
Loading
Loading