about summary refs log tree commit diff stats
path: root/internal/builder/builder.go
diff options
context:
space:
mode:
authorAlan Pearce2024-06-13 20:51:49 +0200
committerAlan Pearce2024-06-13 20:52:16 +0200
commitf690e8cb7a820b0685b98f83a6761cfc169487e4 (patch)
tree3102375c3c3c9461776a79082f4db9898c1eee5e /internal/builder/builder.go
parent6b1697144e6261c09f1d2c254cf33d39f02ce92e (diff)
downloadwebsite-f690e8cb7a820b0685b98f83a6761cfc169487e4.tar.lz
website-f690e8cb7a820b0685b98f83a6761cfc169487e4.tar.zst
website-f690e8cb7a820b0685b98f83a6761cfc169487e4.zip
hash style elements during build step
Diffstat (limited to 'internal/builder/builder.go')
-rw-r--r--internal/builder/builder.go92
1 files changed, 55 insertions, 37 deletions
diff --git a/internal/builder/builder.go b/internal/builder/builder.go
index b17fbc2..bb6f40d 100644
--- a/internal/builder/builder.go
+++ b/internal/builder/builder.go
@@ -25,6 +25,10 @@ type IOConfig struct {
 	Development bool `conf:"default:false,flag:dev"`
 }
 
+type Result struct {
+	Hashes []string
+}
+
 func mkdirp(dirs ...string) error {
 	err := os.MkdirAll(path.Join(dirs...), 0755)
 
@@ -61,16 +65,19 @@ func writerToFile(writer io.WriterTo, filename ...string) error {
 	return nil
 }
 
-func build(outDir string, config config.Config) error {
+func build(outDir string, config config.Config) (*Result, error) {
 	log.Debug("output", "dir", outDir)
+	r := &Result{
+		Hashes: make([]string, 0),
+	}
 	assetsOnce = sync.Once{}
 	privateDir := path.Join(outDir, "private")
 	if err := mkdirp(privateDir); err != nil {
-		return errors.WithMessage(err, "could not create private directory")
+		return nil, errors.WithMessage(err, "could not create private directory")
 	}
 	publicDir := path.Join(outDir, "public")
 	if err := mkdirp(publicDir); err != nil {
-		return errors.WithMessage(err, "could not create public directory")
+		return nil, errors.WithMessage(err, "could not create public directory")
 	}
 
 	err := cp.Copy("static", publicDir, cp.Options{
@@ -78,16 +85,16 @@ func build(outDir string, config config.Config) error {
 		PermissionControl: cp.AddPermission(0755),
 	})
 	if err != nil {
-		return errors.WithMessage(err, "could not copy static files")
+		return nil, errors.WithMessage(err, "could not copy static files")
 	}
 
 	if err := mkdirp(publicDir, "post"); err != nil {
-		return errors.WithMessage(err, "could not create post output directory")
+		return nil, errors.WithMessage(err, "could not create post output directory")
 	}
 	log.Debug("reading posts")
 	posts, tags, err := readPosts("content", "post", publicDir)
 	if err != nil {
-		return err
+		return nil, err
 	}
 
 	sm := NewSitemap(config)
@@ -98,7 +105,7 @@ func build(outDir string, config config.Config) error {
 
 	for _, post := range posts {
 		if err := mkdirp(publicDir, "post", post.Basename); err != nil {
-			return errors.WithMessage(err, "could not create directory for post")
+			return nil, errors.WithMessage(err, "could not create directory for post")
 		}
 		log.Debug("rendering post", "post", post.Basename)
 		sm.Add(&sitemap.URL{
@@ -107,23 +114,23 @@ func build(outDir string, config config.Config) error {
 		})
 		output, err := renderPost(post, config)
 		if err != nil {
-			return errors.WithMessagef(err, "could not render post %s", post.Input)
+			return nil, errors.WithMessagef(err, "could not render post %s", post.Input)
 		}
 		if err := outputToFile(output, post.Output); err != nil {
-			return err
+			return nil, err
 		}
 	}
 
 	if err := mkdirp(publicDir, "tags"); err != nil {
-		return errors.WithMessage(err, "could not create directory for tags")
+		return nil, errors.WithMessage(err, "could not create directory for tags")
 	}
 	log.Debug("rendering tags list")
 	output, err := renderTags(tags, config, "/tags")
 	if err != nil {
-		return errors.WithMessage(err, "could not render tags")
+		return nil, errors.WithMessage(err, "could not render tags")
 	}
 	if err := outputToFile(output, publicDir, "tags", "index.html"); err != nil {
-		return err
+		return nil, err
 	}
 	sm.Add(&sitemap.URL{
 		Loc:     "/tags/",
@@ -138,16 +145,16 @@ func build(outDir string, config config.Config) error {
 			}
 		}
 		if err := mkdirp(publicDir, "tags", tag); err != nil {
-			return errors.WithMessage(err, "could not create directory")
+			return nil, errors.WithMessage(err, "could not create directory")
 		}
 		log.Debug("rendering tags page", "tag", tag)
 		url := "/tags/" + tag
 		output, err := renderListPage(tag, config, matchingPosts, url)
 		if err != nil {
-			return errors.WithMessage(err, "could not render tag page")
+			return nil, errors.WithMessage(err, "could not render tag page")
 		}
 		if err := outputToFile(output, publicDir, "tags", tag, "index.html"); err != nil {
-			return err
+			return nil, err
 		}
 		sm.Add(&sitemap.URL{
 			Loc:     url,
@@ -155,27 +162,27 @@ func build(outDir string, config config.Config) error {
 		})
 
 		log.Debug("rendering tags feed", "tag", tag)
-		output, err = renderFeed(
+		feed, err := renderFeed(
 			fmt.Sprintf("%s - %s", config.Title, tag),
 			config,
 			matchingPosts,
 			tag,
 		)
 		if err != nil {
-			return errors.WithMessage(err, "could not render tag feed page")
+			return nil, errors.WithMessage(err, "could not render tag feed page")
 		}
-		if err := outputToFile(output, publicDir, "tags", tag, "atom.xml"); err != nil {
-			return err
+		if err := outputToFile(feed, publicDir, "tags", tag, "atom.xml"); err != nil {
+			return nil, err
 		}
 	}
 
 	log.Debug("rendering list page")
 	listPage, err := renderListPage("", config, posts, "/post")
 	if err != nil {
-		return errors.WithMessage(err, "could not render list page")
+		return nil, errors.WithMessage(err, "could not render list page")
 	}
 	if err := outputToFile(listPage, publicDir, "post", "index.html"); err != nil {
-		return err
+		return nil, err
 	}
 	sm.Add(&sitemap.URL{
 		Loc:     "/post/",
@@ -185,28 +192,37 @@ func build(outDir string, config config.Config) error {
 	log.Debug("rendering feed")
 	feed, err := renderFeed(config.Title, config, posts, "feed")
 	if err != nil {
-		return errors.WithMessage(err, "could not render feed")
+		return nil, errors.WithMessage(err, "could not render feed")
 	}
 	if err := outputToFile(feed, publicDir, "atom.xml"); err != nil {
-		return err
+		return nil, err
 	}
 
 	log.Debug("rendering feed styles")
 	feedStyles, err := renderFeedStyles()
 	if err != nil {
-		return errors.WithMessage(err, "could not render feed styles")
+		return nil, errors.WithMessage(err, "could not render feed styles")
 	}
 	if err := outputToFile(feedStyles, publicDir, "feed-styles.xsl"); err != nil {
-		return err
+		return nil, err
+	}
+	_, err = feedStyles.Seek(0, 0)
+	if err != nil {
+		return nil, err
+	}
+	h, err := getFeedStylesHash(feedStyles)
+	if err != nil {
+		return nil, err
 	}
+	r.Hashes = append(r.Hashes, h)
 
 	log.Debug("rendering homepage")
 	homePage, err := renderHomepage(config, posts, "/")
 	if err != nil {
-		return errors.WithMessage(err, "could not render homepage")
+		return nil, errors.WithMessage(err, "could not render homepage")
 	}
 	if err := outputToFile(homePage, publicDir, "index.html"); err != nil {
-		return err
+		return nil, err
 	}
 	// it would be nice to set LastMod here, but using the latest post
 	// date would be wrong as the homepage has its own content file
@@ -214,51 +230,53 @@ func build(outDir string, config config.Config) error {
 	sm.Add(&sitemap.URL{
 		Loc: "/",
 	})
+	h, err = getHTMLStyleHash(publicDir, "index.html")
+	r.Hashes = append(r.Hashes, h)
 
 	log.Debug("rendering 404 page")
 	notFound, err := render404(config, "/404.html")
 	if err != nil {
-		return errors.WithMessage(err, "could not render 404 page")
+		return nil, errors.WithMessage(err, "could not render 404 page")
 	}
 	if err := outputToFile(notFound, publicDir, "404.html"); err != nil {
-		return err
+		return nil, err
 	}
 
 	log.Debug("rendering sitemap")
 	if err := writerToFile(sm, publicDir, "sitemap.xml"); err != nil {
-		return err
+		return nil, err
 	}
 
 	log.Debug("rendering robots.txt")
 	rob, err := renderRobotsTXT(config)
 	if err != nil {
-		return err
+		return nil, err
 	}
 	if err := outputToFile(rob, publicDir, "robots.txt"); err != nil {
-		return err
+		return nil, err
 	}
 
-	return nil
+	return r, nil
 }
 
-func BuildSite(ioConfig IOConfig) error {
+func BuildSite(ioConfig IOConfig) (*Result, error) {
 	config, err := config.GetConfig()
 	if err != nil {
-		return errors.WithMessage(err, "could not get config")
+		return nil, errors.WithMessage(err, "could not get config")
 	}
 	config.InjectLiveReload = ioConfig.Development
 
 	if ioConfig.BaseURL.URL != nil {
 		config.BaseURL.URL, err = url.Parse(ioConfig.BaseURL.String())
 		if err != nil {
-			return errors.WithMessage(err, "could not re-parse base URL")
+			return nil, errors.WithMessage(err, "could not re-parse base URL")
 		}
 	}
 
 	if ioConfig.Development && ioConfig.Destination != "website" {
 		err = os.RemoveAll(ioConfig.Destination)
 		if err != nil {
-			return errors.WithMessage(err, "could not remove destination directory")
+			return nil, errors.WithMessage(err, "could not remove destination directory")
 		}
 	}