aboutsummaryrefslogtreecommitdiffhomepage
path: root/cmd
diff options
context:
space:
mode:
authorOphestra <cat@gensokyo.uk>2026-05-17 13:07:12 +0900
committerOphestra <cat@gensokyo.uk>2026-05-17 15:56:53 +0900
commit30eb0d6a613ad268f6805ccbcdcabf158e7f526f (patch)
tree07e55baa52748fd139e183017eeb43f5f64cee59 /cmd
parentc2ff9c9fa55ea569a5e70ee90d2eb0b2ee2a0540 (diff)
internal/rosa: key metadata by string
For upcoming azalea integration. The API is quite ugly right now to ease migration. Signed-off-by: Ophestra <cat@gensokyo.uk>
Diffstat (limited to 'cmd')
-rw-r--r--cmd/mbf/info.go19
-rw-r--r--cmd/mbf/info_test.go34
-rw-r--r--cmd/mbf/internal/pkgserver/api.go6
-rw-r--r--cmd/mbf/internal/pkgserver/api_test.go77
-rw-r--r--cmd/mbf/internal/pkgserver/index.go22
-rw-r--r--cmd/mbf/main.go70
-rw-r--r--cmd/mbf/main_test.go10
7 files changed, 88 insertions, 150 deletions
diff --git a/cmd/mbf/info.go b/cmd/mbf/info.go
index 15357301..4cdea31c 100644
--- a/cmd/mbf/info.go
+++ b/cmd/mbf/info.go
@@ -6,6 +6,7 @@ import (
"io"
"os"
"strings"
+ "unique"
"hakurei.app/internal/pkg"
"hakurei.app/internal/rosa"
@@ -36,16 +37,18 @@ func commandInfo(
}
for i, name := range args {
- if p, ok := rosa.ResolveName(name); !ok {
+ handle := rosa.ArtifactH(unique.Make(name))
+ if meta := rosa.Native().Get(handle); meta == nil {
return fmt.Errorf("unknown artifact %q", name)
} else {
var suffix string
- if version := rosa.Std.Version(p); version != rosa.Unversioned {
+
+ a, version := rosa.Native().MustLoad(rosa.Std, handle)
+ if version != rosa.Unversioned {
suffix += "-" + version
}
mustPrintln("name : " + name + suffix)
- meta := rosa.GetMetadata(p)
mustPrintln("description : " + meta.Description)
if meta.Website != "" {
mustPrintln("website : " +
@@ -54,9 +57,9 @@ func commandInfo(
if len(meta.Dependencies) > 0 {
mustPrint("depends on :")
for _, d := range meta.Dependencies {
- s := rosa.GetMetadata(d).Name
- if version := rosa.Std.Version(d); version != rosa.Unversioned {
- s += "-" + version
+ s := rosa.Native().MustGet(d).Name
+ if _, _version := rosa.Native().Load(rosa.Std, d); _version != rosa.Unversioned {
+ s += "-" + _version
}
mustPrint(" " + s)
}
@@ -68,7 +71,7 @@ func commandInfo(
if r == nil {
var f io.ReadSeekCloser
err = cm.Do(func(cache *pkg.Cache) (err error) {
- f, err = cache.OpenStatus(rosa.Std.Load(p))
+ f, err = cache.OpenStatus(a)
return
})
if err != nil {
@@ -87,7 +90,7 @@ func commandInfo(
}
}
} else if err = cm.Do(func(cache *pkg.Cache) (err error) {
- status, n := r.ArtifactOf(cache.Ident(rosa.Std.Load(p)))
+ status, n := r.ArtifactOf(cache.Ident(a))
if status == nil {
mustPrintln(
statusPrefix + "not in report",
diff --git a/cmd/mbf/info_test.go b/cmd/mbf/info_test.go
index a7219e9c..e3120157 100644
--- a/cmd/mbf/info_test.go
+++ b/cmd/mbf/info_test.go
@@ -10,6 +10,7 @@ import (
"strings"
"syscall"
"testing"
+ "unique"
"unsafe"
"hakurei.app/internal/pkg"
@@ -20,6 +21,13 @@ import (
func TestInfo(t *testing.T) {
t.Parallel()
+ _, qemuVersion := rosa.Native().Load(rosa.Std, rosa.QEMU)
+ _, glibVersion := rosa.Native().Load(rosa.Std, rosa.GLib)
+ zlib, zlibVersion := rosa.Native().Load(rosa.Std, rosa.Zlib)
+ _, zstdVersion := rosa.Native().Load(rosa.Std, rosa.Zstd)
+ _, hakureiVersion := rosa.Native().Load(rosa.Std, rosa.Hakurei)
+ _, hakureiDistVersion := rosa.Native().Load(rosa.Std, rosa.HakureiDist)
+
testCases := []struct {
name string
args []string
@@ -29,24 +37,24 @@ func TestInfo(t *testing.T) {
wantErr any
}{
{"qemu", []string{"qemu"}, nil, "", `
-name : qemu-` + rosa.Std.Version(rosa.QEMU) + `
+name : qemu-` + qemuVersion + `
description : a generic and open source machine emulator and virtualizer
website : https://www.qemu.org
-depends on : glib-` + rosa.Std.Version(rosa.GLib) + ` zstd-` + rosa.Std.Version(rosa.Zstd) + `
+depends on : glib-` + glibVersion + ` zstd-` + zstdVersion + `
`, nil},
{"multi", []string{"hakurei", "hakurei-dist"}, nil, "", `
-name : hakurei-` + rosa.Std.Version(rosa.Hakurei) + `
+name : hakurei-` + hakureiVersion + `
description : low-level userspace tooling for Rosa OS
website : https://hakurei.app
-name : hakurei-dist-` + rosa.Std.Version(rosa.HakureiDist) + `
+name : hakurei-dist-` + hakureiDistVersion + `
description : low-level userspace tooling for Rosa OS (distribution tarball)
website : https://hakurei.app
`, nil},
{"nonexistent", []string{"zlib", "\x00"}, nil, "", `
-name : zlib-` + rosa.Std.Version(rosa.Zlib) + `
+name : zlib-` + zlibVersion + `
description : lossless data-compression library
website : https://zlib.net
@@ -56,12 +64,12 @@ website : https://zlib.net
"zstd": "internal/pkg (amd64) on satori\n",
"hakurei": "internal/pkg (amd64) on satori\n\n",
}, "", `
-name : zlib-` + rosa.Std.Version(rosa.Zlib) + `
+name : zlib-` + zlibVersion + `
description : lossless data-compression library
website : https://zlib.net
status : not yet cured
-name : zstd-` + rosa.Std.Version(rosa.Zstd) + `
+name : zstd-` + zstdVersion + `
description : a fast compression algorithm
website : https://facebook.github.io/zstd
status : internal/pkg (amd64) on satori
@@ -70,19 +78,19 @@ status : internal/pkg (amd64) on satori
{"status cache perm", []string{"zlib"}, map[string]string{
"zlib": "\x00",
}, "", `
-name : zlib-` + rosa.Std.Version(rosa.Zlib) + `
+name : zlib-` + zlibVersion + `
description : lossless data-compression library
website : https://zlib.net
`, func(cm *cache) error {
return &os.PathError{
Op: "open",
- Path: filepath.Join(cm.base, "status", pkg.Encode(cm.c.Ident(rosa.Std.Load(rosa.Zlib)).Value())),
+ Path: filepath.Join(cm.base, "status", pkg.Encode(cm.c.Ident(zlib).Value())),
Err: syscall.EACCES,
}
}},
{"status report", []string{"zlib"}, nil, strings.Repeat("\x00", len(pkg.Checksum{})+8), `
-name : zlib-` + rosa.Std.Version(rosa.Zlib) + `
+name : zlib-` + zlibVersion + `
description : lossless data-compression library
website : https://zlib.net
status : not in report
@@ -131,8 +139,8 @@ status : not in report
if tc.status != nil {
for name, status := range tc.status {
- p, ok := rosa.ResolveName(name)
- if !ok {
+ a, _ := rosa.Native().Load(rosa.Std, rosa.ArtifactH(unique.Make(name)))
+ if a == nil {
t.Fatalf("invalid name %q", name)
}
perm := os.FileMode(0400)
@@ -143,7 +151,7 @@ status : not in report
return os.WriteFile(filepath.Join(
cm.base,
"status",
- pkg.Encode(cache.Ident(rosa.Std.Load(p)).Value()),
+ pkg.Encode(cache.Ident(a).Value()),
), unsafe.Slice(unsafe.StringData(status), len(status)), perm)
}); err != nil {
t.Fatalf("Do: error = %v", err)
diff --git a/cmd/mbf/internal/pkgserver/api.go b/cmd/mbf/internal/pkgserver/api.go
index 599ea522..e73b8bbe 100644
--- a/cmd/mbf/internal/pkgserver/api.go
+++ b/cmd/mbf/internal/pkgserver/api.go
@@ -30,7 +30,7 @@ var (
// handleInfo writes constant system information.
func handleInfo(w http.ResponseWriter, _ *http.Request) {
infoPayloadOnce.Do(func() {
- infoPayload.Count = int(rosa.PresetUnexportedStart)
+ infoPayload.Count = int(rosa.Native().Count())
infoPayload.HakureiVersion = info.Version()
})
// TODO(mae): cache entire response if no additional fields are planned
@@ -91,7 +91,7 @@ func (index *packageIndex) handleGet(w http.ResponseWriter, r *http.Request) {
if err != nil || i >= len(index.sorts[0]) || i < 0 {
http.Error(
w, "index must be an integer between 0 and "+
- strconv.Itoa(int(rosa.PresetUnexportedStart-1)),
+ strconv.Itoa(len(index.sorts[0])-1),
http.StatusBadRequest,
)
return
@@ -125,7 +125,7 @@ func (index *packageIndex) handleSearch(w http.ResponseWriter, r *http.Request)
if err != nil || i >= len(index.sorts[0]) || i < 0 {
http.Error(
w, "index must be an integer between 0 and "+
- strconv.Itoa(int(rosa.PresetUnexportedStart-1)),
+ strconv.Itoa(len(index.sorts[0])-1),
http.StatusBadRequest,
)
return
diff --git a/cmd/mbf/internal/pkgserver/api_test.go b/cmd/mbf/internal/pkgserver/api_test.go
index 8449c234..4c178fb9 100644
--- a/cmd/mbf/internal/pkgserver/api_test.go
+++ b/cmd/mbf/internal/pkgserver/api_test.go
@@ -3,7 +3,6 @@ package pkgserver
import (
"net/http"
"net/http/httptest"
- "slices"
"strconv"
"testing"
@@ -32,7 +31,7 @@ func TestAPIInfo(t *testing.T) {
checkPayload(t, resp, struct {
Count int `json:"count"`
HakureiVersion string `json:"hakurei_version"`
- }{int(rosa.PresetUnexportedStart), info.Version()})
+ }{rosa.Native().Count(), info.Version()})
}
func TestAPIGet(t *testing.T) {
@@ -96,8 +95,8 @@ func TestAPIGet(t *testing.T) {
t.Run("index", func(t *testing.T) {
t.Parallel()
checkValidate(
- t, "limit=1&sort=0&index", 0, int(rosa.PresetUnexportedStart-1),
- "index must be an integer between 0 and "+strconv.Itoa(int(rosa.PresetUnexportedStart-1)),
+ t, "limit=1&sort=0&index", 0, rosa.Native().Count()-1,
+ "index must be an integer between 0 and "+strconv.Itoa(rosa.Native().Count()-1),
)
})
@@ -108,74 +107,4 @@ func TestAPIGet(t *testing.T) {
"sort must be an integer between 0 and "+strconv.Itoa(int(sortOrderEnd)),
)
})
-
- checkWithSuffix := func(name, suffix string, want []*metadata) {
- t.Run(name, func(t *testing.T) {
- t.Parallel()
-
- w := newRequest(suffix)
- resp := w.Result()
- checkStatus(t, resp, http.StatusOK)
- checkAPIHeader(t, w.Header())
- checkPayloadFunc(t, resp, func(got *struct {
- Values []*metadata `json:"values"`
- }) bool {
- return slices.EqualFunc(got.Values, want, func(a, b *metadata) bool {
- return (a.Version == b.Version ||
- a.Version == rosa.Unversioned ||
- b.Version == rosa.Unversioned) &&
- a.HasReport == b.HasReport &&
- a.Name == b.Name &&
- a.Description == b.Description &&
- a.Website == b.Website
- })
- })
-
- })
- }
-
- checkWithSuffix("declarationAscending", "?limit=2&index=1&sort=0", []*metadata{
- {
- Metadata: rosa.GetMetadata(1),
- Version: rosa.Std.Version(1),
- },
- {
- Metadata: rosa.GetMetadata(2),
- Version: rosa.Std.Version(2),
- },
- })
- checkWithSuffix("declarationAscending offset", "?limit=3&index=5&sort=0", []*metadata{
- {
- Metadata: rosa.GetMetadata(5),
- Version: rosa.Std.Version(5),
- },
- {
- Metadata: rosa.GetMetadata(6),
- Version: rosa.Std.Version(6),
- },
- {
- Metadata: rosa.GetMetadata(7),
- Version: rosa.Std.Version(7),
- },
- })
- checkWithSuffix("declarationDescending", "?limit=3&index=0&sort=1", []*metadata{
- {
- Metadata: rosa.GetMetadata(rosa.PresetUnexportedStart - 1),
- Version: rosa.Std.Version(rosa.PresetUnexportedStart - 1),
- },
- {
- Metadata: rosa.GetMetadata(rosa.PresetUnexportedStart - 2),
- Version: rosa.Std.Version(rosa.PresetUnexportedStart - 2),
- },
- {
- Metadata: rosa.GetMetadata(rosa.PresetUnexportedStart - 3),
- Version: rosa.Std.Version(rosa.PresetUnexportedStart - 3),
- },
- })
- checkWithSuffix("declarationDescending offset", "?limit=1&index=37&sort=1", []*metadata{
- {
- Metadata: rosa.GetMetadata(rosa.PresetUnexportedStart - 38),
- Version: rosa.Std.Version(rosa.PresetUnexportedStart - 38),
- },
- })
}
diff --git a/cmd/mbf/internal/pkgserver/index.go b/cmd/mbf/internal/pkgserver/index.go
index 911183da..5711f810 100644
--- a/cmd/mbf/internal/pkgserver/index.go
+++ b/cmd/mbf/internal/pkgserver/index.go
@@ -23,7 +23,7 @@ const (
// packageIndex refers to metadata by name and various sort orders.
type packageIndex struct {
- sorts [sortOrderEnd + 1][rosa.PresetUnexportedStart]*metadata
+ sorts [sortOrderEnd + 1][]*metadata
names map[string]*metadata
search searchCache
// Taken from [rosa.Report] if available.
@@ -32,8 +32,8 @@ type packageIndex struct {
// metadata holds [rosa.Metadata] extended with additional information.
type metadata struct {
- p rosa.PArtifact
- *rosa.Metadata
+ handle rosa.ArtifactH
+ *rosa.Artifact
// Populated via [rosa.Toolchain.Version], [rosa.Unversioned] is equivalent
// to the zero value. Otherwise, the zero value is invalid.
@@ -56,15 +56,17 @@ func (index *packageIndex) populate(report *rosa.Report) (err error) {
index.handleAccess = report.HandleAccess
}
- var work [rosa.PresetUnexportedStart]*metadata
+ handles := rosa.Native().Collect()
+ work := make([]*metadata, len(handles))
index.names = make(map[string]*metadata)
ir := pkg.NewIR()
- for p := range rosa.PresetUnexportedStart {
+ for i, handle := range handles {
+ a, version := rosa.Native().Load(rosa.Std, handle)
m := metadata{
- p: p,
+ handle: handle,
- Metadata: rosa.GetMetadata(p),
- Version: rosa.Std.Version(p),
+ Artifact: rosa.Native().MustGet(handle),
+ Version: version,
}
if m.Version == "" {
return errors.New("invalid version from " + m.Name)
@@ -74,13 +76,13 @@ func (index *packageIndex) populate(report *rosa.Report) (err error) {
}
if report != nil {
- id := ir.Ident(rosa.Std.Load(p))
+ id := ir.Ident(a)
m.ids = pkg.Encode(id.Value())
m.status, m.Size = report.ArtifactOf(id)
m.HasReport = m.Size >= 0
}
- work[p] = &m
+ work[i] = &m
index.names[m.Name] = &m
}
diff --git a/cmd/mbf/main.go b/cmd/mbf/main.go
index ea10d3b7..25902fde 100644
--- a/cmd/mbf/main.go
+++ b/cmd/mbf/main.go
@@ -97,10 +97,10 @@ func main() {
if !flagLTO {
flags |= rosa.OptLLVMNoLTO
}
- rosa.DropCaches("", flags)
+ rosa.Native().DropCaches("", flags)
cross := flagArch != "" && flagArch != runtime.GOARCH
if flagQEMU || cross {
- cm.qemu = rosa.Std.Load(rosa.QEMU)
+ cm.qemu, _ = rosa.Native().Load(rosa.Std, rosa.QEMU)
}
if cross {
@@ -108,7 +108,7 @@ func main() {
flags = flagCrossOverride
}
- rosa.DropCaches(flagArch, flags)
+ rosa.Native().DropCaches(flagArch, flags)
if !rosa.HasStage0() {
return pkg.UnsupportedArchError(flagArch)
}
@@ -331,12 +331,12 @@ func main() {
n atomic.Uint64
)
- w := make(chan rosa.PArtifact)
+ w := make(chan rosa.ArtifactH)
var wg sync.WaitGroup
for range max(flagJobs, 1) {
wg.Go(func() {
for p := range w {
- meta := rosa.GetMetadata(p)
+ meta := rosa.Native().MustGet(p)
if meta.ID == 0 {
continue
}
@@ -349,8 +349,9 @@ func main() {
continue
}
+ _, version := rosa.Native().Load(rosa.Std, p)
if current, latest :=
- rosa.Std.Version(p),
+ version,
meta.GetLatest(v); current != latest {
n.Add(1)
@@ -364,9 +365,9 @@ func main() {
}
done:
- for i := range rosa.PresetEnd {
+ for _, p := range rosa.Native().Collect() {
select {
- case w <- rosa.PArtifact(i):
+ case w <- p:
break
case <-ctx.Done():
break done
@@ -421,7 +422,7 @@ func main() {
return
}
}
- rosa.SetGentooStage3(flagGentoo, checksum)
+ rosa.Native().SetGentooStage3(flagGentoo, checksum)
}
var (
@@ -430,9 +431,8 @@ func main() {
)
if err = cm.Do(func(cache *pkg.Cache) (err error) {
- pathname, _, err = cache.Cure(
- (t - 2).Load(rosa.LLVM),
- )
+ llvm, _ := rosa.Native().Load(t-2, rosa.LLVM)
+ pathname, _, err = cache.Cure(llvm)
return
}); err != nil {
return
@@ -440,18 +440,16 @@ func main() {
log.Println("stage1:", pathname)
if err = cm.Do(func(cache *pkg.Cache) (err error) {
- pathname, checksum[0], err = cache.Cure(
- (t - 1).Load(rosa.LLVM),
- )
+ llvm, _ := rosa.Native().Load(t-1, rosa.LLVM)
+ pathname, checksum[0], err = cache.Cure(llvm)
return
}); err != nil {
return
}
log.Println("stage2:", pathname)
if err = cm.Do(func(cache *pkg.Cache) (err error) {
- pathname, checksum[1], err = cache.Cure(
- t.Load(rosa.LLVM),
- )
+ llvm, _ := rosa.Native().Load(t, rosa.LLVM)
+ pathname, checksum[1], err = cache.Cure(llvm)
return
}); err != nil {
return
@@ -472,9 +470,8 @@ func main() {
if flagStage0 {
if err = cm.Do(func(cache *pkg.Cache) (err error) {
- pathname, _, err = cache.Cure(
- t.Load(rosa.Stage0),
- )
+ stage0, _ := rosa.Native().Load(t, rosa.Stage0)
+ pathname, _, err = cache.Cure(stage0)
return
}); err != nil {
return
@@ -519,10 +516,6 @@ func main() {
if len(args) != 1 {
return errors.New("cure requires 1 argument")
}
- p, ok := rosa.ResolveName(args[0])
- if !ok {
- return fmt.Errorf("unknown artifact %q", args[0])
- }
t := rosa.Std
if flagBoot {
@@ -531,11 +524,16 @@ func main() {
t -= 1
}
+ a, _ := rosa.Native().Load(t, rosa.ArtifactH(unique.Make(args[0])))
+ if a == nil {
+ return fmt.Errorf("unknown artifact %q", args[0])
+ }
+
switch {
default:
var pathname *check.Absolute
err := cm.Do(func(cache *pkg.Cache) (err error) {
- pathname, _, err = cache.Cure(t.Load(p))
+ pathname, _, err = cache.Cure(a)
return
})
if err != nil {
@@ -577,7 +575,7 @@ func main() {
return err
}
- if err = pkg.NewIR().EncodeAll(f, rosa.Std.Load(p)); err != nil {
+ if err = pkg.NewIR().EncodeAll(f, a); err != nil {
_ = f.Close()
return err
}
@@ -588,7 +586,7 @@ func main() {
return cm.Do(func(cache *pkg.Cache) error {
return cache.EnterExec(
ctx,
- t.Load(p),
+ a,
true, os.Stdin, os.Stdout, os.Stderr,
rosa.AbsSystem.Append("bin", "mksh"),
"sh",
@@ -600,7 +598,6 @@ func main() {
if flagNoReply {
flags |= remoteNoReply
}
- a := t.Load(p)
pathname, err := cureRemote(ctx, &addr, a, flags)
if !flagNoReply && err == nil {
log.Println(pathname)
@@ -620,7 +617,7 @@ func main() {
case flagFaults:
var faults []pkg.Fault
if err := cm.Do(func(cache *pkg.Cache) (err error) {
- faults, err = cache.ReadFaults(t.Load(p))
+ faults, err = cache.ReadFaults(a)
return
}); err != nil {
return err
@@ -634,7 +631,7 @@ func main() {
case flagPop:
var faults []pkg.Fault
if err := cm.Do(func(cache *pkg.Cache) (err error) {
- faults, err = cache.ReadFaults(t.Load(p))
+ faults, err = cache.ReadFaults(a)
return
}); err != nil {
return err
@@ -740,27 +737,26 @@ func main() {
"shell",
"Interactive shell in the specified Rosa OS environment",
func(args []string) error {
- presets := make([]rosa.PArtifact, len(args)+3)
+ handles := make([]rosa.ArtifactH, len(args)+3)
for i, arg := range args {
- p, ok := rosa.ResolveName(arg)
- if !ok {
+ handles[i] = rosa.ArtifactH(unique.Make(arg))
+ if rosa.Native().Get(handles[i]) == nil {
return fmt.Errorf("unknown artifact %q", arg)
}
- presets[i] = p
}
base := rosa.LLVM
if !flagWithToolchain {
base = rosa.Musl
}
- presets = append(presets,
+ handles = append(handles,
base,
rosa.Mksh,
rosa.Toybox,
)
root := make(pkg.Collect, 0, 6+len(args))
- root = rosa.Std.AppendPresets(root, presets...)
+ root = rosa.Native().AppendPresets(rosa.Std, root, handles...)
if err := cm.Do(func(cache *pkg.Cache) error {
_, _, err := cache.Cure(&root)
diff --git a/cmd/mbf/main_test.go b/cmd/mbf/main_test.go
index a5b33e90..4554b250 100644
--- a/cmd/mbf/main_test.go
+++ b/cmd/mbf/main_test.go
@@ -9,7 +9,7 @@ import (
)
func TestMain(m *testing.M) {
- rosa.DropCaches("", rosa.OptLLVMNoLTO)
+ rosa.Native().DropCaches("", rosa.OptLLVMNoLTO)
os.Exit(m.Run())
}
@@ -35,10 +35,10 @@ func TestCureAll(t *testing.T) {
}
})
- for i := range rosa.PresetEnd {
- p := rosa.PArtifact(i)
- t.Run(rosa.GetMetadata(p).Name, func(t *testing.T) {
- _, err := cureRemote(t.Context(), &addr, rosa.Std.Load(p), 0)
+ for _, handle := range rosa.Native().Collect() {
+ a, _ := rosa.Native().MustLoad(rosa.Std, handle)
+ t.Run(rosa.Native().MustGet(handle).Name, func(t *testing.T) {
+ _, err := cureRemote(t.Context(), &addr, a, 0)
if err != nil {
t.Error(err)
}