Skip to content

Commit

Permalink
Refactor build hook
Browse files Browse the repository at this point in the history
  • Loading branch information
nenadalm committed Jan 10, 2024
1 parent c9c8614 commit 8e07837
Show file tree
Hide file tree
Showing 3 changed files with 93 additions and 43 deletions.
2 changes: 1 addition & 1 deletion shadow-cljs.edn
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
:dev {:closure-defines {"re_frame.trace.trace_enabled_QMARK_" true}}
:release {:module-hash-names true}
:devtools {:preloads [day8.re-frame-10x.preload]}
:build-hooks [(build.hook/hook)]
:build-hooks [(build.hook/hook {:public-dir "resources/public"})]
:target :browser}
:test {:target :node-test
:output-to "target/node-test.js"
Expand Down
82 changes: 82 additions & 0 deletions src/build/assets.clj
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
(ns build.assets
(:require
[clojure.java.io :as io]
[build.util :as u]))

(defn- path [s]
(java.nio.file.Paths/get s (make-array java.lang.String 0)))

(defn- symlink [link target]
(let [link-path (path link)
target-rel (.relativize (.getParent link-path)
(path target))]
(.mkdirs (.toFile (.getParent link-path)))
(java.nio.file.Files/createSymbolicLink link-path target-rel (make-array java.nio.file.attribute.FileAttribute 0))))

(defn- copy [src target]
(let [target-f (io/file target)]
(.mkdirs (.getParentFile target-f))
(io/copy
(io/file src)
target-f)))

(defn- file-name->file-name-and-extension [s]
(let [ext-index (.lastIndexOf s ".")]
(if (== -1 ext-index)
[s]
[(.substring s 0 ext-index) (.substring s (inc ext-index))])))

(defn- hashed-asset [asset hash]
(let [asset-path (path asset)
dir (.getParent asset-path)
asset-file-name (.getFileName asset-path)
[asset-name asset-ext] (file-name->file-name-and-extension (.toString asset-file-name))
target (str (when dir (str dir "/")) asset-name "." hash (when asset-ext (str "." asset-ext)))]
target))

(comment
(hashed-asset "app" "hash")
(hashed-asset "app.js" "hash")
(hashed-asset "js/app.js" "hash")
;;
)

(defn- symlink-assets [{:keys [public-dir assets]}]
(doseq [[asset src] assets]
(symlink (str public-dir "/" asset) src))
{})

(defn- hash-assets [{:keys [public-dir assets]}]
(reduce
(fn [acc [asset src]]
(let [hash (u/file-hash src)
asset-path (hashed-asset asset hash)
target (str public-dir "/" asset-path)]
(copy src target)
(assoc acc asset asset-path)))
{}
assets))

(defn create
"opts:
- `:public-dir`
- `:assets` - map where key is asset path and value file path"
[build-state asset-opts]
(case (:shadow.build/mode build-state)
:release (hash-assets asset-opts)
(symlink-assets asset-opts)))

(defn from-modules
"opts:
- `:public-dir`"
[build-state {:keys [public-dir]}]
(let [output-dir (get-in build-state [:shadow.build/config :output-dir])
path-prefix (str (.relativize
(path public-dir)
(path output-dir))
"/")]
(-> (group-by (fn [m]
(str path-prefix (m :module-name)))
(:shadow.build.closure/modules build-state))
(update-vals (fn [coll]
(str path-prefix (-> coll first :output-name)))))))
52 changes: 10 additions & 42 deletions src/build/hook.clj
Original file line number Diff line number Diff line change
Expand Up @@ -4,50 +4,18 @@
[build.create-manifest]
[build.create-index]
[build.create-worker]
[build.util :as u]))

(defn- file->output-name [build-state]
(-> (group-by (fn [m]
(str "js/" (m :module-name))) (:shadow.build.closure/modules build-state))
(update-vals (fn [coll]
(str "js/" (-> coll first :output-name))))))

(defn- path [s]
(java.nio.file.Paths/get s (make-array java.lang.String 0)))

(defn- symlink [link target]
(let [link-path (path link)
target-rel (.relativize (.getParent link-path)
(path target))]
(.mkdirs (.toFile (.getParent link-path)))
(java.nio.file.Files/createSymbolicLink link-path target-rel (make-array java.nio.file.attribute.FileAttribute 0))))

(defn- copy [src target]
(let [target-f (io/file target)]
(.mkdirs (.getParentFile target-f))
(io/copy
(io/file src)
target-f)))

(defn- create-styles [build-mode]
(let [src "resources/private/css/styles.css"]
(case build-mode
:release
(let [hash (u/file-hash src)
target (str "resources/public/css/styles." hash ".css")]
(copy src target)
{"css/styles.css" (str "css/styles." hash ".css")})
(do
(symlink "resources/public/css/styles.css" src)
{}))))
[build.assets :as assets]))

(defn hook
{:shadow.build/stage :flush}
[build-state & _args]
[build-state {:keys [public-dir]}]
(when-not (.exists (io/file "resources/public/worker.js"))
(let [outputs (merge (file->output-name build-state)
(create-styles (:shadow.build/mode build-state)))]
(spit "resources/public/manifest.json" (build.create-manifest/render outputs))
(spit "resources/public/index.html" (build.create-index/render outputs))
(spit "resources/public/worker.js" (build.create-worker/render outputs))))
(let [assets (merge (assets/from-modules build-state {:public-dir public-dir})
(assets/create
build-state
{:public-dir public-dir
:assets {"css/styles.css" "resources/private/css/styles.css"}}))]
(spit "resources/public/manifest.json" (build.create-manifest/render assets))
(spit "resources/public/index.html" (build.create-index/render assets))
(spit "resources/public/worker.js" (build.create-worker/render assets))))
build-state)

0 comments on commit 8e07837

Please sign in to comment.