Documentation
¶
Overview ¶
Package lockfile manages CLI lockfile state: loading, saving, and converting the on-disk format.
Index ¶
- Variables
- type DirectTracker
- type MetadataResolver
- type State
- func (s *State) AllDeps() []dep.Dependency
- func (s *State) File() parserlock.File
- func (s *State) Get(workflowKey string) ([]dep.Dependency, error)
- func (s *State) HasWorkflow(workflowKey string) bool
- func (s *State) Save() error
- func (s *State) Set(ctx context.Context, workflowKey string, deps []dep.Dependency, ...) error
Constants ¶
This section is empty.
Variables ¶
var ErrCorruptLockfile = errors.New("lockfile is unreadable")
ErrCorruptLockfile reports that a lockfile exists on disk but cannot be parsed (malformed YAML, unknown fields, or a dependency entry missing a required key). It is distinct from a missing lockfile (legitimately empty) and from a future-version lockfile (ErrFutureVersion). Callers decide recovery policy: prompt to delete and recreate, or fail loudly. Loading must never silently discard an unreadable lockfile and overwrite it.
Functions ¶
This section is empty.
Types ¶
type DirectTracker ¶
type DirectTracker struct {
// contains filtered or unexported fields
}
DirectTracker captures, by dep index, which resolved deps correspond to a workflow's direct uses: refs. Build it from the freshly resolved deps (before any narrowing/normalization mutates dep.Ref), then read the final NWO@Ref direct-key set back with Keys after mutation.
Keys takes the (possibly reassigned) deps slice so callers that swap the slice for an index-aligned copy — e.g. PreserveRefs — still resolve to the post-mutation refs. The index alignment is the contract: every transform between NewDirectTracker and Keys must preserve dep order and length.
Directness is determined by the workflow file's own uses: refs, not by the resolver parent map. A dep that is both a direct use and a composite transitive dep (e.g. actions/setup-go used directly and also pulled in by a composite) has a parent in the parent map but must still be recorded as a workflow-direct pin — otherwise it is perpetually re-flagged as not-pinned.
func NewDirectTracker ¶
func NewDirectTracker(refs []parserlock.ActionRef, deps []dep.Dependency) DirectTracker
NewDirectTracker records which entries of deps match one of the workflow's direct refs, by NWO@Ref, at the deps' current (pre-mutation) refs.
func (DirectTracker) Keys ¶
func (t DirectTracker) Keys(deps []dep.Dependency) map[string]bool
Keys returns the set of workflow-direct NWO@Ref keys, reading each dep's current (post-mutation) Key() from the supplied index-aligned slice.
type MetadataResolver ¶
type MetadataResolver interface {
RepoIDs(ctx context.Context, owner, repo string) (ownerID, repoID int64, err error)
}
MetadataResolver fetches the owner/repo numeric IDs for a NWO. The store needs these to populate the dependencies: section on every write.
type State ¶
type State struct {
// contains filtered or unexported fields
}
State wraps the on-disk dependency lockfile for the current invocation. Save garbage-collects orphan dependencies: entries — entries still referenced by an out-of-scope workflow are preserved, so partial invocations (e.g. `upgrade workflows/foo.yml`) stay noop on unrelated workflows.
State is safe for concurrent use: Set/Save/Get/File/AllDeps/lookupIDs all take the same mutex, allowing parallel pin and upgrade workers to share a single store instance without external synchronization.
func LoadState ¶
func LoadState(repoRoot string, meta MetadataResolver) (*State, error)
LoadState reads the lockfile at repoRoot, returning an empty in-memory file when none exists on disk. A lockfile that exists but cannot be parsed is surfaced as ErrCorruptLockfile rather than being silently treated as empty.
func LoadStateAt ¶
func LoadStateAt(lockfilePath string, meta MetadataResolver) (*State, error)
LoadStateAt reads the lockfile at the given path, returning an empty in-memory file when none exists on disk. Use this when the lockfile lives outside the standard .github/workflows/ location.
func (*State) AllDeps ¶
func (s *State) AllDeps() []dep.Dependency
AllDeps returns every action entry in the lockfile as a Dependency, populated with Tag and Branch from the action metadata block. Order is undefined. Intended for callers that need the union of recorded pins across all workflows (e.g. seeding resolver caches on startup).
func (*State) File ¶
func (s *State) File() parserlock.File
File returns the in-memory parser-level lockfile snapshot. Intended for consumers that drive the workflow-parser diagnostics engine directly and need the whole file (workflow keys + actions metadata) in one shot.
func (*State) Get ¶
func (s *State) Get(workflowKey string) ([]dep.Dependency, error)
Get returns the dependencies recorded for workflowKey (e.g. ".github/workflows/ci.yml"). Returns nil when the workflow has no entry.
func (*State) HasWorkflow ¶
HasWorkflow reports whether the lockfile's workflows{} map already contains an entry for workflowKey. Used by `upgrade --no-onboard` to refuse silently onboarding a previously-untracked workflow during a Dependabot run.
func (*State) Save ¶
Save persists the lockfile to disk, garbage-collecting orphan action entries (pins referenced by no workflow). When the in-memory file is empty after GC, the on-disk file is removed.
func (*State) Set ¶
func (s *State) Set(ctx context.Context, workflowKey string, deps []dep.Dependency, parentMap map[string][]string, directKeys map[string]bool) error
Set replaces the workflow's direct-dependency entry and upserts the per-action metadata for every pin in the resolved closure. The workflow entry holds only the action refs that appear in the workflow file itself (its direct uses); per-action `uses:` lists encode the transitive graph, so a reader walks from each direct pin to reconstruct the full closure — the npm/cargo lockfile model.
parentMap is the resolver's child → []parent map (Dependency.Key() form: NWO@Ref, without the SHA suffix), as returned by Resolver.ParentMap. Set uses it to build per-action `uses:` lists by inversion. Both sides are translated into canonical pin keys (NWO@Ref:algo-hex).
directKeys is the set of Dependency.Key() values (NWO@Ref) that the workflow file uses directly. It is authoritative for the workflow's direct-pin list: a dep is recorded as workflow-direct iff its key is in directKeys. This correctly handles deps that are both a direct use and a composite-transitive dep (e.g. actions/setup-go used directly and also pulled in by a composite) — such a dep has a parent in parentMap but must still appear in the workflow's direct list. When directKeys is nil, Set falls back to treating any dep with no parent in parentMap as direct.
Resolution of owner/repo numeric IDs happens lazily per NWO and is cached for the lifetime of the store.