diff options
Diffstat (limited to 'internal/rosa/state.go')
| -rw-r--r-- | internal/rosa/state.go | 90 |
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) { |
