From 23ca87a8cd473fd405469811ea9d7d512f996ff9 Mon Sep 17 00:00:00 2001 From: jem Date: Tue, 17 Dec 2019 16:58:11 +0100 Subject: [PATCH] introduce Resource for path-handling --- src/cryogen_core/classpath_able_io.clj | 134 ++++++++++++++++--- test/cryogen_core/classpath_able_io_test.clj | 14 +- 2 files changed, 119 insertions(+), 29 deletions(-) diff --git a/src/cryogen_core/classpath_able_io.clj b/src/cryogen_core/classpath_able_io.clj index 1b316a9..cbd54c9 100644 --- a/src/cryogen_core/classpath_able_io.clj +++ b/src/cryogen_core/classpath_able_io.clj @@ -11,6 +11,25 @@ [clojure.string :as st] [schema.core :as s])) +(def SourceType (s/enum :classpath :filesystem)) + +(def ResourceType (s/enum :file :dir :unknown)) + +(def Prefix s/Str) + +(def Uri s/Any) ; java.net.URI + +(def Path s/Str) + +(def File s/Any) ; java.io.File + +(def Resource + {:path Path + :uri Uri + :file File + :source-type SourceType + :resource-type ResourceType }) + (def public "resources/public") (defn path @@ -25,8 +44,31 @@ [ignore-patterns source-list] (filter #(not (re-matches ignore-patterns %)) source-list)) -(defn file-from-cp - [resource-path] +(s/defn create-resource :- Resource + ([path :- Path + uri :- Uri + file :- File + source-type :- SourceType + resource-type :- ResourceType] + {:path path + :uri uri + :file file + :source-type source-type + :resource-type resource-type}) + ([path :- Path + file :- File + source-type :- SourceType] + {:path path + :uri (.toURI file) + :file file + :source-type source-type + :resource-type (cond + (.isDirectory file) :dir + (.isFile file) :file + :else :unknown)})) + +(s/defn file-from-cp ; :- File + [resource-path :- Path] (let [file-from-cp (io/file (io/resource resource-path))] (try (when (.exists file-from-cp) @@ -34,8 +76,9 @@ (catch Exception e nil)))) -(defn file-from-fs - [fs-prefix resource-path] +(s/defn file-from-fs ; :- File + [fs-prefix :- Prefix + resource-path :- Path] (let [file-from-fs (io/file (str fs-prefix resource-path))] (try (when (.exists file-from-fs) @@ -43,7 +86,26 @@ (catch Exception e nil)))) -(defn file-from-cp-or-filesystem +(defn resource-from-cp-or-filesystem ; :- Resource + [fs-prefix ; :- Prefix + resource-path ; :- Path + & {:keys [from-cp from-fs] + :or {from-cp true + from-fs true}}] + (let [file-from-fs (if from-fs + (file-from-fs fs-prefix resource-path) + nil) + file-from-cp (if from-cp + (file-from-cp resource-path) + nil)] + (cond + (some? file-from-fs) + (create-resource resource-path file-from-fs :filesystem) + (some? file-from-cp) + (create-resource resource-path file-from-cp :classpath) + :else nil))) + +(defn uri-from-cp-or-filesystem [fs-prefix resource-path & {:keys [from-cp from-fs] :or {from-cp true @@ -58,10 +120,38 @@ from-fs-file from-cp-file))) -(defn get-resource-paths-recursive ;:- [s/Str] - [fs-prefix ;:- s/Str - base-path ;:- s/Str - paths ;:- [s/Str] +(defn get-resources-recursive ;:- [Resource] + [fs-prefix ;:- Prefix + base-path ;:- Path + paths ;:- [Path] + & {:keys [from-cp from-fs] + :or {from-cp true + from-fs true}}] + (loop [paths paths + result []] + (if (not (empty? paths)) + (do + (let [path-to-work-with (first paths) + resource-to-work-with (resource-from-cp-or-filesystem + fs-prefix + (str base-path "/" path-to-work-with) + :from-cp from-cp + :from-fs from-fs) + result (into result [path-to-work-with])] + (cond + (nil? resource-to-work-with) [] + (= :file (:resource-type resource-to-work-with)) (recur (drop 1 paths) result) + :else + (recur (into (drop 1 paths) + (map #(str path-to-work-with "/" %) + (.list (:file resource-to-work-with)))) + result)))) + result))) + +(defn get-resource-paths-recursive ;:- [Path] + [fs-prefix ;:- Prefix + base-path ;:- Path + paths ;:- [Path] & {:keys [from-cp from-fs] :or {from-cp true from-fs true}}] @@ -70,19 +160,19 @@ (if (not (empty? paths)) (do (let [path-to-work-with (first paths) - file-to-work-with (io/file (file-from-cp-or-filesystem - fs-prefix - (str base-path "/" path-to-work-with) - :from-cp from-cp - :from-fs from-fs)) + resource-to-work-with (resource-from-cp-or-filesystem + fs-prefix + (str base-path "/" path-to-work-with) + :from-cp from-cp + :from-fs from-fs) result (into result [path-to-work-with])] (cond - (nil? file-to-work-with) [] - (.isFile file-to-work-with) (recur (drop 1 paths) result) + (nil? resource-to-work-with) [] + (= :file (:resource-type resource-to-work-with)) (recur (drop 1 paths) result) :else (recur (into (drop 1 paths) (map #(str path-to-work-with "/" %) - (.list file-to-work-with))) + (.list (:file resource-to-work-with)))) result) ))) result))) @@ -98,10 +188,10 @@ ; TODO: add ignore patterns filtering (defn copy-resources! - [fs-prefix ;:- s/Str - base-path ;:- s/Str - source-paths ;:- [s/Str] - target-path ;:- s/Str + [fs-prefix ;:- Prefix + base-path ;:- Path + source-paths ;:- [Path] + target-path ;:- Path ignore-patterns ;:- s/Str ] (let [resource-paths @@ -111,7 +201,7 @@ source-paths " not found"))) (doseq [resource-path resource-paths] (let [target-file (io/file target-path resource-path) - source-file (io/file (file-from-cp-or-filesystem + source-file (io/file (uri-from-cp-or-filesystem fs-prefix (str base-path "/" resource-path)))] (io/make-parents target-file) diff --git a/test/cryogen_core/classpath_able_io_test.clj b/test/cryogen_core/classpath_able_io_test.clj index e3794db..513a452 100644 --- a/test/cryogen_core/classpath_able_io_test.clj +++ b/test/cryogen_core/classpath_able_io_test.clj @@ -25,13 +25,13 @@ (and (verify-file-exists path) (.isDirectory (io/file path)))) -(deftest test-file-from-cp-or-filesystem +(deftest test-uri-from-cp-or-filesystem (is - (some? (sut/file-from-cp-or-filesystem + (some? (sut/uri-from-cp-or-filesystem "./test-resources/" "templates/themes/bootstrap4-test/js"))) (is - (some? (sut/file-from-cp-or-filesystem + (some? (sut/uri-from-cp-or-filesystem "./not-existing-so-load-from-cp" ".gitkeep")))) (deftest test-get-resource-paths-recursive @@ -80,16 +80,16 @@ ["file.js"] (sut/filter-for-ignore-patterns #".*\.ignore" ["file.js" "file.ignore"])))) -(deftest test-file-from-cp +(deftest test-uri-from-cp (is (sut/file-from-cp ".gitkeep"))) -(deftest test-file-from-cp-or-filesystem +(deftest test-uri-from-cp-or-filesystem (is - (.exists (sut/file-from-cp-or-filesystem + (.exists (sut/uri-from-cp-or-filesystem "./test-resources/" "templates/themes/bootstrap4-test/js"))) (is - (.exists (sut/file-from-cp-or-filesystem + (.exists (sut/uri-from-cp-or-filesystem "./" ".gitkeep")))) (deftest test-copy-resources-from-theme! (is (do