121 lines
4.6 KiB
EmacsLisp
121 lines
4.6 KiB
EmacsLisp
;;; build-runner.el --- Build orchestration -*- lexical-binding: t; -*-
|
|
|
|
;;; Code:
|
|
|
|
(require 'ox-publish)
|
|
|
|
(defun z/wipe-build-dirs ()
|
|
"Delete output/ and .org-timestamps/ together."
|
|
(dolist (dir (list z/output-root
|
|
(site-path ".org-timestamps/")))
|
|
(if (file-directory-p dir)
|
|
(progn
|
|
(z/with-timing (format "delete %s"
|
|
(file-name-nondirectory
|
|
(directory-file-name dir)))
|
|
(delete-directory dir t))
|
|
(z/log 'done "Deleted %s" dir))
|
|
(z/log 'info "Already absent: %s" dir))))
|
|
|
|
(defun z/output-integrity-ok-p ()
|
|
"Return t if critical output paths all exist."
|
|
(let ((missing '()))
|
|
(unless (file-directory-p (output-path "assets/"))
|
|
(push "output/assets/" missing))
|
|
(unless (or (file-exists-p (output-path "index.html"))
|
|
(file-exists-p (output-path "sitemap.html")))
|
|
(push "output/index.html (or sitemap.html)" missing))
|
|
(dolist (m missing)
|
|
(z/log 'warn "Integrity check: missing %s" m))
|
|
(null missing)))
|
|
|
|
(defun z/prepare-output-cache ()
|
|
"Keep org-publish output and timestamp cache in sync."
|
|
(z/log-separator "Pre-build")
|
|
(z/log 'info "Site source root : %s" z/site-root)
|
|
(z/log 'info "Site output root : %s" z/output-root)
|
|
(cond
|
|
((getenv "SITE_CLEAN")
|
|
(z/log 'warn "SITE_CLEAN=1 - wiping output/ and .org-timestamps/")
|
|
(z/wipe-build-dirs)
|
|
(setenv "SITE_FORCE" "1"))
|
|
((not (z/output-integrity-ok-p))
|
|
(z/log 'warn "Output integrity check failed - timestamp cache is stale")
|
|
(z/log 'warn "Clearing .org-timestamps/ and forcing full republish")
|
|
(let ((ts-dir (site-path ".org-timestamps/")))
|
|
(when (file-directory-p ts-dir)
|
|
(z/with-timing "delete .org-timestamps"
|
|
(delete-directory ts-dir t))
|
|
(z/log 'done "Deleted .org-timestamps/")))
|
|
(setenv "SITE_FORCE" "1"))
|
|
(t
|
|
(z/log 'info "Incremental build - output/ looks complete"))))
|
|
|
|
(defun z/generate-build-inputs ()
|
|
"Generate source-side data files required before publishing."
|
|
(z/log-separator "Generated inputs")
|
|
(z/with-timing "tag page generation"
|
|
(condition-case err
|
|
(let ((n (z/write-tag-pages)))
|
|
(z/log 'done "Tag pages written%s"
|
|
(if (numberp n) (format " (%d tags)" n) "")))
|
|
(error
|
|
(z/log 'error "Tag generation failed: %s" (error-message-string err))
|
|
(error "Aborting build: tag generation error"))))
|
|
(z/with-timing "comment page manifest"
|
|
(condition-case err
|
|
(z/generate-comment-pages-json)
|
|
(error
|
|
(z/log 'error "Comment page manifest failed: %s" (error-message-string err))
|
|
(error "Aborting build: comment page manifest error")))))
|
|
|
|
(defun z/publish-site ()
|
|
"Publish the configured site."
|
|
(z/log-separator "Publishing")
|
|
(if (getenv "SITE_DRY")
|
|
(z/log 'warn "SITE_DRY=1 - skipping org-publish-all (dry run)")
|
|
(let ((force (not (not (getenv "SITE_FORCE")))))
|
|
(when force
|
|
(z/log 'info "SITE_FORCE=1 - forcing republish of all files"))
|
|
(condition-case err
|
|
(progn
|
|
(z/with-timing "org-publish-all"
|
|
(org-publish-all force))
|
|
(z/with-timing "asset sync"
|
|
(z/sync-assets-to-output)))
|
|
(error
|
|
(z/log 'error "org-publish-all failed: %s" (error-message-string err))
|
|
(error "Build failed"))))))
|
|
|
|
(defun z/log-build-summary ()
|
|
"Log a summary of output artifacts."
|
|
(z/log-separator "Build summary")
|
|
(let* ((elapsed (- (float-time) z/build-start-time))
|
|
(out-dir z/output-root)
|
|
(html-files (when (file-directory-p out-dir)
|
|
(length (directory-files-recursively out-dir "\\.html\\'"))))
|
|
(css-files (when (file-directory-p out-dir)
|
|
(length (directory-files-recursively out-dir "\\.css\\'"))))
|
|
(js-files (when (file-directory-p out-dir)
|
|
(length (directory-files-recursively out-dir "\\.js\\'"))))
|
|
(tag-files (let ((td (output-path "tags/")))
|
|
(when (file-directory-p td)
|
|
(length (directory-files td nil "\\.html\\'"))))))
|
|
(z/log 'metric "Total elapsed : %.2fs" elapsed)
|
|
(z/log 'metric "HTML files output: %d" (or html-files 0))
|
|
(z/log 'metric "CSS files output: %d" (or css-files 0))
|
|
(z/log 'metric "JS files output: %d" (or js-files 0))
|
|
(z/log 'metric "Tag pages output: %d" (or tag-files 0))
|
|
(z/log 'done "Build complete")))
|
|
|
|
(defun z/run-build ()
|
|
"Run the full site build."
|
|
(z/prepare-output-cache)
|
|
(z/generate-build-inputs)
|
|
(z/publish-site)
|
|
(z/log-build-summary))
|
|
|
|
(provide 'build-runner)
|
|
|
|
;;; build-runner.el ends here
|