From b47fa1a214eb5a081c4ceb39cf30ac708e19b8ed Mon Sep 17 00:00:00 2001 From: Ophestra Date: Fri, 22 May 2026 22:24:16 +0900 Subject: [PATCH] internal/rosa: IR-curable source override This creates a tarball in-memory for overriding hakurei-source. Signed-off-by: Ophestra --- cmd/mbf/main.go | 18 +++++++-- internal/rosa/state.go | 87 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 102 insertions(+), 3 deletions(-) diff --git a/cmd/mbf/main.go b/cmd/mbf/main.go index cc8a40b2..8e2c4bda 100644 --- a/cmd/mbf/main.go +++ b/cmd/mbf/main.go @@ -64,11 +64,12 @@ func main() { return } - e, ok := r.(rosa.LoadError) - if !ok { + switch r.(type) { + case rosa.LoadError, pkg.IRStringError: + log.Fatal(r) + default: panic(r) } - log.Fatal(e) }() ctx, stop := signal.NotifyContext(context.Background(), @@ -86,6 +87,7 @@ func main() { flagLTO bool flagPT bool + flagSourcePath string flagCrossOverride int addr net.UnixAddr @@ -136,6 +138,12 @@ func main() { } } + if flagSourcePath != "" { + if err := rosa.Native().SetSource(os.DirFS(flagSourcePath)); err != nil { + return err + } + } + return nil }).Flag( &flagQuiet, @@ -196,6 +204,10 @@ func main() { &flagPT, "parse-time", command.BoolFlag(false), "Print duration of the initial azalea parse", + ).Flag( + &flagSourcePath, + "source", command.StringFlag(""), + "Override hakurei source tree", ) c.NewCommand( diff --git a/internal/rosa/state.go b/internal/rosa/state.go index 4a324094..399e6dc9 100644 --- a/internal/rosa/state.go +++ b/internal/rosa/state.go @@ -1,6 +1,9 @@ package rosa import ( + "archive/tar" + "bytes" + "compress/gzip" "context" "encoding/json" "errors" @@ -1173,6 +1176,90 @@ func (s *S) RegisterFS(fsys fs.FS) error { return nil } +// SetSource overrides the hakurei-source package with a cached tarball of fsys. +// The resulting IR is curable on the daemon. Must not be used concurrently with +// any other method. +func (s *S) SetSource(fsys fs.FS) error { + var buf bytes.Buffer + w, err := gzip.NewWriterLevel(&buf, gzip.BestSpeed) + if err != nil { + return err + } + tw := tar.NewWriter(w) + + if err = fs.WalkDir(fsys, ".", func(path string, d fs.DirEntry, err error) error { + if err != nil { + return err + } + + if d.IsDir() && d.Name() == ".git" { + return fs.SkipDir + } + + var fi fs.FileInfo + if fi, err = d.Info(); err != nil { + return err + } + + var linkname string + if fi.Mode()&fs.ModeSymlink != 0 { + if linkname, err = fs.ReadLink(fsys, path); err != nil { + return err + } + } + + var h *tar.Header + if h, err = tar.FileInfoHeader(fi, linkname); err != nil { + return err + } + h.Name = path + + if err = tw.WriteHeader(h); err != nil { + return err + } + + if fi.Mode().IsRegular() { + var f io.ReadCloser + if f, err = fsys.Open(path); err != nil { + return err + } + + _, err = io.Copy(tw, f) + if _err := f.Close(); err == nil { + err = _err + } + if err != nil { + return err + } + } + return nil + }); err != nil { + return err + } + + if err = tw.Close(); err != nil { + return err + } else if err = w.Close(); err != nil { + return err + } + + const name = "hakurei-source" + a := pkg.NewFile("hakurei-src-current.tar.gz", buf.Bytes()) + s.artifacts.Store( + H(name), + Artifact(func(t Toolchain) (*Metadata, pkg.Artifact) { + return &Metadata{ + Name: name, + Description: "hakurei source tree (current)", + Version: "1.0.0-CURRENT", + Exclude: true, + }, pkg.NewTar(a, pkg.TarGzip) + }), + ) + s.DropCaches(s.Arch(), s.Flags()) + return nil +} + // SetGentooStage3 sets the Gentoo stage3 tarball url and checksum. It panics // if given zero values or if these values have already been set. func (s *S) SetGentooStage3(url string, checksum pkg.Checksum) {