forked from rosa/hakurei
internal/rosa: read-only access to built-ins
This removes potential footguns caused by mutable builtins without requiring unnecessary clones. Signed-off-by: Ophestra <cat@gensokyo.uk>
This commit is contained in:
+3
-4
@@ -21,7 +21,7 @@ func commandInfo(
|
|||||||
r *rosa.Report,
|
r *rosa.Report,
|
||||||
) (err error) {
|
) (err error) {
|
||||||
if len(args) == 0 {
|
if len(args) == 0 {
|
||||||
for _, h := range rosa.Native().CollectAll() {
|
for _, h := range rosa.CollectAll() {
|
||||||
fmt.Println(h)
|
fmt.Println(h)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@@ -39,10 +39,9 @@ func commandInfo(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
t := rosa.Native().Std()
|
|
||||||
for i, name := range args {
|
for i, name := range args {
|
||||||
handle := rosa.ArtifactH(unique.Make(name))
|
handle := rosa.ArtifactH(unique.Make(name))
|
||||||
if meta, a := t.Load(handle); meta == nil {
|
if meta, a := rosa.Load(handle); meta == nil {
|
||||||
return fmt.Errorf("unknown artifact %q", name)
|
return fmt.Errorf("unknown artifact %q", name)
|
||||||
} else {
|
} else {
|
||||||
var suffix string
|
var suffix string
|
||||||
@@ -60,7 +59,7 @@ func commandInfo(
|
|||||||
if len(meta.Dependencies) > 0 {
|
if len(meta.Dependencies) > 0 {
|
||||||
mustPrint("depends on :")
|
mustPrint("depends on :")
|
||||||
for _, d := range meta.Dependencies {
|
for _, d := range meta.Dependencies {
|
||||||
_meta, _ := rosa.Native().Std().MustLoad(d)
|
_meta, _ := rosa.MustLoad(d)
|
||||||
s := _meta.Name
|
s := _meta.Name
|
||||||
if _meta.Version != rosa.Unversioned {
|
if _meta.Version != rosa.Unversioned {
|
||||||
s += "-" + _meta.Version
|
s += "-" + _meta.Version
|
||||||
|
|||||||
@@ -21,13 +21,12 @@ import (
|
|||||||
func TestInfo(t *testing.T) {
|
func TestInfo(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
_t := rosa.Native().Std()
|
qemuMeta, _ := rosa.MustLoad(rosa.H("qemu"))
|
||||||
qemuMeta, _ := _t.Load(rosa.H("qemu"))
|
glibMeta, _ := rosa.MustLoad(rosa.H("glib"))
|
||||||
glibMeta, _ := _t.Load(rosa.H("glib"))
|
zlibMeta, zlib := rosa.MustLoad(rosa.H("zlib"))
|
||||||
zlibMeta, zlib := _t.Load(rosa.H("zlib"))
|
zstdMeta, _ := rosa.MustLoad(rosa.H("zstd"))
|
||||||
zstdMeta, _ := _t.Load(rosa.H("zstd"))
|
hakureiMeta, _ := rosa.MustLoad(rosa.H("hakurei"))
|
||||||
hakureiMeta, _ := _t.Load(rosa.H("hakurei"))
|
hakureiDistMeta, _ := rosa.MustLoad(rosa.H("hakurei-dist"))
|
||||||
hakureiDistMeta, _ := _t.Load(rosa.H("hakurei-dist"))
|
|
||||||
|
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
name string
|
name string
|
||||||
@@ -140,7 +139,7 @@ status : not in report
|
|||||||
|
|
||||||
if tc.status != nil {
|
if tc.status != nil {
|
||||||
for name, status := range tc.status {
|
for name, status := range tc.status {
|
||||||
_, a := _t.Load(rosa.ArtifactH(unique.Make(name)))
|
_, a := rosa.Load(rosa.ArtifactH(unique.Make(name)))
|
||||||
if a == nil {
|
if a == nil {
|
||||||
t.Fatalf("invalid name %q", name)
|
t.Fatalf("invalid name %q", name)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ var (
|
|||||||
// handleInfo writes constant system information.
|
// handleInfo writes constant system information.
|
||||||
func handleInfo(w http.ResponseWriter, _ *http.Request) {
|
func handleInfo(w http.ResponseWriter, _ *http.Request) {
|
||||||
infoPayloadOnce.Do(func() {
|
infoPayloadOnce.Do(func() {
|
||||||
infoPayload.Count = len(rosa.Native().Collect())
|
infoPayload.Count = len(rosa.Collect())
|
||||||
infoPayload.HakureiVersion = info.Version()
|
infoPayload.HakureiVersion = info.Version()
|
||||||
})
|
})
|
||||||
// TODO(mae): cache entire response if no additional fields are planned
|
// TODO(mae): cache entire response if no additional fields are planned
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ func TestAPIInfo(t *testing.T) {
|
|||||||
checkPayload(t, resp, struct {
|
checkPayload(t, resp, struct {
|
||||||
Count int `json:"count"`
|
Count int `json:"count"`
|
||||||
HakureiVersion string `json:"hakurei_version"`
|
HakureiVersion string `json:"hakurei_version"`
|
||||||
}{len(rosa.Native().Collect()), info.Version()})
|
}{len(rosa.Collect()), info.Version()})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestAPIGet(t *testing.T) {
|
func TestAPIGet(t *testing.T) {
|
||||||
@@ -92,7 +92,7 @@ func TestAPIGet(t *testing.T) {
|
|||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
count := len(rosa.Native().Collect())
|
count := len(rosa.Collect())
|
||||||
t.Run("index", func(t *testing.T) {
|
t.Run("index", func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
checkValidate(
|
checkValidate(
|
||||||
|
|||||||
@@ -56,12 +56,12 @@ func (index *packageIndex) populate(report *rosa.Report) (err error) {
|
|||||||
index.handleAccess = report.HandleAccess
|
index.handleAccess = report.HandleAccess
|
||||||
}
|
}
|
||||||
|
|
||||||
handles := rosa.Native().Collect()
|
handles := rosa.Collect()
|
||||||
work := make([]*metadata, len(handles))
|
work := make([]*metadata, len(handles))
|
||||||
index.names = make(map[string]*metadata)
|
index.names = make(map[string]*metadata)
|
||||||
ir := pkg.NewIR()
|
ir := pkg.NewIR()
|
||||||
for i, handle := range handles {
|
for i, handle := range handles {
|
||||||
meta, a := rosa.Native().Std().MustLoad(handle)
|
meta, a := rosa.MustLoad(handle)
|
||||||
m := metadata{
|
m := metadata{
|
||||||
handle: handle,
|
handle: handle,
|
||||||
|
|
||||||
|
|||||||
+32
-27
@@ -48,6 +48,11 @@ import (
|
|||||||
"hakurei.app/cmd/mbf/internal/pkgserver/ui"
|
"hakurei.app/cmd/mbf/internal/pkgserver/ui"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// builtin contains native and embedded [rosa.Artifact] registrations.
|
||||||
|
//
|
||||||
|
//go:linkname builtin hakurei.app/internal/rosa.builtin
|
||||||
|
var builtin rosa.S
|
||||||
|
|
||||||
// writeFileExcl is like [os.WriteFile], but sets [os.O_EXCL] instead.
|
// writeFileExcl is like [os.WriteFile], but sets [os.O_EXCL] instead.
|
||||||
func writeFileExcl(name string, data []byte, perm os.FileMode) error {
|
func writeFileExcl(name string, data []byte, perm os.FileMode) error {
|
||||||
f, err := os.OpenFile(name, os.O_WRONLY|os.O_CREATE|os.O_EXCL, perm)
|
f, err := os.OpenFile(name, os.O_WRONLY|os.O_CREATE|os.O_EXCL, perm)
|
||||||
@@ -114,7 +119,7 @@ func main() {
|
|||||||
addr net.UnixAddr
|
addr net.UnixAddr
|
||||||
)
|
)
|
||||||
c := command.New(os.Stderr, log.Printf, "mbf", func([]string) error {
|
c := command.New(os.Stderr, log.Printf, "mbf", func([]string) error {
|
||||||
if !rosa.Native().HasStageEarly() {
|
if !rosa.HasStageEarly() {
|
||||||
return pkg.UnsupportedArchError(runtime.GOARCH)
|
return pkg.UnsupportedArchError(runtime.GOARCH)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -141,13 +146,13 @@ func main() {
|
|||||||
if !flagCheck {
|
if !flagCheck {
|
||||||
flags |= rosa.OptSkipCheck
|
flags |= rosa.OptSkipCheck
|
||||||
}
|
}
|
||||||
if !flagLTO {
|
if flagLTO {
|
||||||
flags |= rosa.OptLLVMNoLTO
|
flags |= rosa.OptToolchainLTO
|
||||||
}
|
}
|
||||||
rosa.Native().DropCaches("", flags)
|
builtin.DropCaches("", flags)
|
||||||
cross := flagArch != "" && flagArch != runtime.GOARCH
|
cross := flagArch != "" && flagArch != runtime.GOARCH
|
||||||
if flagQEMU || cross {
|
if flagQEMU || cross {
|
||||||
_, cm.qemu = rosa.Native().Std().MustLoad(rosa.H("qemu"))
|
_, cm.qemu = rosa.MustLoad(rosa.H("qemu"))
|
||||||
}
|
}
|
||||||
|
|
||||||
if cross {
|
if cross {
|
||||||
@@ -155,14 +160,14 @@ func main() {
|
|||||||
flags = flagCrossOverride
|
flags = flagCrossOverride
|
||||||
}
|
}
|
||||||
|
|
||||||
rosa.Native().DropCaches(flagArch, flags)
|
builtin.DropCaches(flagArch, flags)
|
||||||
if !rosa.Native().HasStageEarly() {
|
if !rosa.HasStageEarly() {
|
||||||
return pkg.UnsupportedArchError(flagArch)
|
return pkg.UnsupportedArchError(flagArch)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if flagSourcePath != "" {
|
if flagSourcePath != "" {
|
||||||
if err := rosa.Native().SetSource(os.DirFS(flagSourcePath)); err != nil {
|
if err := builtin.SetSource(os.DirFS(flagSourcePath)); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -173,7 +178,7 @@ func main() {
|
|||||||
return err
|
return err
|
||||||
} else if root, err = os.OpenRoot(a.String()); err != nil {
|
} else if root, err = os.OpenRoot(a.String()); err != nil {
|
||||||
return err
|
return err
|
||||||
} else if err = rosa.Native().RegisterFS(root.FS()); err != nil {
|
} else if err = builtin.RegisterFS(root.FS()); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -432,7 +437,7 @@ func main() {
|
|||||||
for range max(flagJobs, 1) {
|
for range max(flagJobs, 1) {
|
||||||
wg.Go(func() {
|
wg.Go(func() {
|
||||||
for p := range w {
|
for p := range w {
|
||||||
meta, _ := rosa.Native().Std().MustLoad(p)
|
meta, _ := rosa.MustLoad(p)
|
||||||
if meta.ID == 0 {
|
if meta.ID == 0 {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@@ -462,7 +467,7 @@ func main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
done:
|
done:
|
||||||
for _, p := range rosa.Native().CollectAll() {
|
for _, p := range rosa.CollectAll() {
|
||||||
select {
|
select {
|
||||||
case w <- p:
|
case w <- p:
|
||||||
break
|
break
|
||||||
@@ -490,8 +495,8 @@ func main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
c.NewCommand("blocked", command.UsageInternal, func([]string) error {
|
c.NewCommand("blocked", command.UsageInternal, func([]string) error {
|
||||||
for _, p := range rosa.Native().CollectAll() {
|
for _, p := range rosa.CollectAll() {
|
||||||
meta, _ := rosa.Native().Std().Load(p)
|
meta, _ := rosa.Load(p)
|
||||||
if meta.Blocked != "" {
|
if meta.Blocked != "" {
|
||||||
fmt.Printf("%s: %s\n", meta.Name, meta.Blocked)
|
fmt.Printf("%s: %s\n", meta.Name, meta.Blocked)
|
||||||
}
|
}
|
||||||
@@ -631,7 +636,7 @@ func main() {
|
|||||||
|
|
||||||
_llvm := rosa.H("llvm")
|
_llvm := rosa.H("llvm")
|
||||||
if err = cm.Do(func(cache *pkg.Cache) (err error) {
|
if err = cm.Do(func(cache *pkg.Cache) (err error) {
|
||||||
_, llvm := rosa.Native().New(rosa.Std - 2).Load(_llvm)
|
_, llvm := rosa.MustLoadAt(rosa.Std-2, _llvm)
|
||||||
pathname, _, err = cache.Cure(llvm)
|
pathname, _, err = cache.Cure(llvm)
|
||||||
return
|
return
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
@@ -640,7 +645,7 @@ func main() {
|
|||||||
log.Println("stage1:", pathname)
|
log.Println("stage1:", pathname)
|
||||||
|
|
||||||
if err = cm.Do(func(cache *pkg.Cache) (err error) {
|
if err = cm.Do(func(cache *pkg.Cache) (err error) {
|
||||||
_, llvm := rosa.Native().New(rosa.Std - 1).Load(_llvm)
|
_, llvm := rosa.MustLoadAt(rosa.Std-1, _llvm)
|
||||||
pathname, _, err = cache.Cure(llvm)
|
pathname, _, err = cache.Cure(llvm)
|
||||||
return
|
return
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
@@ -649,7 +654,7 @@ func main() {
|
|||||||
log.Println("stage2:", pathname)
|
log.Println("stage2:", pathname)
|
||||||
|
|
||||||
if err = cm.Do(func(cache *pkg.Cache) (err error) {
|
if err = cm.Do(func(cache *pkg.Cache) (err error) {
|
||||||
_, llvm := rosa.Native().New(rosa.Std).Load(_llvm)
|
_, llvm := rosa.MustLoadAt(rosa.Std, _llvm)
|
||||||
pathname, checksum[0], err = cache.Cure(llvm)
|
pathname, checksum[0], err = cache.Cure(llvm)
|
||||||
return
|
return
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
@@ -658,7 +663,7 @@ func main() {
|
|||||||
log.Println("stage3:", pathname)
|
log.Println("stage3:", pathname)
|
||||||
|
|
||||||
if err = cm.Do(func(cache *pkg.Cache) (err error) {
|
if err = cm.Do(func(cache *pkg.Cache) (err error) {
|
||||||
_, llvm := rosa.Native().New(rosa.Stage3).Load(_llvm)
|
_, llvm := rosa.MustLoadAt(rosa.Stage3, _llvm)
|
||||||
pathname, checksum[1], err = cache.Cure(llvm)
|
pathname, checksum[1], err = cache.Cure(llvm)
|
||||||
return
|
return
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
@@ -686,10 +691,10 @@ func main() {
|
|||||||
"all",
|
"all",
|
||||||
command.UsageInternal,
|
command.UsageInternal,
|
||||||
func([]string) error {
|
func([]string) error {
|
||||||
all := rosa.Native().CollectAll()
|
all := rosa.CollectAll()
|
||||||
a := make(pkg.Collect, len(all))
|
a := make(pkg.Collect, len(all))
|
||||||
for i, h := range all {
|
for i, h := range all {
|
||||||
_, a[i] = rosa.Native().Std().Load(h)
|
_, a[i] = rosa.Load(h)
|
||||||
}
|
}
|
||||||
return cm.Do(func(cache *pkg.Cache) (err error) {
|
return cm.Do(func(cache *pkg.Cache) (err error) {
|
||||||
_, _, err = cache.Cure(&a)
|
_, _, err = cache.Cure(&a)
|
||||||
@@ -740,12 +745,12 @@ func main() {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
rosa.Native().SetGentooStage3(flagGentoo, checksum)
|
builtin.SetGentooStage3(flagGentoo, checksum)
|
||||||
|
|
||||||
t -= 3 // magic number to discourage misuse
|
t -= 3 // magic number to discourage misuse
|
||||||
}
|
}
|
||||||
|
|
||||||
_, a := rosa.Native().New(t).Load(rosa.ArtifactH(unique.Make(args[0])))
|
_, a := rosa.LoadAt(t, rosa.ArtifactH(unique.Make(args[0])))
|
||||||
if a == nil {
|
if a == nil {
|
||||||
return fmt.Errorf("unknown artifact %q", args[0])
|
return fmt.Errorf("unknown artifact %q", args[0])
|
||||||
}
|
}
|
||||||
@@ -965,7 +970,7 @@ func main() {
|
|||||||
return errors.New("validate must rebuild at least twice")
|
return errors.New("validate must rebuild at least twice")
|
||||||
}
|
}
|
||||||
|
|
||||||
_, a := rosa.Native().New(stage).Load(rosa.ArtifactH(unique.Make(args[1])))
|
_, a := rosa.LoadAt(stage, rosa.ArtifactH(unique.Make(args[1])))
|
||||||
if a == nil {
|
if a == nil {
|
||||||
return fmt.Errorf("unknown artifact %q", args[1])
|
return fmt.Errorf("unknown artifact %q", args[1])
|
||||||
}
|
}
|
||||||
@@ -1051,7 +1056,7 @@ func main() {
|
|||||||
"Remove identifiers not reachable by loaded packages",
|
"Remove identifiers not reachable by loaded packages",
|
||||||
func([]string) error {
|
func([]string) error {
|
||||||
return cm.Do(func(cache *pkg.Cache) error {
|
return cm.Do(func(cache *pkg.Cache) error {
|
||||||
t := rosa.Native().Clone().Std()
|
t := rosa.New().Std()
|
||||||
handles := t.CollectAll()
|
handles := t.CollectAll()
|
||||||
|
|
||||||
flags := t.Flags()
|
flags := t.Flags()
|
||||||
@@ -1061,7 +1066,7 @@ func main() {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
t.DropCaches(arch, rosa.OptLLVMNoLTO|rosa.OptSkipCheck)
|
t.DropCaches(arch, rosa.OptSkipCheck)
|
||||||
a = t.Append(a, handles...)
|
a = t.Append(a, handles...)
|
||||||
t.DropCaches(arch, flags)
|
t.DropCaches(arch, flags)
|
||||||
a = t.Append(a, handles...)
|
a = t.Append(a, handles...)
|
||||||
@@ -1117,7 +1122,7 @@ func main() {
|
|||||||
handles := make([]rosa.ArtifactH, len(args), len(args)+3)
|
handles := make([]rosa.ArtifactH, len(args), len(args)+3)
|
||||||
for i, arg := range args {
|
for i, arg := range args {
|
||||||
handles[i] = rosa.ArtifactH(unique.Make(arg))
|
handles[i] = rosa.ArtifactH(unique.Make(arg))
|
||||||
if meta, _ := rosa.Native().Std().Load(handles[i]); meta == nil {
|
if meta, _ := rosa.Load(handles[i]); meta == nil {
|
||||||
return fmt.Errorf("unknown artifact %q", arg)
|
return fmt.Errorf("unknown artifact %q", arg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1134,14 +1139,14 @@ func main() {
|
|||||||
|
|
||||||
root := make(pkg.Collect, 0, 6+len(args))
|
root := make(pkg.Collect, 0, 6+len(args))
|
||||||
root = append(root, rosa.NewEtc(false))
|
root = append(root, rosa.NewEtc(false))
|
||||||
root = rosa.Native().Std().Append(root, handles...)
|
root = builtin.Std().Append(root, handles...)
|
||||||
|
|
||||||
return cm.Do(func(cache *pkg.Cache) error {
|
return cm.Do(func(cache *pkg.Cache) error {
|
||||||
return cache.EnterExec(
|
return cache.EnterExec(
|
||||||
ctx,
|
ctx,
|
||||||
pkg.NewExec(
|
pkg.NewExec(
|
||||||
"",
|
"",
|
||||||
rosa.Native().Arch(),
|
builtin.Arch(),
|
||||||
new(pkg.Checksum),
|
new(pkg.Checksum),
|
||||||
1,
|
1,
|
||||||
flagNet,
|
flagNet,
|
||||||
|
|||||||
@@ -8,11 +8,6 @@ import (
|
|||||||
"hakurei.app/internal/rosa"
|
"hakurei.app/internal/rosa"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestMain(m *testing.M) {
|
|
||||||
rosa.Native().DropCaches("", rosa.OptLLVMNoLTO)
|
|
||||||
os.Exit(m.Run())
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestCureAll(t *testing.T) {
|
func TestCureAll(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
const env = "ROSA_TEST_DAEMON"
|
const env = "ROSA_TEST_DAEMON"
|
||||||
@@ -35,8 +30,8 @@ func TestCureAll(t *testing.T) {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
for _, handle := range rosa.Native().Collect() {
|
for _, handle := range rosa.Collect() {
|
||||||
_, a := rosa.Native().Std().MustLoad(handle)
|
_, a := rosa.MustLoad(handle)
|
||||||
t.Run(handle.String(), func(t *testing.T) {
|
t.Run(handle.String(), func(t *testing.T) {
|
||||||
_, err := cureRemote(t.Context(), &addr, a, 0)
|
_, err := cureRemote(t.Context(), &addr, a, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ const (
|
|||||||
loadFlagE = `"-l$` + pkg.EnvLoad + `"`
|
loadFlagE = `"-l$` + pkg.EnvLoad + `"`
|
||||||
)
|
)
|
||||||
|
|
||||||
// newTar wraps [pkg.NewHTTPGetTar] with a simpler function signature.
|
// newTar is a helper for downloading compressed tarballs.
|
||||||
func newTar(url, checksum string, compress uint32) pkg.Artifact {
|
func newTar(url, checksum string, compress uint32) pkg.Artifact {
|
||||||
return pkg.NewTar(
|
return pkg.NewTar(
|
||||||
pkg.NewDecompress(
|
pkg.NewDecompress(
|
||||||
@@ -114,3 +114,43 @@ func skipGNUTests(tests ...int64) string {
|
|||||||
}
|
}
|
||||||
return buf.String()
|
return buf.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// builtin contains native and embedded [Artifact] registrations.
|
||||||
|
var builtin S
|
||||||
|
|
||||||
|
// New returns the address of a newly populated [S] derived from built-ins.
|
||||||
|
func New() *S { return builtin.Clone() }
|
||||||
|
|
||||||
|
// Collect returns all built-in non-excluded [ArtifactH].
|
||||||
|
func Collect() (handles P) { return builtin.Collect() }
|
||||||
|
|
||||||
|
// CollectAll returns all built-in [ArtifactH].
|
||||||
|
func CollectAll() (handles P) { return builtin.CollectAll() }
|
||||||
|
|
||||||
|
// builtinStd is the [Std] toolchain stage on builtin.
|
||||||
|
var builtinStd = builtin.Std()
|
||||||
|
|
||||||
|
// Load satisfies an [Artifact] referred to by an [ArtifactH].
|
||||||
|
func Load(handle ArtifactH) (*Metadata, pkg.Artifact) {
|
||||||
|
return builtinStd.Load(handle)
|
||||||
|
}
|
||||||
|
|
||||||
|
// LoadAt satisfies an [Artifact] referred to by an [ArtifactH] at the
|
||||||
|
// specified stage.
|
||||||
|
func LoadAt(stage Stage, handle ArtifactH) (*Metadata, pkg.Artifact) {
|
||||||
|
return builtin.New(stage).Load(handle)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MustLoad is like Load, but panics if the named [Artifact] is not registered.
|
||||||
|
func MustLoad(handle ArtifactH) (*Metadata, pkg.Artifact) {
|
||||||
|
return builtinStd.MustLoad(handle)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MustLoadAt is like LoadAt, but panics if the named [Artifact] is not
|
||||||
|
// registered.
|
||||||
|
func MustLoadAt(stage Stage, handle ArtifactH) (*Metadata, pkg.Artifact) {
|
||||||
|
return builtin.New(stage).MustLoad(handle)
|
||||||
|
}
|
||||||
|
|
||||||
|
// HasStageEarly returns whether a stage0 distribution is available.
|
||||||
|
func HasStageEarly() (ok bool) { return builtin.HasStageEarly() }
|
||||||
|
|||||||
+1
-1
@@ -66,7 +66,7 @@ func init() {
|
|||||||
Version: version,
|
Version: version,
|
||||||
Exclude: true,
|
Exclude: true,
|
||||||
}
|
}
|
||||||
native.MustRegister(meta.Name, func(t Toolchain) (*Metadata, pkg.Artifact) {
|
builtin.MustRegister(meta.Name, func(t Toolchain) (*Metadata, pkg.Artifact) {
|
||||||
var (
|
var (
|
||||||
bootstrapEnv []string
|
bootstrapEnv []string
|
||||||
bootstrapEarly []pkg.Artifact
|
bootstrapEarly []pkg.Artifact
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ func litArgs(verbose bool, skipChecks ...string) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
native.MustRegister("llvm", func(t Toolchain) (*Metadata, pkg.Artifact) {
|
builtin.MustRegister("llvm", func(t Toolchain) (*Metadata, pkg.Artifact) {
|
||||||
meta := Metadata{
|
meta := Metadata{
|
||||||
Name: "llvm",
|
Name: "llvm",
|
||||||
Description: "a collection of modular and reusable compiler and toolchain technologies",
|
Description: "a collection of modular and reusable compiler and toolchain technologies",
|
||||||
@@ -168,7 +168,7 @@ func init() {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
if t.opts&OptLLVMNoLTO == 0 {
|
if t.opts&OptToolchainLTO != 0 {
|
||||||
cache = append(cache, []KV{
|
cache = append(cache, []KV{
|
||||||
// very expensive
|
// very expensive
|
||||||
{"LLVM_ENABLE_LTO", "Thin"},
|
{"LLVM_ENABLE_LTO", "Thin"},
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import (
|
|||||||
func TestLLVMInputs(t *testing.T) {
|
func TestLLVMInputs(t *testing.T) {
|
||||||
const wantInputCount = 470
|
const wantInputCount = 470
|
||||||
|
|
||||||
_, llvm := rosa.Native().Std().MustLoad(rosa.H("llvm"))
|
_, llvm := rosa.MustLoad(rosa.H("llvm"))
|
||||||
var n int
|
var n int
|
||||||
for range pkg.Inputs(llvm) {
|
for range pkg.Inputs(llvm) {
|
||||||
n++
|
n++
|
||||||
|
|||||||
@@ -42,8 +42,8 @@ func WriteReport(msg message.Msg, w io.Writer, c *pkg.Cache) error {
|
|||||||
zero [wordSize]byte
|
zero [wordSize]byte
|
||||||
buf [len(pkg.ID{}) + wordSize]byte
|
buf [len(pkg.ID{}) + wordSize]byte
|
||||||
)
|
)
|
||||||
t := native.Std()
|
t := builtin.Std()
|
||||||
for _, p := range native.Collect() {
|
for _, p := range builtin.Collect() {
|
||||||
meta, a := t.MustLoad(p)
|
meta, a := t.MustLoad(p)
|
||||||
if meta == nil {
|
if meta == nil {
|
||||||
return errors.New("artifact " + p.String() + " in inconsistent state")
|
return errors.New("artifact " + p.String() + " in inconsistent state")
|
||||||
|
|||||||
+4
-12
@@ -624,33 +624,25 @@ func (attr *GenericHelper) script(t Toolchain, _ string) string {
|
|||||||
return script
|
return script
|
||||||
}
|
}
|
||||||
|
|
||||||
// native contains natively-implemented and built-in azalea-based [Artifact].
|
|
||||||
// It is generally recommended to clone this instance for custom [Artifact]
|
|
||||||
// registrations.
|
|
||||||
var native S
|
|
||||||
|
|
||||||
// Native returns the global [S].
|
|
||||||
func Native() *S { return &native }
|
|
||||||
|
|
||||||
// parseTime is the duration of early parsing of built-in azalea expressions.
|
// parseTime is the duration of early parsing of built-in azalea expressions.
|
||||||
var parseTime time.Duration
|
var parseTime time.Duration
|
||||||
|
|
||||||
// ParseTime returns the time taken by early parsing of built-in azalea expressions.
|
// ParseTime returns the time taken by early parsing of built-in azalea expressions.
|
||||||
func ParseTime() time.Duration { return parseTime }
|
func ParseTime() time.Duration { return parseTime }
|
||||||
|
|
||||||
// nativeB is the backing directory of built-in azalea-based [Artifact]
|
// builtinAzalea is the backing directory of built-in azalea-based [Artifact]
|
||||||
// implementations.
|
// implementations.
|
||||||
//
|
//
|
||||||
//go:embed package
|
//go:embed package
|
||||||
var nativeB embed.FS
|
var builtinAzalea embed.FS
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
sub, err := fs.Sub(nativeB, "package")
|
sub, err := fs.Sub(builtinAzalea, "package")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
t := time.Now()
|
t := time.Now()
|
||||||
if err = native.RegisterFS(sub); err != nil {
|
if err = builtin.RegisterFS(sub); err != nil {
|
||||||
println(err.Error())
|
println(err.Error())
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,7 +28,6 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestMain(m *testing.M) {
|
func TestMain(m *testing.M) {
|
||||||
rosa.Native().DropCaches("", rosa.OptLLVMNoLTO)
|
|
||||||
container.TryArgv0(nil)
|
container.TryArgv0(nil)
|
||||||
|
|
||||||
code := m.Run()
|
code := m.Run()
|
||||||
@@ -79,8 +78,8 @@ func TestCureAll(t *testing.T) {
|
|||||||
cache := getCache(t)
|
cache := getCache(t)
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
for _, p := range rosa.Native().CollectAll() {
|
for _, p := range rosa.CollectAll() {
|
||||||
_, a := rosa.Native().Std().MustLoad(p)
|
_, a := rosa.MustLoad(p)
|
||||||
t.Run(p.String(), func(t *testing.T) {
|
t.Run(p.String(), func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
@@ -94,7 +93,7 @@ func TestCureAll(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func BenchmarkStage3(b *testing.B) {
|
func BenchmarkStage3(b *testing.B) {
|
||||||
t := rosa.Native().Clone().Std()
|
t := rosa.New().Std()
|
||||||
|
|
||||||
llvm := rosa.H("llvm")
|
llvm := rosa.H("llvm")
|
||||||
for b.Loop() {
|
for b.Loop() {
|
||||||
|
|||||||
+17
-17
@@ -184,16 +184,16 @@ type cachedArtifact struct {
|
|||||||
const (
|
const (
|
||||||
// OptSkipCheck skips running all test suites.
|
// OptSkipCheck skips running all test suites.
|
||||||
OptSkipCheck = 1 << iota
|
OptSkipCheck = 1 << iota
|
||||||
// OptLLVMNoLTO disables LTO in all [LLVM] stages.
|
// OptToolchainLTO enables LTO in all LLVM stages.
|
||||||
OptLLVMNoLTO
|
OptToolchainLTO
|
||||||
)
|
)
|
||||||
|
|
||||||
// S holds a set of [Artifact].
|
// S holds a set of [Artifact].
|
||||||
type S struct {
|
type S struct {
|
||||||
// [ArtifactH] to [Artifact].
|
// [ArtifactH] to [Artifact].
|
||||||
artifacts sync.Map
|
p sync.Map
|
||||||
// Size of artifacts.
|
// Size of p.
|
||||||
artifactCount atomic.Uint64
|
len atomic.Uint64
|
||||||
|
|
||||||
// Target architecture.
|
// Target architecture.
|
||||||
arch string
|
arch string
|
||||||
@@ -220,9 +220,9 @@ type S struct {
|
|||||||
// Clone returns a copy of s.
|
// Clone returns a copy of s.
|
||||||
func (s *S) Clone() *S {
|
func (s *S) Clone() *S {
|
||||||
v := S{arch: s.arch, opts: s.opts}
|
v := S{arch: s.arch, opts: s.opts}
|
||||||
s.artifacts.Range(func(key, value any) bool {
|
s.p.Range(func(key, value any) bool {
|
||||||
v.artifacts.Store(key, value)
|
v.p.Store(key, value)
|
||||||
v.artifactCount.Add(1)
|
v.len.Add(1)
|
||||||
return true
|
return true
|
||||||
})
|
})
|
||||||
return &v
|
return &v
|
||||||
@@ -304,7 +304,7 @@ func (s *S) DropCaches(targetArch string, flags int) {
|
|||||||
// get returns the named [Artifact].
|
// get returns the named [Artifact].
|
||||||
func (s *S) get(handle ArtifactH) (f Artifact) {
|
func (s *S) get(handle ArtifactH) (f Artifact) {
|
||||||
s.wantsArch()
|
s.wantsArch()
|
||||||
v, ok := s.artifacts.Load(handle)
|
v, ok := s.p.Load(handle)
|
||||||
if ok {
|
if ok {
|
||||||
f = v.(Artifact)
|
f = v.(Artifact)
|
||||||
}
|
}
|
||||||
@@ -393,9 +393,9 @@ func (s *S) Register(name string, f Artifact) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
p := ArtifactH(unique.Make(name))
|
p := ArtifactH(unique.Make(name))
|
||||||
_, ok := s.artifacts.LoadOrStore(p, f)
|
_, ok := s.p.LoadOrStore(p, f)
|
||||||
if !ok {
|
if !ok {
|
||||||
s.artifactCount.Add(1)
|
s.len.Add(1)
|
||||||
}
|
}
|
||||||
return !ok
|
return !ok
|
||||||
}
|
}
|
||||||
@@ -418,15 +418,15 @@ func (s *S) MustRegister(name string, f Artifact) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// count returns the number of [Artifact] registered to s.
|
// count returns the number of [Artifact] registered to r.
|
||||||
func (s *S) count() int {
|
func (s *S) count() int {
|
||||||
return int(s.artifactCount.Load())
|
return int(s.len.Load())
|
||||||
}
|
}
|
||||||
|
|
||||||
// CollectAll returns all [ArtifactH] registered to s.
|
// CollectAll returns all [ArtifactH] registered to s.
|
||||||
func (s *S) CollectAll() (handles P) {
|
func (s *S) CollectAll() (handles P) {
|
||||||
handles = make(P, 0, s.count())
|
handles = make(P, 0, s.count())
|
||||||
s.artifacts.Range(func(key, _ any) bool {
|
s.p.Range(func(key, _ any) bool {
|
||||||
handles = append(handles, key.(ArtifactH))
|
handles = append(handles, key.(ArtifactH))
|
||||||
return true
|
return true
|
||||||
})
|
})
|
||||||
@@ -439,7 +439,7 @@ func (s *S) CollectAll() (handles P) {
|
|||||||
// Collect returns all non-excluded [ArtifactH] registered to s.
|
// Collect returns all non-excluded [ArtifactH] registered to s.
|
||||||
func (s *S) Collect() (handles P) {
|
func (s *S) Collect() (handles P) {
|
||||||
handles = make(P, 0, s.count())
|
handles = make(P, 0, s.count())
|
||||||
s.artifacts.Range(func(key, _ any) bool {
|
s.p.Range(func(key, _ any) bool {
|
||||||
h := key.(ArtifactH)
|
h := key.(ArtifactH)
|
||||||
meta, _ := s.Std().MustLoad(h)
|
meta, _ := s.Std().MustLoad(h)
|
||||||
if !meta.Exclude {
|
if !meta.Exclude {
|
||||||
@@ -453,7 +453,7 @@ func (s *S) Collect() (handles P) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// deferredGit is a call to Toolchain.newTagRemote from azalea.
|
// deferredGit is a call to [Toolchain.NewViaGit] from azalea.
|
||||||
type deferredGit struct {
|
type deferredGit struct {
|
||||||
url string
|
url string
|
||||||
tag string
|
tag string
|
||||||
@@ -1375,7 +1375,7 @@ func (s *S) SetSource(fsys fs.FS) error {
|
|||||||
|
|
||||||
const name = "hakurei-source"
|
const name = "hakurei-source"
|
||||||
a := pkg.NewFile("hakurei-src-current.tar.gz", buf.Bytes())
|
a := pkg.NewFile("hakurei-src-current.tar.gz", buf.Bytes())
|
||||||
s.artifacts.Store(
|
s.p.Store(
|
||||||
H(name),
|
H(name),
|
||||||
Artifact(func(t Toolchain) (*Metadata, pkg.Artifact) {
|
Artifact(func(t Toolchain) (*Metadata, pkg.Artifact) {
|
||||||
return &Metadata{
|
return &Metadata{
|
||||||
|
|||||||
@@ -9,17 +9,17 @@ import (
|
|||||||
func TestLoad(t *testing.T) {
|
func TestLoad(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
for _, p := range rosa.Native().Collect() {
|
for _, p := range rosa.Collect() {
|
||||||
t.Run(p.String(), func(t *testing.T) {
|
t.Run(p.String(), func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
rosa.Native().Std().MustLoad(p)
|
rosa.MustLoad(p)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func BenchmarkAll(b *testing.B) {
|
func BenchmarkAll(b *testing.B) {
|
||||||
t := rosa.Native().Clone().Std()
|
t := rosa.New().Std()
|
||||||
|
|
||||||
for b.Loop() {
|
for b.Loop() {
|
||||||
for _, p := range t.Collect() {
|
for _, p := range t.Collect() {
|
||||||
|
|||||||
Reference in New Issue
Block a user