detect

package
v1.0.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 21, 2026 License: MIT Imports: 10 Imported by: 0

Documentation

Overview

Package detect discovers buildable targets under a directory tree.

It recognises three kinds of build, matching the conventions used across the a-novel / a-novel-kit repositories:

  • KindGo — any directory containing a go.mod (one target per module, including nested modules).
  • KindPnpm — any package.json whose "scripts" map has one or more keys starting with "build" (one target per matching script).
  • KindPodman — any builds/ directory containing *.Dockerfile files (one target per Dockerfile). The image tag is derived heuristically; see docker.go.

Discovery is recursive from the scan root so nested modules and workspace sub-packages are found, while vendored / generated trees (node_modules, .git, …) are pruned for speed and signal.

Index

Constants

This section is empty.

Variables

View Source
var InitOrder = []string{"init", "migrations", "rotate-keys"}

InitOrder is the priority list of one-shot init Go entrypoints by Name. Anything in this list, when selected, must run to completion BEFORE the long-lived service targets — and IN this order (init seeds, migrations applies schema, rotate-keys refreshes JWKs). Shared between detect (mode filter), runner (launch barrier) and main (mode resolution) so the policy lives in one place.

Functions

func IsInit

func IsInit(t Target) bool

IsInit reports whether t is one of the InitOrder entrypoints (a Go `cmd/<name>` main). It is the same predicate used everywhere — the container-mode picker keeps these alongside KindContainer targets, the runner barriers on them, the picker auto-pull (migrations only) pulls them.

func RepoGuard

func RepoGuard(dir string) error

RepoGuard fails fast (no filesystem scan) when dir is not inside a git repository owned by the a-novel / a-novel-kit orgs. Walking up for .git and reading the remotes is O(path depth) + two quick git calls, so an invalid directory errors almost instantly instead of triggering a deep walk.

Types

type ComposeEnv

type ComposeEnv struct {
	// File is the absolute path to the compose YAML.
	File string
	// Project is the `podman compose -p` project name — unique per env file
	// so parallel test targets never collide on container/network names.
	Project string
	// ID is the parsed identifier, e.g. "go.internal" or "pnpm".
	ID string
	// Ports are the env-var names the compose file binds on the HOST side of
	// a `ports:` mapping (e.g. POSTGRES_PORT, GRPC_PORT) — exactly the ports
	// the host test process talks to. The runner allocates a free TCP port
	// for each so parallel targets never collide, replacing setup-env.sh's
	// node/get-port-please randomisation.
	Ports []string
	// Refs is every ${VAR} the compose file interpolates (host-exposed or
	// not). The runner fills known test defaults (POSTGRES_USER/PASSWORD/DB/
	// HOST) for any it references, so an internal-only postgres — which has
	// no host port and thus no entry in Ports — still gets credentials.
	Refs []string
	// Profiles maps a compose `profiles: ["x"]` value to the service name
	// that carries it (e.g. "rest" → "service-json-keys-rest"). `run` uses
	// this to know which compose service to bring up when a target is
	// requested in dockerised mode (`podman compose --profile x up <svc>`).
	Profiles map[string]string
	// Services lists every compose service declared under `services:`, in
	// source order. The runner uses it to compute the set of services to
	// bring up at env-up time — in global mode it skips any sibling service
	// that is also being run from its own repo (avoiding duplicates).
	Services []string
}

ComposeEnv is a podman-compose test environment discovered from a builds/podman-compose.<id>.test.yaml file.

type Kind

type Kind string

Kind classifies a build target. Its string value doubles as the user-facing group label and the value accepted by the `--type` filter.

const (
	KindGo     Kind = "go"
	KindPnpm   Kind = "pnpm"
	KindPodman Kind = "podman"
	// KindContainer is a run-mode target: a compose service guarded by a
	// profile that the runner brings up via `podman compose --profile X
	// up <svc>`. Distinct from KindPodman (build's Dockerfile targets) so
	// the two never collide in pickers / dispatch — KindContainer only
	// appears via DetectRun in container mode.
	KindContainer Kind = "container"
)

type Target

type Target struct {
	Kind Kind

	// Name is the unit's short identity within its directory, e.g. the module
	// name (go), the script name "build:rest" (pnpm), or "rest.Dockerfile"
	// (podman). It is NOT unique on its own — pair it with RelDir.
	Name string

	// Service is the owning repo/module short name (e.g. "service-json-keys").
	// Set for `run` targets so the UI can disambiguate identically-named
	// entrypoints across services (a "rest" exists in every service). Empty
	// for build/test where Name+RelDir already suffice.
	Service string

	// RelDir is the target's directory relative to the scan root ("." for the
	// root itself). Used for display grouping and de-duplication.
	RelDir string

	// Dir is the absolute working directory the command executes in.
	Dir string

	// Detail is a one-line, human-readable summary shown under the target in
	// the menu and report (the resolved image tag, the script body, …).
	Detail string

	// Cmd and Args are the exact process to spawn, executed with Dir as CWD.
	Cmd  string
	Args []string

	// Env, when non-nil, is a podman-compose environment that must be up
	// before the command runs and torn down after. Only test targets set it.
	Env *ComposeEnv

	// ComposeService is the compose service name that would run this target
	// dockerised — populated by `run` detection when the target's name
	// matches a profile in its env's compose file (e.g. "rest" →
	// "service-json-keys-rest"). Empty means dockerised mode cannot run this
	// target (one-shots like migrations / rotate-keys / init have no compose
	// service); the runner falls back to local exec for those.
	ComposeService string
}

Target is a single selectable, runnable build unit.

func Detect

func Detect(root string) ([]Target, error)

Detect walks root and returns every build target found, sorted for stable presentation (by kind, then directory, then name).

func DetectRun

func DetectRun(root string) ([]Target, error)

DetectRun is the run-suite counterpart of Detect/DetectTests. It discovers long-lived entrypoints:

  • Go: every `package main` directory (one target per cmd/…), run via `go run ./<relpath>` from the owning module root.
  • pnpm: every package.json script named "run" or "run:*".

Each target is wired to a compose env the same way tests are, with one addition: if no target-specific builds/podman-compose.<id>.yaml matches, a plain builds/podman-compose.yaml (the runtime stack) is used as a fallback. Run projects are prefixed "anovel-run-" so they never collide with the "anovel-test-" projects of a concurrent test run.

func DetectTests

func DetectTests(root string) ([]Target, error)

DetectTests is the test-suite counterpart of Detect. It discovers:

  • Go test targets — one per Go module. When the module ships builds/podman-compose.go[.<path>].test.yaml files, one target per file scoped to that path (`go test ./<path>/...`) with the compose env attached; otherwise a single env-less `go test ./...`.
  • pnpm test targets — every package.json script named "test" or "test:*". A builds/podman-compose.pnpm[.<path>].test.yaml whose path matches the script is attached as that script's env.

The env filename convention is `podman-compose.<id>.test.yaml` where <id> is the environment ("go"/"pnpm") followed by the dotted test path it covers ("go.internal", "go.pkg", "pnpm"); a bare env id covers the whole suite.

func (Target) ID

func (t Target) ID() string

ID is a stable, unique key for a target (used as a selection-map key and to keep the menu order deterministic across runs).

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL