Created
November 18, 2014 02:06
-
-
Save micha/71c3bdb78e44af029602 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| (ns boot.tmpdir | |
| (:require | |
| [clojure.java.io :as io] | |
| [clojure.set :as set] | |
| [boot.file :as file])) | |
| (defprotocol ITmpFile | |
| (dir [this]) | |
| (path [this]) | |
| (file [this])) | |
| (defprotocol ITmpFileSet | |
| (user-dirs [this]) | |
| (input-dirs [this]) | |
| (output-dirs [this]) | |
| (user-files [this]) | |
| (input-files [this]) | |
| (output-files [this]) | |
| (add-asset! [this dir]) | |
| (add-source! [this dir]) | |
| (add-resource! [this dir])) | |
| (defrecord TmpFile [dir path] | |
| ITmpFile | |
| (dir [this] dir) | |
| (path [this] path) | |
| (file [this] (io/file dir path))) | |
| (defrecord TmpDir [dir user input output scoped restored]) | |
| (def ^:private masks | |
| {:user {:user true} | |
| :source {:input true :output nil} | |
| :resource {:input true :output true} | |
| :asset {:input nil :output true} | |
| :cache {:input nil :output nil} | |
| :input {:input true} | |
| :output {:output true} | |
| :scoped {:scoped true} | |
| :restored {:restored true}}) | |
| (defn- filter-keys | |
| [maps mask] | |
| (->> maps (filter #(= mask (select-keys % (keys mask)))))) | |
| (defn- temp-dirs-by | |
| [dirs & masks+] | |
| (->> masks+ (map masks) (apply merge) (filter-keys dirs) (map :dir) set)) | |
| (defn- temp-files-for | |
| [dirset] | |
| (->> dirset (mapcat file-seq) (filter (memfn isFile)))) | |
| (defn- merge-files! | |
| [tmp-files source-files dest-dir] | |
| (loop [ret tmp-files, [[p f] & fs] (seq source-files)] | |
| (if-not p | |
| ret | |
| (let [tmpf (get ret p) | |
| outf (io/file dest-dir p)] | |
| (file/copy-with-lastmod f outf) | |
| (when tmpf (io/delete-file (file tmpf) true)) | |
| (recur (assoc ret p (TmpFile. dest-dir p)) fs))))) | |
| (defn- add-dir! | |
| [fileset mask src-dir] | |
| (let [[out & _] (seq (-> (temp-dirs-by (:dirs fileset) mask) | |
| (set/difference (user-dirs fileset)))) | |
| split #(vector (str (file/relative-to %1 %2)) %2) | |
| ->files (partial filter (memfn isFile)) | |
| file-map #(->> % file-seq ->files (map (partial split %)) (into {}))] | |
| (assoc fileset :files (merge-files! (:files fileset) (file-map src-dir) out)))) | |
| (defn- tmp-dir | |
| [dir & masks+] | |
| (-> (->> masks+ (map masks) (apply merge)) (assoc :dir dir) map->TmpDir)) | |
| (defrecord TmpFileSet [dirs files] | |
| ITmpFileSet | |
| (user-dirs [this] (temp-dirs-by dirs :user)) | |
| (input-dirs [this] (temp-dirs-by dirs :input)) | |
| (output-dirs [this] (temp-dirs-by dirs :output)) | |
| (user-files [this] (temp-files-for (user-dirs this))) | |
| (input-files [this] (temp-files-for (input-dirs this))) | |
| (output-files [this] (temp-files-for (output-dirs this))) | |
| (add-asset! [this dir] (add-dir! this :asset dir)) | |
| (add-source! [this dir] (add-dir! this :source dir)) | |
| (add-resource! [this dir] (add-dir! this :resource dir))) | |
| (comment | |
| (def t1 (tmp-dir (io/file "foop1") :source)) | |
| (def t2 (tmp-dir (io/file "foop2") :resource)) | |
| (def tf (map->TmpFileSet {:dirs #{t1 t2} :files {}})) | |
| (input-dirs tf) | |
| (output-dirs tf) | |
| (def tf (add-source! tf (io/file "foop3"))) | |
| (def tf (add-resource! tf (io/file "foop3"))) | |
| (file-seq (io/file "foop3/")) | |
| (identity tf) | |
| (user-files tf) | |
| (input-files tf) | |
| (output-files tf) | |
| ) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment