fix: make generate-error-page command output assets BREAKING CHANGE: requires `--outdir` instead of writing to stdout
2 files changed, 77 insertions(+), 8 deletions(-)
M cmd/searchix-web/generate-error-page.go → cmd/searchix-web/generate-error-page.go
@@ -1,7 +1,9 @@ package main import ( + "io" "os" + "strings" "github.com/Southclaws/fault" "github.com/Southclaws/fault/fmsg"@@ -9,16 +11,53 @@ "alin.ovh/searchix/frontend" "alin.ovh/searchix/internal/components" "alin.ovh/searchix/internal/config" + "alin.ovh/searchix/internal/file" ) -type GenerateErrorPageOptions struct{} +const perm = 0o644 -func (*GenerateErrorPageOptions) Execute(_ []string) error { +type GenerateErrorPageOptions struct { + Outdir string `long:"outdir" description:"output directory"` +} + +func (opts *GenerateErrorPageOptions) Execute(_ []string) error { assets, err := frontend.New() if err != nil { return fault.Wrap(err, fmsg.With("could not create frontend")) } + root, err := file.CreateAndOpenRoot(opts.Outdir) + if err != nil { + return fault.Wrap(err, fmsg.With("could not open root directory")) + } + defer root.Close() + + err = writeErrorPageTemplate(root, assets) + if err != nil { + return err + } + + err = root.Mkdir("assets", 0o755) + if err != nil { + return fault.Wrap(err, fmsg.With("could not create assets directory")) + } + + for _, asset := range assets.ByPath { + if err := writeFile(root, asset); err != nil { + return err + } + } + + return nil +} + +func writeErrorPageTemplate(root *file.Root, assets *frontend.AssetCollection) error { + out, err := root.OpenFile("error.html", os.O_CREATE|os.O_WRONLY, perm) + if err != nil { + return fault.Wrap(err, fmsg.With("could not open error.html")) + } + defer out.Close() + err = components.ErrorTemplate(components.TemplateData{ Source: config.Source{ Importer: config.All,@@ -29,9 +68,42 @@ ExtraHeadHTML: "", Code: 0, Message: `{{placeholder "http.error.status_code"}} {{placeholder "http.error.status_text"}}`, Assets: assets, - }).Render(os.Stdout) + }).Render(out) if err != nil { - panic("failed to render error template: " + err.Error()) + return fault.Wrap(err, fmsg.With("could not render error template")) + } + + err = out.Sync() + if err != nil { + return fault.Wrap(err, fmsg.With("could not sync error.html")) + } + + return nil +} + +func writeFile(root *file.Root, asset *frontend.Asset) error { + outname := strings.TrimPrefix(asset.ImmutablePath, "/") + + in, err := frontend.Files.Open(asset.Filename) + if err != nil { + return fault.Wrap(err, fmsg.With("could not open asset file")) + } + defer in.Close() + + out, err := root.OpenFile(outname, os.O_CREATE|os.O_WRONLY, perm) + if err != nil { + return fault.Wrap(err, fmsg.With("could not open output file")) + } + defer out.Close() + + _, err = io.Copy(out, in) + if err != nil { + return fault.Wrap(err, fmsg.With("could not write asset file")) + } + + err = out.Sync() + if err != nil { + return fault.Wrap(err, fmsg.With("could not sync asset file")) } return nil
M nix/package.nix → nix/package.nix
@@ -46,10 +46,7 @@ "alin.ovh/searchix/internal/config.Version=${version}" ]; postInstall = '' - install -d -m755 $out/lib/searchix/static - cp -r $src/frontend/static $out/lib/searchix - cp ${css} $out/lib/searchix/static/base.css - $out/bin/searchix-web generate-error-page > $out/lib/searchix/error.html + $out/bin/searchix-web generate-error-page --outdir $out/lib/searchix/ ''; modules = ../gomod2nix.toml;