Documentation
¶
Overview ¶
Package pkg provides package management actions for the operation graph.
Index ¶
- Constants
- type MutationKind
- type Observation
- type Provider
- func (p *Provider) CompensateInstall(activation *op.ActivationRecord, stack *op.RecoveryStack) error
- func (p *Provider) CompensatePackageMutation(activationRecord *op.ActivationRecord, receipt *Receipt) error
- func (p *Provider) CompensateRemove(activation *op.ActivationRecord, stack *op.RecoveryStack) error
- func (p *Provider) CompensateUpgrade(activation *op.ActivationRecord, stack *op.RecoveryStack) error
- func (p *Provider) Install(activationRecord *op.ActivationRecord, packages []Resource, ...) (result []Resource, stack *op.RecoveryStack, err error)
- func (p *Provider) Installed(name Resource) (bool, error)
- func (p *Provider) NotInstalled(name Resource) (bool, error)
- func (p *Provider) Observe(resource Resource) (*Observation, error)
- func (p *Provider) Remove(activationRecord *op.ActivationRecord, packages []Resource, ...) (result []Resource, stack *op.RecoveryStack, err error)
- func (p *Provider) Update() error
- func (p *Provider) Upgrade(activationRecord *op.ActivationRecord, packages []Resource, ...) (result []Resource, stack *op.RecoveryStack, err error)
- func (p *Provider) VersionGTE(name Resource, version string) (bool, error)
- type Receipt
- type Resource
Constants ¶
const ( Install op.ActionName = "pkg.install" Installed op.ActionName = "pkg.installed" NotInstalled op.ActionName = "pkg.not_installed" Observe op.ActionName = "pkg.observe" Remove op.ActionName = "pkg.remove" Update op.ActionName = "pkg.update" Upgrade op.ActionName = "pkg.upgrade" VersionGTE op.ActionName = "pkg.version_gte" )
Action-name constants for the pkg provider's plan-mode actions.
Each constant is the short dotted action label its method dispatches under. Pass these to plan.Plan, op.ReceiverRegistry().BuildAction, RuntimeEnvironment.ActionByName, or WithActionNamed in place of a string literal so a typo is a compile error and rename / find-references work through the constant.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type MutationKind ¶
type MutationKind string
MutationKind identifies the package mutation a Receipt records, so Provider.CompensatePackageMutation can invert it: remove a newly-installed package, restore a pre-existing one's prior version, reinstall a removed package, or best-effort restore an upgraded package's prior version.
const ( // MutationInstall records an install; its undo removes a newly-installed package, or restores a pre-existing one's // prior version when the install drifted it. MutationInstall MutationKind = "install" // MutationRemove records a removal; its undo reinstalls a package that was present before. MutationRemove MutationKind = "remove" // MutationUpgrade records an upgrade; its undo best-effort restores the package's prior version. MutationUpgrade MutationKind = "upgrade" )
type Observation ¶
type Observation struct {
op.ObservationBase
// Version is the version string the platform's package manager reports for the package at
// observation time. Empty when `Exists` is false.
Version string
}
Observation captures the runtime-observed state of a Resource (a host package) at the moment it was observed.
Distinct from Resource, which carries identity (the purl URI, `Name`, `Type`). An observation is a point-in-time metadata snapshot record — not a Resource, never cataloged — whose identity comes from the resource it references (op.ObservationBase.OfResource, by pointer value). It embeds op.ObservationBase (the back-link + op.ObservationBase.Exists) and adds the package-specific measurement field: `Version`.
func NewObservation ¶
func NewObservation(ofResource Resource, exists bool, version string) *Observation
NewObservation constructs a *Observation anchored to the resource it observes.
Parameters:
- `ofResource`: the Resource this observation is of. Must be non-nil (asserted by op.NewObservationBase).
- `exists`: true when the package was installed at observation time.
- `version`: the installed version reported by the package manager.
Returns:
- `*Observation`: the constructed observation.
func (*Observation) String ¶
func (o *Observation) String() string
String returns a debug-oriented single-line representation of the observation.
Returns:
- `string`: `pkg.Observation{of=<OfResource.URI()>, exists=<bool>, version=<string>}`.
type Provider ¶
type Provider struct {
op.ProviderBase
}
Provider is a thin veneer over the platform's Composite package-manager router.
It carries no convergence policy of its own: each verb projects its Resource slice into a platform.PURL slice, calls the router once, and adapts the router's per-package platform.Receipt slice into the provider's *Receipt compensation state. All convergence and verification live in the platform's leaf drivers.
func NewProvider ¶
func NewProvider(runtimeEnvironment *op.RuntimeEnvironment) *Provider
NewProvider constructs a package-management Provider bound to the given runtime environment.
Parameters:
- `runtimeEnvironment`: the runtime environment that supplies the platform abstraction and status sink.
Returns:
- `*Provider`: the initialized provider.
func (*Provider) CompensateInstall ¶
func (p *Provider) CompensateInstall(activation *op.ActivationRecord, stack *op.RecoveryStack) error
CompensateInstall reverses an install by unwinding its recovery stack.
Each entry is a self-describing *Receipt naming Provider.CompensatePackageMutation, so unwinding removes each newly-installed package and restores any pre-existing one whose version the install drifted.
Parameters:
- `activation`: the per-dispatch record; supplies the *op.RuntimeEnvironment passed to op.RecoveryStack.Unwind.
- `stack`: the recovery stack Provider.Install returned as its compensator; a nil stack returns nil.
Returns:
- `error`: the joined errors from the per-package compensations, or nil when all succeed.
func (*Provider) CompensatePackageMutation ¶
func (p *Provider) CompensatePackageMutation(activationRecord *op.ActivationRecord, receipt *Receipt) error
CompensatePackageMutation inverts one package mutation, dispatching on the receipt's MutationKind: remove a newly-installed package or restore a pre-existing one's drifted version (install), reinstall a removed package (remove), or best-effort restore an upgraded package's prior version (upgrade). It is the single undo named by every package receipt; the verb companions (Provider.CompensateInstall / Provider.CompensateRemove / Provider.CompensateUpgrade) just unwind the stack of these.
Parameters:
- `activationRecord`: the dispatch activation (the required floor for compensating actions — step 27).
- `receipt`: the package *Receipt to invert; a nil receipt or nil resource is a no-op.
Returns:
- `error`: a missing platform, an unknown kind, or any removal / reinstall failure.
func (*Provider) CompensateRemove ¶
func (p *Provider) CompensateRemove(activation *op.ActivationRecord, stack *op.RecoveryStack) error
CompensateRemove reverses a removal by unwinding its recovery stack — each entry reinstalls a package that was present before.
Parameters:
- `activation`: the per-dispatch record; supplies the *op.RuntimeEnvironment passed to op.RecoveryStack.Unwind.
- `stack`: the recovery stack Provider.Remove returned as its compensator; a nil stack returns nil.
Returns:
- `error`: the joined errors from the per-package compensations, or nil when all succeed.
func (*Provider) CompensateUpgrade ¶
func (p *Provider) CompensateUpgrade(activation *op.ActivationRecord, stack *op.RecoveryStack) error
CompensateUpgrade reverses an upgrade by unwinding its recovery stack — each entry best-effort restores its package's prior version.
Parameters:
- `activation`: the per-dispatch record; supplies the *op.RuntimeEnvironment passed to op.RecoveryStack.Unwind.
- `stack`: the recovery stack Provider.Upgrade returned as its compensator; a nil stack returns nil.
Returns:
- `error`: the joined errors from the per-package compensations, or nil when all succeed.
func (*Provider) Install ¶
func (p *Provider) Install( activationRecord *op.ActivationRecord, packages []Resource, kwargs map[string]any, ) (result []Resource, stack *op.RecoveryStack, err error)
Install installs each package via the platform's Composite router.
Parameters:
- `activationRecord`: the dispatch activation (the required floor for compensable actions — step 27).
- `packages`: package resources to install, each carrying its requested version.
- `kwargs`: opaque native-installer flags passed through to the routed leaf (e.g. `cask`).
Returns:
- `result`: the input packages, each with Type set to the purl type of the leaf that handled it.
- `stack`: a op.RecoveryStack carrying one self-describing *Receipt per package, in input order, so a failed run unwinds it in reverse — each receipt routes to Provider.CompensatePackageMutation.
- `error`: non-nil if no packages were specified, no platform is available, or any package failed to install.
func (*Provider) Installed ¶
Installed reports whether the named package is installed, querying the router by purl.
Parameters:
- `name`: the package resource to check.
Returns:
- `bool`: true when the package is installed.
- `error`: non-nil when no platform is available.
func (*Provider) NotInstalled ¶
NotInstalled reports whether the named package is not installed, querying the router by purl.
Parameters:
- `name`: the package resource to check.
Returns:
- `bool`: true when the package is not installed.
- `error`: non-nil when no platform is available.
func (*Provider) Observe ¶
func (p *Provider) Observe(resource Resource) (*Observation, error)
Observe captures the runtime-observed state of `resource` as an *Observation.
Asks the platform's Composite router for the installed version of the package identified by `resource`. When a platform exists and the router reports a non-empty version, the Observation carries `Exists=true` and the version string; otherwise it carries `Exists=false`.
Parameters:
- `resource`: the Resource whose installed state to observe.
Returns:
- `*Observation`: the constructed observation; never nil.
- `error`: always nil — a missing platform or an uninstalled package is a valid observation, not a failure; the error return keeps the announced fallible-action shape.
func (*Provider) Remove ¶
func (p *Provider) Remove( activationRecord *op.ActivationRecord, packages []Resource, kwargs map[string]any, ) (result []Resource, stack *op.RecoveryStack, err error)
Remove removes each package via the platform's Composite router.
Parameters:
- `activationRecord`: the dispatch activation (the required floor for compensable actions — step 27).
- `packages`: package resources to remove.
- `kwargs`: opaque native-installer flags passed through to the routed leaf.
Returns:
- `result`: the input packages, each with Type set to the purl type of the leaf that handled it.
- `stack`: a op.RecoveryStack carrying one self-describing *Receipt per package, in input order.
- `error`: non-nil if no packages were specified, no platform is available, or any package failed to remove.
func (*Provider) Update ¶
Update forces an immediate index refresh on every leaf via the platform's Composite router.
Returns:
- `error`: aggregated per-leaf refresh failures, or non-nil when no platform is available.
func (*Provider) Upgrade ¶
func (p *Provider) Upgrade( activationRecord *op.ActivationRecord, packages []Resource, kwargs map[string]any, ) (result []Resource, stack *op.RecoveryStack, err error)
Upgrade upgrades each package to the latest available version via the platform's Composite router.
Parameters:
- `activationRecord`: the dispatch activation (the required floor for compensable actions — step 27).
- `packages`: package resources to upgrade.
- `kwargs`: opaque native-installer flags passed through to the routed leaf.
Returns:
- `result`: the input packages, each with Type set to the purl type of the leaf that handled it.
- `stack`: a op.RecoveryStack carrying one self-describing *Receipt per package, in input order.
- `error`: non-nil if no packages were specified, no platform is available, or any package failed to upgrade.
func (*Provider) VersionGTE ¶
VersionGTE reports whether the installed version of `name` is greater than or equal to `version`.
Parameters:
- `name`: the package resource to check.
- `version`: the minimum version string to compare against.
Returns:
- `bool`: true when the installed version is non-empty and >= `version`.
- `error`: non-nil when no platform is available.
type Receipt ¶
type Receipt struct {
op.ReceiptBase
// Manager is the purl type of the leaf that handled the package.
Manager string
// InstalledBefore records whether the package was present before the action.
InstalledBefore bool
// PreviousVersion is the version observed before the action.
PreviousVersion string
// contains filtered or unexported fields
}
Receipt holds the per-package compensation state Provider.CompensatePackageMutation needs to undo one package mutation.
The embedded op.ReceiptBase carries the affected Resource and the opaque op.ReceiptBase.TransactionID minted at op.ReceiptBase.Commit. One Receipt records one package: `kind` is the mutation it undoes, `Manager` is the purl type of the leaf that handled it, `InstalledBefore` records whether the package was present before the action (so unwind does not remove a package the user already had), and `PreviousVersion` is the version observed before the action (so an upgrade or a drifted install can be best-effort restored). A multi-package verb pushes one Receipt per package onto a op.RecoveryStack.
func NewReceipt ¶
func NewReceipt(resource Resource, kind MutationKind, manager string, installedBefore bool, previousVersion string) *Receipt
NewReceipt builds a per-package *Receipt that declares its undo at construction.
The receipt names [compensatePackageMutationAction] as its compensating action (so Provider.CompensatePackageMutation inverts it regardless of which verb or dispatcher created it) and records the mutation kind and the package fields. The transactionID is minted later at op.ReceiptBase.Commit.
Parameters:
- `resource`: the package Resource the mutation affected.
- `kind`: the MutationKind the receipt records.
- `manager`: the purl type of the leaf that handled the package.
- `installedBefore`: whether the package was present before the action.
- `previousVersion`: the version observed before the action.
Returns:
- `*Receipt`: the constructed receipt, born naming its compensator.
func (*Receipt) Kind ¶
func (r *Receipt) Kind() MutationKind
Kind returns the MutationKind this receipt records, or "" when unset.
Returns:
- `MutationKind`: the recorded mutation kind.
func (*Receipt) MarshalJSON ¶
MarshalJSON encodes the receipt's compensation state as JSON.
Delegates to Receipt.MarshalYAML for the serialized-shape value, then runs json.Marshal over it.
Returns:
- `[]byte`: JSON-encoded object carrying the receipt's resource URI and package fields.
- `error`: any error from Receipt.MarshalYAML or json.Marshal.
func (*Receipt) MarshalYAML ¶
MarshalYAML returns the receipt's compensation state as an anonymous struct value the encoder serializes.
This is the `receipt` sub-field the recovery stack embeds: the resource URI, transaction id, mutation kind, and the package fields. The base execution state (`action`/`compensating_action`/`result`/`status`) rides the stack-owned envelope, so it is not repeated here; resume reconstructs the receipt in Receipt.RestoreEncoded.
Returns:
- `any`: the populated anonymous struct for the encoder to walk.
- `error`: nil under normal conditions.
func (*Receipt) RestoreEncoded ¶
func (r *Receipt) RestoreEncoded( runtimeEnvironment *op.RuntimeEnvironment, base op.ReceiptData, fields map[string]any, ) error
RestoreEncoded reconstructs the receipt from its codec-decoded envelope.
It is the op.Receipt.RestoreEncoded override for package receipts. The recovery stack already decoded the envelope, so this consumes decoded values, never bytes: `base` carries the execution state and `fields` the receipt sub-field. It rehydrates the resource from its URI via DiscoverResource, seeds the base via op.NewReceiptBase + op.ReceiptBase.Restore, and restores the kind and package fields.
Parameters:
- `runtimeEnvironment`: the resume environment; its catalog must hold (or be able to construct) the resource.
- `base`: the codec-decoded base execution state.
- `fields`: the receipt sub-field, decoded to a format-neutral map.
Returns:
- `error`: a missing catalog or a DiscoverResource failure (an external-system interaction). The envelope itself arrives post-op.LoadTrace — checksum-verified — so document-derived failures panic (docs/architecture/5-graph-trace-integrity.md).
type Resource ¶
type Resource interface {
op.Resource
// Name returns the package name ("jq", "curl", "VisualStudioCode"). Identity-bearing.
Name() string
// Type returns the purl type — the manager ("brew", "deb", "port", "winget"). Identity-bearing as
// requested; after an install the provider resolves it to the manager that actually handled the
// package, in-package, so a reader sees the resolved type.
Type() string
// Version returns the requested version (the purl `@version`); empty means latest. Not identity.
Version() string
// contains filtered or unexported methods
}
Resource is this provider's resource type — the sealed interface over a host package identified by its package-URL (purl) coordinates.
Sealed by an unexported marker, so the closed set of implementations is the one this package declares and no value reaching a pkg method was built anywhere else. That is the guarantee the resource model rests on: identity is the catalog key, and a hand-built or reflectively-hydrated value carries none.
Location-keyed: `Name` and `Type` together form the versionless purl encoded in the op.ResourceBase URI, so "git" and "git@2.39.0" intern to the same catalog entry. `Version` is the requested version (the purl `@version`; empty means latest) — mutable state on the Resource, not part of its identity. Runtime-observed state (the installed version the platform's package manager reports) lives on a separate *Observation minted by Provider.Observe, never on the Resource.
func DiscoverResource ¶
func DiscoverResource(runtimeEnvironment *op.RuntimeEnvironment, value any) (Resource, error)
DiscoverResource registers a pkg.Resource via op.ResourceCatalog.Discover without claiming production.
Used by the framework's resource registry adapter for slot coercion (when starlark supplies a string package name and the slot expects a pkg.Resource), and by callers holding a reference handle without claiming production (receipt rehydration is the canonical example).
Discover does not stamp a producer, so unlike NewResource it takes only `runtimeEnvironment` — no unit reference is needed.
Nil-Catalog tolerance: returns the unlinked candidate when no catalog is present.
Parameters:
- `runtimeEnvironment`: the session runtime environment.
- `value`: a string package name with an optional manager prefix.
Returns:
- `Resource`: the canonical catalog entry (or the unlinked candidate when no catalog is present).
- `error`: if `value` is not a string or the manager prefix is unknown.
func NewResource ¶
func NewResource(runtimeEnvironment *op.RuntimeEnvironment, producerID string, value any) (Resource, error)
NewResource constructs a pkg.Resource and claims production via op.ResourceCatalog.GetOrCreate.
Use NewResource from a producer dispatch context — typically a provider method that has received an op.ActivationRecord from the framework. The returned Resource is the canonical catalog entry, stamped with `producerID = activationRecord.CallerID.ID()` (or empty when `Unit` is nil for non-graph dispatch). Use DiscoverResource instead when the caller is not claiming production (rehydration, reference handles, the framework's slot-coercion adapter).
Today no pkg provider method actually claims production — Install / Remove / Upgrade all take an existing `[]*Resource` and return the same pointers with their `Type` field updated to reflect which platform manager handled them. URIs (purls) are unchanged. NewResource exists for symmetry with the m.4 two-constructor pattern and as a stable surface for any future pkg producer that creates a new purl.
The value is a string package name with an optional manager prefix and optional version (e.g., "jq", "brew:jq", "port:wget", "git@2.39.0"). When no prefix is present, the platform's default purl type is used; the prefix otherwise resolves through platform.Platform.ResolvePurlType. The `@version` tail becomes the Resource's requested version and is excluded from the versionless catalog URI.
Nil-Catalog tolerance: returns the unlinked candidate when no catalog is present.
Parameters:
- `runtimeEnvironment`: the session runtime environment (must have `Platform` set).
- `producerID`: the producing caller's id (`activationRecord.CallerID`), or "" for caller-less dispatch. for non-graph dispatch.
- `value`: a string package name with an optional manager prefix.
Returns:
- `Resource`: the canonical catalog entry (or the unlinked candidate when no catalog is present).
- `error`: if `value` is not a string or the manager prefix is unknown.