aboutsummaryrefslogtreecommitdiffhomepage
path: root/internal/rosa
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
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')
-rw-r--r--internal/rosa/gnu.go27
-rw-r--r--internal/rosa/package/gnu/package.az22
-rw-r--r--internal/rosa/rosa.go20
-rw-r--r--internal/rosa/state.go90
4 files changed, 131 insertions, 28 deletions
diff --git a/internal/rosa/gnu.go b/internal/rosa/gnu.go
index 54833db5..5e6bb358 100644
--- a/internal/rosa/gnu.go
+++ b/internal/rosa/gnu.go
@@ -109,33 +109,6 @@ func init() {
})
}
-func (t Toolchain) newSed() (pkg.Artifact, string) {
- const (
- version = "4.10"
- checksum = "TXTRFQJCyflb-bpBRI2S5Y1DpplwvT7-KfXtpqN4AdZgZ5OtI6yStn1-bkhDKx51"
- )
- return t.NewPackage("sed", version, newTar(
- "https://ftpmirror.gnu.org/gnu/sed/sed-"+version+".tar.gz",
- checksum,
- pkg.TarGzip,
- ), nil, (*MakeHelper)(nil),
- Diffutils,
-
- KernelHeaders,
- ), version
-}
-func init() {
- native.MustRegister(&Artifact{
- f: Toolchain.newSed,
-
- Name: "sed",
- Description: "a non-interactive command-line text editor",
- Website: "https://www.gnu.org/software/sed/",
-
- ID: 4789,
- })
-}
-
func (t Toolchain) newAutoconf() (pkg.Artifact, string) {
const (
version = "2.73"
diff --git a/internal/rosa/package/gnu/package.az b/internal/rosa/package/gnu/package.az
new file mode 100644
index 00000000..a50c1a90
--- /dev/null
+++ b/internal/rosa/package/gnu/package.az
@@ -0,0 +1,22 @@
+// GNU software with trivial packaging.
+
+package sed {
+ description = "a non-interactive command-line text editor";
+ website = "https://www.gnu.org/software/sed";
+ anitya = 4789;
+
+ version* = "4.10";
+ source = remoteTar {
+ url = "https://ftpmirror.gnu.org/gnu/sed/sed-"+version+".tar.gz";
+ checksum = "TXTRFQJCyflb-bpBRI2S5Y1DpplwvT7-KfXtpqN4AdZgZ5OtI6yStn1-bkhDKx51";
+ compress = gzip;
+ };
+
+ exec = make {};
+
+ inputs = [
+ diffutils,
+
+ kernel-headers,
+ ];
+}
diff --git a/internal/rosa/rosa.go b/internal/rosa/rosa.go
index 709b8420..d1a6c25e 100644
--- a/internal/rosa/rosa.go
+++ b/internal/rosa/rosa.go
@@ -2,6 +2,9 @@
package rosa
import (
+ "embed"
+ "io/fs"
+ "os"
"path"
"slices"
"strconv"
@@ -608,3 +611,20 @@ var native S
// Native returns the global [S].
func Native() *S { return &native }
+
+// nativeB is the backing directory of built-in azalea-based [Artifact]
+// implementations.
+//
+//go:embed package
+var nativeB embed.FS
+
+func init() {
+ sub, err := fs.Sub(nativeB, "package")
+ if err != nil {
+ panic(err)
+ }
+ if err = native.EvaluateFS(sub); err != nil {
+ println(err)
+ os.Exit(1)
+ }
+}
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) {