internal/rosa: represent runtime dependencies
All checks were successful
Test / Create distribution (push) Successful in 1m1s
Test / Sandbox (push) Successful in 2m38s
Test / Hakurei (push) Successful in 3m37s
Test / ShareFS (push) Successful in 3m41s
Test / Sandbox (race detector) (push) Successful in 4m57s
Test / Hakurei (race detector) (push) Successful in 6m10s
Test / Flake checks (push) Successful in 1m21s
All checks were successful
Test / Create distribution (push) Successful in 1m1s
Test / Sandbox (push) Successful in 2m38s
Test / Hakurei (push) Successful in 3m37s
Test / ShareFS (push) Successful in 3m41s
Test / Sandbox (race detector) (push) Successful in 4m57s
Test / Hakurei (race detector) (push) Successful in 6m10s
Test / Flake checks (push) Successful in 1m21s
This also resolves indirect dependencies, reducing noise. Signed-off-by: Ophestra <cat@gensokyo.uk>
This commit is contained in:
@@ -4,6 +4,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
"strconv"
|
||||||
"sync"
|
"sync"
|
||||||
@@ -167,6 +168,36 @@ const (
|
|||||||
PresetEnd
|
PresetEnd
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// P represents multiple [PArtifact] and is stable through JSON.
|
||||||
|
type P []PArtifact
|
||||||
|
|
||||||
|
// MarshalJSON represents [PArtifact] by their [Metadata.Name].
|
||||||
|
func (s P) MarshalJSON() ([]byte, error) {
|
||||||
|
names := make([]string, len(s))
|
||||||
|
for i, p := range s {
|
||||||
|
names[i] = GetMetadata(p).Name
|
||||||
|
}
|
||||||
|
return json.Marshal(names)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSON resolves the value created by MarshalJSON back to [P].
|
||||||
|
func (s *P) UnmarshalJSON(data []byte) error {
|
||||||
|
var names []string
|
||||||
|
if err := json.Unmarshal(data, &names); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
*s = make(P, len(names))
|
||||||
|
for i, name := range names {
|
||||||
|
if p, ok := ResolveName(name); !ok {
|
||||||
|
return fmt.Errorf("unknown artifact %q", name)
|
||||||
|
} else {
|
||||||
|
(*s)[i] = p
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// Metadata is stage-agnostic information of a [PArtifact] not directly
|
// Metadata is stage-agnostic information of a [PArtifact] not directly
|
||||||
// representable in the resulting [pkg.Artifact].
|
// representable in the resulting [pkg.Artifact].
|
||||||
type Metadata struct {
|
type Metadata struct {
|
||||||
@@ -179,6 +210,9 @@ type Metadata struct {
|
|||||||
// Project home page.
|
// Project home page.
|
||||||
Website string `json:"website,omitempty"`
|
Website string `json:"website,omitempty"`
|
||||||
|
|
||||||
|
// Runtime dependencies.
|
||||||
|
Dependencies P `json:"dependencies"`
|
||||||
|
|
||||||
// Project identifier on [Anitya].
|
// Project identifier on [Anitya].
|
||||||
//
|
//
|
||||||
// [Anitya]: https://release-monitoring.org/
|
// [Anitya]: https://release-monitoring.org/
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import (
|
|||||||
"slices"
|
"slices"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
"sync"
|
||||||
|
|
||||||
"hakurei.app/container/fhs"
|
"hakurei.app/container/fhs"
|
||||||
"hakurei.app/internal/pkg"
|
"hakurei.app/internal/pkg"
|
||||||
@@ -454,6 +455,48 @@ type PackageAttr struct {
|
|||||||
Flag int
|
Flag int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// pa holds whether a [PArtifact] is present.
|
||||||
|
type pa = [PresetEnd]bool
|
||||||
|
|
||||||
|
// paPool holds addresses of pa.
|
||||||
|
var paPool = sync.Pool{New: func() any { return new(pa) }}
|
||||||
|
|
||||||
|
// paGet returns the address of a new pa.
|
||||||
|
func paGet() *pa { return paPool.Get().(*pa) }
|
||||||
|
|
||||||
|
// paPut returns a pa to paPool.
|
||||||
|
func paPut(pv *pa) { *pv = pa{}; paPool.Put(pv) }
|
||||||
|
|
||||||
|
// appendPreset recursively appends a [PArtifact] and its runtime dependencies.
|
||||||
|
func (t Toolchain) appendPreset(
|
||||||
|
a []pkg.Artifact,
|
||||||
|
pv *pa, p PArtifact,
|
||||||
|
) []pkg.Artifact {
|
||||||
|
if pv[p] {
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
pv[p] = true
|
||||||
|
|
||||||
|
for _, d := range GetMetadata(p).Dependencies {
|
||||||
|
a = t.appendPreset(a, pv, d)
|
||||||
|
}
|
||||||
|
return append(a, t.Load(p))
|
||||||
|
}
|
||||||
|
|
||||||
|
// AppendPresets recursively appends multiple [PArtifact] and their runtime
|
||||||
|
// dependencies.
|
||||||
|
func (t Toolchain) AppendPresets(
|
||||||
|
a []pkg.Artifact,
|
||||||
|
presets ...PArtifact,
|
||||||
|
) []pkg.Artifact {
|
||||||
|
pv := paGet()
|
||||||
|
for _, p := range presets {
|
||||||
|
a = t.appendPreset(a, pv, p)
|
||||||
|
}
|
||||||
|
paPut(pv)
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
|
||||||
// NewPackage constructs a [pkg.Artifact] via a build system helper.
|
// NewPackage constructs a [pkg.Artifact] via a build system helper.
|
||||||
func (t Toolchain) NewPackage(
|
func (t Toolchain) NewPackage(
|
||||||
name, version string,
|
name, version string,
|
||||||
@@ -486,12 +529,14 @@ func (t Toolchain) NewPackage(
|
|||||||
extraRes := make([]pkg.Artifact, 0, dc)
|
extraRes := make([]pkg.Artifact, 0, dc)
|
||||||
extraRes = append(extraRes, attr.NonStage0...)
|
extraRes = append(extraRes, attr.NonStage0...)
|
||||||
if !t.isStage0() {
|
if !t.isStage0() {
|
||||||
|
pv := paGet()
|
||||||
for _, p := range helper.extra(attr.Flag) {
|
for _, p := range helper.extra(attr.Flag) {
|
||||||
extraRes = append(extraRes, t.Load(p))
|
extraRes = t.appendPreset(extraRes, pv, p)
|
||||||
}
|
}
|
||||||
for _, p := range extra {
|
for _, p := range extra {
|
||||||
extraRes = append(extraRes, t.Load(p))
|
extraRes = t.appendPreset(extraRes, pv, p)
|
||||||
}
|
}
|
||||||
|
paPut(pv)
|
||||||
}
|
}
|
||||||
|
|
||||||
var scriptEarly string
|
var scriptEarly string
|
||||||
|
|||||||
Reference in New Issue
Block a user