external

package
v0.3.2 Latest Latest
Warning

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

Go to latest
Published: Aug 29, 2026 License: Apache-2.0 Imports: 9 Imported by: 0

Documentation

Overview

Package external resolves whether a CANARY requirement ID is satisfied as an external dependency — one owned by a ticket-source (e.g. JIRA) or a peer project (see resolvePeer) rather than this project's own flatfile series. It answers purely from on-disk sources: the remote-status cache (.canary/remote-status.json, written by `canary ticket sync --apply` and `canary ticket status --refresh` in pkg/cmds/ticket) and configured peers' status.json files. This package performs NO network I/O, ever — a missing or stale cache, or an unreachable/malformed peer file, degrades to State=unknown (or falls through to the next source) rather than blocking or erroring. CANARY: REQ=ENG-3959; FEATURE="ExternalResolve"; ASPECT=Engine; STATUS=TESTED; TEST=TestCANARY_ENG_3959_Cache_RoundTrip,TestCANARY_ENG_3959_Cache_LoadMissing_NoError,TestCANARY_ENG_3959_Cache_LoadCorrupt_Error,TestCANARY_ENG_3959_Resolve_FlatfileSource_Unknown,TestCANARY_ENG_3959_Resolve_UnresolvedPrefix_Unknown,TestCANARY_ENG_3959_Resolve_NilRegistry_Unknown,TestCANARY_ENG_3959_Resolve_NoCacheFile_Unknown,TestCANARY_ENG_3959_Resolve_CachedDone_Satisfied,TestCANARY_ENG_3959_Resolve_CachedNotDone_Unsatisfied,TestCANARY_ENG_3959_Resolve_AbsentFromCache_Unknown,TestCANARY_ENG_3959_Resolve_CustomStatusMap_DoneSet,TestCANARY_ENG_3959_Resolve_StaleCache_DetailNote,TestCANARY_ENG_3959_Resolve_FreshCache_NoStaleNote,TestCANARY_ENG_3960_Resolution_IsExternal,TestCANARY_ENG_3960_Resolution_ShortDetail; UPDATED=2026-08-29 CANARY: REQ=ENG-3961; FEATURE="PeerProjects"; ASPECT=Engine; STATUS=TESTED; TEST=TestCANARY_ENG_3961_Resolve_PeerSatisfied,TestCANARY_ENG_3961_Resolve_PeerUnsatisfied,TestCANARY_ENG_3961_Resolve_PeerNotFound,TestCANARY_ENG_3961_Resolve_PeerMissingFile,TestCANARY_ENG_3961_Resolve_PeerMalformedJSON,TestCANARY_ENG_3961_Resolve_PeerRelativeRoot,TestCANARY_ENG_3961_Resolve_PeerBeatsTicketCache,TestCANARY_ENG_3961_Resolve_UnknownPrefixResolvedByPeer,TestCANARY_ENG_3961_Resolve_LocalFlatfileNeverConsultsPeer,TestCANARY_ENG_3961_Resolve_SecondPeerFallsThroughFirst; UPDATED=2026-08-29

Index

Constants

View Source
const (
	StateSatisfied   = "satisfied"
	StateUnsatisfied = "unsatisfied"
	StateUnknown     = "unknown"
)

State values for Resolution.State.

View Source
const CacheFileName = "remote-status.json"

CacheFileName is the remote-status cache's basename under .canary/.

Variables

This section is empty.

Functions

func CachePath

func CachePath(root string) string

CachePath returns the remote-status cache path under root.

func SaveCache

func SaveCache(root string, statuses map[string]string, fetchedAt time.Time) error

SaveCache writes statuses to root's .canary/remote-status.json with fetchedAt (converted to UTC) as fetched_at, creating .canary/ if needed. Written with mode 0600 — this file only ever holds ticket-system status names, but is treated as project-local state, not something to expose group/world-readable.

Types

type Cache

type Cache struct {
	FetchedAt string            `json:"fetched_at"`
	Statuses  map[string]string `json:"statuses"`
}

Cache is the on-disk shape of .canary/remote-status.json: the last time a fetch succeeded, and the issue-key -> remote-status-name snapshot it produced.

func LoadCache

func LoadCache(root string) (*Cache, error)

LoadCache reads the cache at root's .canary/remote-status.json. A missing file is not an error — it returns (nil, nil), the "no cache yet" case callers must degrade gracefully on.

type Resolution

type Resolution struct {
	ID     string
	State  string // satisfied | unsatisfied | unknown
	Detail string
}

Resolution is the outcome of resolving one requirement ID as a possible external dependency.

func Resolve

func Resolve(id string, reg *sources.Registry, root string) Resolution

Resolve determines whether id is satisfied as an external dependency.

  1. id is external (resolves to a non-flatfile source) OR has an unknown prefix (resolves to no configured source at all, including when reg is nil): every configured peer project is consulted, in declaration order, BEFORE the ticket cache below. This is the inter-dependent-repos case: a peer may own an id under a key this project's own sources: list never heard of. Peers are drawn from reg.Peers() when reg != nil (no additional config.Load); otherwise peers are loaded fresh from root's .canary/project.yaml for backward compatibility. A known local (flatfile) id never consults peers — it is unambiguously this project's own. See resolvePeer for the peer-file contract.
  2. id resolves to a flatfile source, or to no configured source at all (and no peer claimed it): State=unknown, Detail="not external" — callers treat this as a local requirement, not an external one.
  3. id resolves to a ticket-source (jira/github/gitlab) and no peer claimed it: the cache is read (never fetched — this package performs no network I/O). - No cache file, or the cache holds no entry for id: State=unknown, Detail points at `canary ticket status --refresh`. - id's cached status is in the source's done-set (its StatusMap's TESTED/BENCHED names, defaulting to {"Done"}): State=satisfied, Detail is the cached status name. - id's cached status is present but not in the done-set: State=unsatisfied, Detail is the cached status name.

Whenever a cache file exists and its fetched_at is more than 24h old (relative to CANARY_TEST_TIMESTAMP when set, else now in UTC), a staleness note is appended to Detail — the cache is still used; a stale answer is strictly better than none (degradation is sacred).

func (Resolution) IsExternal

func (r Resolution) IsExternal() bool

IsExternal reports whether r describes an actual external (ticket-source) dependency, as opposed to a local/flatfile id or an unconfigured prefix — the case Resolve marks with Detail "not external". Callers (deps/next/view) use this to decide whether to apply external-dependency display/blocking rules at all.

func (Resolution) ShortDetail

func (r Resolution) ShortDetail() string

ShortDetail returns a short, display-friendly rendering of r.Detail: the cached remote-status name (with any appended staleness note stripped) for satisfied/unsatisfied, or the fixed short note "no cached ticket status" for unknown — dropping the longer refresh-hint command suggestion so callers like `deps check` and `view` stay on one line.

Jump to

Keyboard shortcuts

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