diff options
Diffstat (limited to 'cmd/mbf/info.go')
| -rw-r--r-- | cmd/mbf/info.go | 127 |
1 files changed, 127 insertions, 0 deletions
diff --git a/cmd/mbf/info.go b/cmd/mbf/info.go new file mode 100644 index 00000000..f421ce66 --- /dev/null +++ b/cmd/mbf/info.go @@ -0,0 +1,127 @@ +package main + +import ( + "errors" + "fmt" + "io" + "os" + "strings" + + "hakurei.app/internal/pkg" + "hakurei.app/internal/rosa" +) + +// commandInfo implements the info subcommand. +func commandInfo( + cm *cache, + args []string, + w io.Writer, + writeStatus bool, + reportPath string, +) (err error) { + if len(args) == 0 { + return errors.New("info requires at least 1 argument") + } + + var r *rosa.Report + if reportPath != "" { + if r, err = rosa.OpenReport(reportPath); err != nil { + return err + } + defer func() { + if closeErr := r.Close(); err == nil { + err = closeErr + } + }() + defer r.HandleAccess(&err)() + } + + // recovered by HandleAccess + mustPrintln := func(a ...any) { + if _, _err := fmt.Fprintln(w, a...); _err != nil { + panic(_err) + } + } + mustPrint := func(a ...any) { + if _, _err := fmt.Fprint(w, a...); _err != nil { + panic(_err) + } + } + + for i, name := range args { + if p, ok := rosa.ResolveName(name); !ok { + return fmt.Errorf("unknown artifact %q", name) + } else { + var suffix string + if version := rosa.Std.Version(p); version != rosa.Unversioned { + suffix += "-" + version + } + mustPrintln("name : " + name + suffix) + + meta := rosa.GetMetadata(p) + mustPrintln("description : " + meta.Description) + if meta.Website != "" { + mustPrintln("website : " + + strings.TrimSuffix(meta.Website, "/")) + } + if len(meta.Dependencies) > 0 { + mustPrint("depends on :") + for _, d := range meta.Dependencies { + s := rosa.GetMetadata(d).Name + if version := rosa.Std.Version(d); version != rosa.Unversioned { + s += "-" + version + } + mustPrint(" " + s) + } + mustPrintln() + } + + const statusPrefix = "status : " + if writeStatus { + if r == nil { + var f io.ReadSeekCloser + err = cm.Do(func(cache *pkg.Cache) (err error) { + f, err = cache.OpenStatus(rosa.Std.Load(p)) + return + }) + if err != nil { + if errors.Is(err, os.ErrNotExist) { + mustPrintln( + statusPrefix + "not yet cured", + ) + } else { + return + } + } else { + mustPrint(statusPrefix) + _, err = io.Copy(w, f) + if err = errors.Join(err, f.Close()); err != nil { + return + } + } + } else if err = cm.Do(func(cache *pkg.Cache) (err error) { + status, n := r.ArtifactOf(cache.Ident(rosa.Std.Load(p))) + if status == nil { + mustPrintln( + statusPrefix + "not in report", + ) + } else { + mustPrintln("size :", n) + mustPrint(statusPrefix) + if _, err = w.Write(status); err != nil { + return + } + } + return + }); err != nil { + return + } + } + + if i != len(args)-1 { + mustPrintln() + } + } + } + return nil +} |
