internal/rosa: pass stage alongside state

This cleans up many function signatures.

Signed-off-by: Ophestra <cat@gensokyo.uk>
This commit is contained in:
2026-05-17 16:44:13 +09:00
parent 30eb0d6a61
commit 38bc2c7508
89 changed files with 563 additions and 558 deletions

View File

@@ -20,30 +20,43 @@ import (
type ArtifactH unique.Handle[string]
// String returns the name of p.
func (p ArtifactH) String() string {
return unique.Handle[string](p).Value()
func (handle ArtifactH) String() string {
return unique.Handle[string](handle).Value()
}
// MarshalJSON represents [ArtifactH] by its [Artifact.Name].
func (p ArtifactH) MarshalJSON() ([]byte, error) { return json.Marshal(p.String()) }
func (handle ArtifactH) MarshalJSON() ([]byte, error) {
return json.Marshal(handle.String())
}
// UnmarshalJSON resolves [ArtifactH] by its [Artifact.Name].
func (p *ArtifactH) UnmarshalJSON(data []byte) error {
func (handle *ArtifactH) UnmarshalJSON(data []byte) error {
var name string
if err := json.Unmarshal(data, &name); err != nil {
return err
}
*p = ArtifactH(unique.Make(name))
*handle = ArtifactH(unique.Make(name))
return nil
}
type (
// Stage denotes the infrastructure to compile a [pkg.Artifact] on.
Stage uint32
// Toolchain refers to an instance of [S], and a [Stage] to compile on.
Toolchain struct {
stage Stage
*S
}
)
// P represents multiple [ArtifactH].
type P []ArtifactH
// Artifact is stage-agnostic immutable data with a deterministic resulting
// [pkg.Artifact]. It can be created natively or through evaluation.
type Artifact struct {
f func(t Toolchain, s *S) (a pkg.Artifact, version string)
f func(t Toolchain) (a pkg.Artifact, version string)
// Unique package name.
Name string `json:"name"`
@@ -159,7 +172,7 @@ type S struct {
opts int
// Cached [pkg.Artifact].
c [_toolchainEnd]sync.Map
c [_stageEnd]sync.Map
// URL of a Gentoo stage3 tarball.
gentooStage3 string
@@ -208,9 +221,9 @@ func (s *S) DropCaches(targetArch string, flags int) {
}
// Get returns the address of the named [Artifact].
func (s *S) Get(p ArtifactH) (meta *Artifact) {
func (s *S) Get(handle ArtifactH) (meta *Artifact) {
s.wantsArch()
v, ok := s.artifacts.Load(p)
v, ok := s.artifacts.Load(handle)
if ok {
meta = v.(*Artifact)
}
@@ -218,38 +231,46 @@ func (s *S) Get(p ArtifactH) (meta *Artifact) {
}
// MustGet is like Get, but panics if the named [Artifact] is not registered.
func (s *S) MustGet(p ArtifactH) (meta *Artifact) {
meta = s.Get(p)
func (s *S) MustGet(handle ArtifactH) (meta *Artifact) {
meta = s.Get(handle)
if meta == nil {
panic("artifact " + strconv.Quote(p.String()) + " not available")
panic("artifact " + strconv.Quote(handle.String()) + " not available")
}
return
}
// New returns a [Toolchain] for the specified [Stage].
func (s *S) New(stage Stage) Toolchain {
return Toolchain{S: s, stage: stage}
}
// Std is a convenience method that returns a [Toolchain] for the [Std] stage.
func (s *S) Std() Toolchain { return s.New(Std) }
// Load returns the resulting [pkg.Artifact] of [ArtifactH].
func (s *S) Load(t Toolchain, p ArtifactH) (pkg.Artifact, string) {
s.wantsArch()
e, ok := s.c[t].Load(p)
func (t Toolchain) Load(handle ArtifactH) (pkg.Artifact, string) {
t.wantsArch()
e, ok := t.c[t.stage].Load(handle)
if ok {
r := e.(cachedArtifact)
return r.a, r.v
}
meta := s.Get(p)
meta := t.Get(handle)
if meta == nil {
return nil, ""
}
var r cachedArtifact
r.a, r.v = meta.f(t, s)
s.c[t].Store(p, r)
r.a, r.v = meta.f(t)
t.c[t.stage].Store(handle, r)
return r.a, r.v
}
// MustLoad is like Load, but panics if the named [Artifact] is not registered.
func (s *S) MustLoad(t Toolchain, p ArtifactH) (pkg.Artifact, string) {
a, version := s.Load(t, p)
func (t Toolchain) MustLoad(handle ArtifactH) (pkg.Artifact, string) {
a, version := t.Load(handle)
if a == nil {
panic("artifact " + strconv.Quote(p.String()) + " not available")
panic("artifact " + strconv.Quote(handle.String()) + " not available")
}
return a, version
}