109 lines
3.9 KiB
Go
109 lines
3.9 KiB
Go
package cmd
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"os"
|
|
"time"
|
|
|
|
"github.com/spf13/cobra"
|
|
|
|
core "git.dev.alexdunmow.com/block/core/plugin"
|
|
|
|
"git.dev.alexdunmow.com/block/core/cmd/ninja/internal/shot"
|
|
)
|
|
|
|
func newThemeCmd() *cobra.Command {
|
|
c := &cobra.Command{Use: "theme", Short: "Theme authoring helpers (preview screenshots)"}
|
|
c.AddCommand(newThemeScreenshotCmd())
|
|
return c
|
|
}
|
|
|
|
func newThemeScreenshotCmd() *cobra.Command {
|
|
var gallery, slug, out, mobileOut, themeName, waitSelector string
|
|
var mobile bool
|
|
var width, height int
|
|
cmd := &cobra.Command{
|
|
Use: "screenshot",
|
|
Short: "Render this theme's showcase page and write preview.png into the repo",
|
|
Long: `screenshot builds the gallery URL for this theme's showcase page
|
|
(rendered via the CMS render-only ?preview_template override), drives a headless
|
|
Chromium against it, and writes the captured PNG into the theme repo (preview.png,
|
|
git-tracked — the source of truth a human may later replace).
|
|
|
|
The theme name defaults to plugin.mod's name in the current directory. Point
|
|
--gallery at the gallery CMS site that has this theme's .so loaded and the
|
|
showcase content seeded. --host selects the orchestrator (defaults to PROD); the
|
|
gallery URL is independent of --host but the flag is accepted for parity with
|
|
the rest of the CLI.`,
|
|
RunE: func(c *cobra.Command, _ []string) error {
|
|
if themeName == "" {
|
|
modBytes, err := os.ReadFile("plugin.mod")
|
|
if err != nil {
|
|
return fmt.Errorf("read plugin.mod (run from the theme repo, or pass --theme): %w", err)
|
|
}
|
|
mod, err := core.ParseModFull(modBytes)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if mod.Plugin.Kind != "theme" {
|
|
return fmt.Errorf("plugin.mod kind = %q, want theme", mod.Plugin.Kind)
|
|
}
|
|
themeName = mod.Plugin.Name
|
|
}
|
|
if gallery == "" {
|
|
return fmt.Errorf("--gallery is required (the gallery CMS site base, e.g. https://showcase.localdev.blockninjacms.com)")
|
|
}
|
|
|
|
ctx := context.Background()
|
|
|
|
desktopURL := shot.PreviewURL(gallery, slug, themeName)
|
|
fmt.Fprintf(os.Stderr, "capturing desktop: %s\n", desktopURL)
|
|
png, err := shot.Capture(ctx, shot.Options{
|
|
URL: desktopURL,
|
|
Width: width,
|
|
Height: height,
|
|
WaitSelector: waitSelector,
|
|
Timeout: 45 * time.Second,
|
|
})
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if err := os.WriteFile(out, png, 0o644); err != nil {
|
|
return fmt.Errorf("write %s: %w", out, err)
|
|
}
|
|
fmt.Printf("wrote %s (%d bytes)\n", out, len(png))
|
|
|
|
if mobile {
|
|
mURL := shot.PreviewURL(gallery, slug, themeName)
|
|
fmt.Fprintf(os.Stderr, "capturing mobile: %s\n", mURL)
|
|
mpng, err := shot.Capture(ctx, shot.Options{
|
|
URL: mURL,
|
|
Width: 390,
|
|
Height: 844,
|
|
WaitSelector: waitSelector,
|
|
Timeout: 45 * time.Second,
|
|
})
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if err := os.WriteFile(mobileOut, mpng, 0o644); err != nil {
|
|
return fmt.Errorf("write %s: %w", mobileOut, err)
|
|
}
|
|
fmt.Printf("wrote %s (%d bytes)\n", mobileOut, len(mpng))
|
|
}
|
|
return nil
|
|
},
|
|
}
|
|
cmd.Flags().StringVar(&gallery, "gallery", "", "Gallery CMS site base URL (has this theme loaded + showcase seeded)")
|
|
cmd.Flags().StringVar(&slug, "slug", "/", "Showcase page slug to capture")
|
|
cmd.Flags().StringVar(&out, "out", "preview.png", "Output path for the desktop screenshot (git-tracked in the theme repo)")
|
|
cmd.Flags().StringVar(&mobileOut, "mobile-out", "preview-mobile.png", "Output path for the mobile screenshot")
|
|
cmd.Flags().StringVar(&themeName, "theme", "", "Theme key to preview (default: plugin.mod name)")
|
|
cmd.Flags().StringVar(&waitSelector, "wait", "section", "CSS selector to wait for before capturing")
|
|
cmd.Flags().BoolVar(&mobile, "mobile", false, "Also capture preview-mobile.png at a phone viewport")
|
|
cmd.Flags().IntVar(&width, "width", 1440, "Desktop viewport width")
|
|
cmd.Flags().IntVar(&height, "height", 900, "Desktop viewport height")
|
|
return cmd
|
|
}
|