aboutsummaryrefslogtreecommitdiffhomepage
path: root/internal/rosa/state.go
diff options
context:
space:
mode:
authorOphestra <cat@gensokyo.uk>2026-05-18 17:53:48 +0900
committerOphestra <cat@gensokyo.uk>2026-05-18 17:54:01 +0900
commit37df040d85e06100c69c6aa3560b2e4ebf977255 (patch)
treec82f47e38a8e53e4b285e4c6c5611dba578d834b /internal/rosa/state.go
parent0360e779f3fb9dc770e1f33420ca5b8f8f638666 (diff)
internal/rosa: evaluate packages from fs
This migrates GNU sed to azalea, and resulting IR matches. Signed-off-by: Ophestra <cat@gensokyo.uk>
Diffstat (limited to 'internal/rosa/state.go')
-rw-r--r--internal/rosa/state.go90
1 files changed, 89 insertions, 1 deletions
diff --git a/internal/rosa/state.go b/internal/rosa/state.go
index 71f25520..b01c4c38 100644
--- a/internal/rosa/state.go
+++ b/internal/rosa/state.go
@@ -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) {