hugo-cms/services/sitebuilder/service.go

156 lines
3.5 KiB
Go
Raw Normal View History

2025-01-26 23:19:31 +00:00
package sitebuilder
import (
"context"
"errors"
2025-01-27 10:48:40 +00:00
"lmika.dev/lmika/hugo-cms/models"
2025-02-03 11:23:48 +00:00
"lmika.dev/lmika/hugo-cms/providers/bus"
2025-01-27 10:48:40 +00:00
"lmika.dev/lmika/hugo-cms/providers/db"
"lmika.dev/lmika/hugo-cms/providers/git"
"lmika.dev/lmika/hugo-cms/providers/hugo"
"lmika.dev/lmika/hugo-cms/providers/netlify"
"lmika.dev/lmika/hugo-cms/providers/themes"
2025-01-26 23:19:31 +00:00
"log"
2025-01-27 03:23:54 +00:00
"os"
"path/filepath"
2025-01-26 23:19:31 +00:00
)
type Service struct {
2025-01-27 04:45:53 +00:00
db *db.DB
themes *themes.Provider
git *git.Provider
hugo *hugo.Provider
netlify *netlify.Provider
2025-02-03 11:23:48 +00:00
bus *bus.Bus
2025-01-26 23:19:31 +00:00
}
func New(
2025-01-27 04:45:53 +00:00
db *db.DB,
2025-01-26 23:19:31 +00:00
themes *themes.Provider,
git *git.Provider,
hugo *hugo.Provider,
2025-01-27 04:45:53 +00:00
netlify *netlify.Provider,
2025-02-03 11:23:48 +00:00
bus *bus.Bus,
2025-01-26 23:19:31 +00:00
) *Service {
return &Service{
2025-01-27 04:45:53 +00:00
db: db,
themes: themes,
git: git,
hugo: hugo,
netlify: netlify,
2025-02-03 11:23:48 +00:00
bus: bus,
2025-01-26 23:19:31 +00:00
}
}
func (s *Service) CreateNewSite(site models.Site) models.Job {
return models.Job{
Do: func(ctx context.Context) error {
2025-02-03 11:23:48 +00:00
s.signalSiteBuildingStarted(ctx, site)
defer s.signalSiteBuildingFinished(ctx, site)
2025-01-27 04:45:53 +00:00
return s.createSite(ctx, site)
2025-01-26 23:19:31 +00:00
},
}
}
2025-01-27 03:23:54 +00:00
2025-02-01 22:54:30 +00:00
func (s *Service) RebuildSite(oldSite, newSite models.Site) models.Job {
2025-02-03 11:23:48 +00:00
return models.Job{
Do: func(ctx context.Context) error {
s.signalSiteBuildingStarted(ctx, newSite)
defer s.signalSiteBuildingFinished(ctx, newSite)
return s.rebuildSite(ctx, oldSite, newSite)
2025-01-27 04:45:53 +00:00
},
2025-02-03 11:23:48 +00:00
}
}
func (s *Service) rebuildSite(ctx context.Context, oldSite, newSite models.Site) error {
// Teardown the existing site
siteDir := s.hugo.SiteStagingDir(oldSite, hugo.BaseSiteDir)
if err := os.RemoveAll(siteDir); err != nil {
return err
}
if err := s.createSite(ctx, newSite); err != nil {
return err
}
if err := s.writeAllPosts(ctx, newSite); err != nil {
return err
}
2025-02-16 00:43:22 +00:00
if err := s.writeAllPages(ctx, newSite); err != nil {
return err
}
2025-02-03 11:23:48 +00:00
return s.publish(ctx, newSite)
2025-01-27 04:45:53 +00:00
}
2025-01-27 03:23:54 +00:00
func (s *Service) fullRebuildNecessary(ctx context.Context, site models.Site) (bool, error) {
dirsMustExists := []string{
s.hugo.SiteStagingDir(site, hugo.BaseSiteDir),
s.hugo.SiteStagingDir(site, hugo.ThemeSiteDir),
s.hugo.SiteStagingDir(site, hugo.ContentSiteDir),
}
filesMustExists := []string{
filepath.Join(s.hugo.SiteStagingDir(site, hugo.BaseSiteDir), "hugo.yaml"),
}
for _, dir := range dirsMustExists {
if stat, err := os.Stat(dir); err != nil {
if errors.Is(err, os.ErrNotExist) {
return true, nil
} else {
return false, err
}
} else if !stat.IsDir() {
return true, nil
}
}
for _, file := range filesMustExists {
if _, err := os.Stat(file); err != nil {
if errors.Is(err, os.ErrNotExist) {
return true, nil
} else {
return false, err
}
}
}
return false, nil
}
2025-01-27 04:45:53 +00:00
func (s *Service) createSite(ctx context.Context, site models.Site) error {
themeMeta, ok := s.themes.Lookup(site.Theme)
if !ok {
return errors.New("theme not found")
}
2025-01-27 03:23:54 +00:00
2025-01-27 04:45:53 +00:00
// Build the site
log.Printf(" .. build")
if err := s.hugo.NewSite(ctx, site); err != nil {
return err
}
2025-01-27 03:23:54 +00:00
2025-01-27 04:45:53 +00:00
// Setup the theme
log.Printf(" .. theme")
if err := s.git.Clone(ctx, themeMeta.URL, s.hugo.SiteStagingDir(site, hugo.ThemeSiteDir)); err != nil {
return err
}
2025-01-27 03:23:54 +00:00
2025-01-27 04:45:53 +00:00
if err := s.hugo.ReconfigureSite(ctx, site); err != nil {
return err
2025-01-27 03:23:54 +00:00
}
2025-01-27 04:45:53 +00:00
return nil
2025-01-27 03:23:54 +00:00
}
2025-02-03 11:23:48 +00:00
func (s *Service) signalSiteBuildingStarted(ctx context.Context, site models.Site) {
s.bus.Fire(models.Event{Type: models.EventSiteBuildingStart, Data: site})
}
func (s *Service) signalSiteBuildingFinished(ctx context.Context, site models.Site) {
s.bus.Fire(models.Event{Type: models.EventSiteBuildingDone, Data: site})
}
2025-02-16 00:43:22 +00:00