internal/rosa: evaluate packages from fs

This migrates GNU sed to azalea, and resulting IR matches.

Signed-off-by: Ophestra <cat@gensokyo.uk>
This commit is contained in:
2026-05-18 17:53:48 +09:00
parent 0360e779f3
commit 37df040d85
5 changed files with 133 additions and 30 deletions

View File

@@ -52,7 +52,7 @@ func (handle *ArtifactH) UnmarshalJSON(data []byte) error {
type HandleError ArtifactH
func (e HandleError) Error() string {
return "artifact " + strconv.Quote(ArtifactH(e).String()) + " not available"
return "package " + strconv.Quote(ArtifactH(e).String()) + " not available"
}
type (
@@ -268,8 +268,38 @@ func (s *S) New(stage Stage) Toolchain {
// Std is a convenience method that returns a [Toolchain] for the [Std] stage.
func (s *S) Std() Toolchain { return s.New(Std) }
// LoadError wraps panicked errors reaching [Toolchain.Load].
type LoadError struct {
// Offending artifact handle.
Handle ArtifactH
// Recovered error.
Err error
}
func (e LoadError) Unwrap() error { return e.Err }
func (e LoadError) Error() string {
return "cannot load " + strconv.Quote(e.Handle.String()) + ": " + e.Err.Error()
}
// Load returns the resulting [pkg.Artifact] of [ArtifactH].
func (t Toolchain) Load(handle ArtifactH) (pkg.Artifact, string) {
defer func() {
r := recover()
if r == nil {
return
}
err, ok := r.(error)
if !ok {
panic(r)
}
if _, ok = err.(LoadError); ok {
panic(err)
}
panic(LoadError{handle, err})
}()
t.wantsArch()
e, ok := t.c[t.stage].Load(handle)
if ok {
@@ -552,6 +582,64 @@ func (s *S) Evaluate(r io.Reader, b fs.FS) error {
return nil
}
// EvaluateFS evaluates azalea files discovered in fsys. A file is evaluated if
// it is at the top level and its name has the suffix ".az", or it is in a
// top-level directory with the exact file name "package.az". The backing
// filesystem is directly exposed to azalea pathnames.
func (s *S) EvaluateFS(fsys fs.FS) error {
dents, err := fs.ReadDir(fsys, ".")
if err != nil {
return err
}
var r fs.File
for _, dent := range dents {
if dent.IsDir() {
var sub fs.FS
sub, err = fs.Sub(fsys, dent.Name())
if err != nil {
return err
}
r, err = sub.Open("package.az")
if errors.Is(err, fs.ErrNotExist) {
continue
}
if err != nil {
return err
}
err = s.Evaluate(r, sub)
if _err := r.Close(); err == nil {
err = _err
}
if err != nil {
return err
}
continue
}
if !dent.Type().IsRegular() ||
!strings.HasSuffix(dent.Name(), ".az") {
continue
}
r, err = fsys.Open(dent.Name())
if err != nil {
return err
}
err = s.Evaluate(r, fsys)
if _err := r.Close(); err == nil {
err = _err
}
if err != nil {
return err
}
}
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) {