package hugo import ( "context" "gopkg.in/yaml.v3" "lmika.dev/lmika/hugo-cms/models" "log" "os" "os/exec" "path/filepath" ) type Provider struct { stagingDir string scratchDir string } func New(stagingDir, scratchDir string) (*Provider, error) { return &Provider{ stagingDir: stagingDir, scratchDir: scratchDir, }, nil } func (p *Provider) SiteStagingDir(site models.Site, what SiteDir) string { switch what { case BaseSiteDir: return filepath.Join(p.stagingDir, site.Name) case ThemeSiteDir: return filepath.Join(p.stagingDir, site.Name, "themes", site.Theme) } return filepath.Join(p.stagingDir, site.Name, string(what)) } func (p *Provider) NewSite(ctx context.Context, site models.Site) error { log.Printf(" .. %v", p.SiteStagingDir(site, BaseSiteDir)) if err := os.MkdirAll(p.SiteStagingDir(site, BaseSiteDir), 0755); err != nil { return err } // Create the new site if err := exec.CommandContext(ctx, "hugo", "new", "site", "--config=hugo.yaml", p.SiteStagingDir(site, BaseSiteDir)).Run(); err != nil { return err } return nil } func (p *Provider) PublishSite(ctx context.Context, site models.Site, target models.PublishTarget) (outDir string, clean func(), err error) { if err := os.MkdirAll(p.scratchDir, 0755); err != nil { return "", nil, err } outDir, err = os.MkdirTemp(p.scratchDir, site.Name+"-*") if err != nil { return "", nil, err } clean = func() { os.RemoveAll(outDir) } outDir, err = filepath.Abs(outDir) if err != nil { return "", nil, err } cmd := exec.CommandContext(ctx, "hugo", "--source", p.SiteStagingDir(site, BaseSiteDir), "--destination", outDir, "--baseURL", target.URL) cmd.Stderr = os.Stderr cmd.Stdout = os.Stdout if err := cmd.Run(); err != nil { return "", clean, err } return outDir, clean, nil } func (p *Provider) ReconfigureSite(ctx context.Context, site models.Site) error { hugoCfg := hugoConfig{ Title: site.Title, LanguageCode: "en", Theme: site.Theme, Markup: hugoConfigMarkup{ Goldmark: hugoGoldmarkConfig{ Renderer: hugoGoldmarkRendererConfig{ Unsafe: true, }, }, }, } ymlBytes, err := yaml.Marshal(hugoCfg) if err != nil { return err } if err := os.WriteFile(filepath.Join(p.SiteStagingDir(site, BaseSiteDir), "hugo.yaml"), ymlBytes, 0644); err != nil { return err } if _, err := os.Stat(filepath.Join(p.SiteStagingDir(site, BaseSiteDir), "hugo.toml")); err == nil { if err := os.Remove(filepath.Join(p.SiteStagingDir(site, BaseSiteDir), "hugo.toml")); err != nil { return err } } return nil }