diff options
| author | Ophestra <cat@gensokyo.uk> | 2026-05-17 13:07:12 +0900 |
|---|---|---|
| committer | Ophestra <cat@gensokyo.uk> | 2026-05-17 15:56:53 +0900 |
| commit | 30eb0d6a613ad268f6805ccbcdcabf158e7f526f (patch) | |
| tree | 07e55baa52748fd139e183017eeb43f5f64cee59 /cmd | |
| parent | c2ff9c9fa55ea569a5e70ee90d2eb0b2ee2a0540 (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.go | 19 | ||||
| -rw-r--r-- | cmd/mbf/info_test.go | 34 | ||||
| -rw-r--r-- | cmd/mbf/internal/pkgserver/api.go | 6 | ||||
| -rw-r--r-- | cmd/mbf/internal/pkgserver/api_test.go | 77 | ||||
| -rw-r--r-- | cmd/mbf/internal/pkgserver/index.go | 22 | ||||
| -rw-r--r-- | cmd/mbf/main.go | 70 | ||||
| -rw-r--r-- | cmd/mbf/main_test.go | 10 |
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) } |
