Updated tests, added some nil handling and started to simplify classpath_able_io.clj

This commit is contained in:
Clemens Geibel 2020-02-06 18:01:09 +01:00
parent 53a897d687
commit 202ed27e2b
6 changed files with 128 additions and 156 deletions

View file

View file

@ -9,82 +9,48 @@
(ns cryogen-core.classpath-able-io (ns cryogen-core.classpath-able-io
(:require [clojure.java.io :as io] (:require [clojure.java.io :as io]
[clojure.string :as st] [clojure.string :as st]
[cryogen-core.classpath-able-io.fs :as fs]
[cryogen-core.classpath-able-io.jar :as jar]
[cryogen-core.classpath-able-io.type :as type]
[schema.core :as s]) [schema.core :as s])
(:import [java.net URI] (:import [java.net URI]
[java.util.jar JarFile JarEntry] [java.util.jar JarFile JarEntry]
[java.nio.file FileSystems Paths Files LinkOption StandardCopyOption] [java.nio.file FileSystems Paths Files LinkOption StandardCopyOption]
[java.nio.file.attribute FileAttribute])) [java.nio.file.attribute FileAttribute]))
; -------------------- Domain Definition ------------------------------ (s/defn create-fs-resource :- type/Resource
(def SourceType (s/enum :java-classpath-filesystem :java-classpath-jar :filesystem)) ([virtual-path :- type/VirtualPath
(def ResourceType (s/enum :file :dir :unknown)) java-path :- type/JavaPath]
(def Prefix s/Str)
(def JavaUri s/Any) ; java.net.URI
(def VirtualPath s/Str)
(def JavaPath s/Any) ; java.nio.Path
(def Resource
{:virtual-path VirtualPath
:source-type SourceType
:resource-type ResourceType
:java-uri JavaUri
:java-path JavaPath})
; ----------------------- Domain functions ------------------------
(def no-link-option (into-array [LinkOption/NOFOLLOW_LINKS]))
(s/defn is-from-classpath-jar? :- s/Bool
[uri ;:- JavaUri
]
(= (.getScheme uri) "jar"))
(s/defn create-fs-resource :- Resource
([virtual-path :- VirtualPath
java-path :- JavaPath]
{:virtual-path virtual-path {:virtual-path virtual-path
:java-uri (.toUri java-path) :java-uri (.toUri java-path)
:java-path java-path :java-path java-path
:source-type :filesystem :source-type :filesystem
:resource-type (cond :resource-type (cond
(Files/isDirectory java-path no-link-option) :dir (Files/isDirectory java-path fs/no-link-option) :dir
(Files/isRegularFile java-path no-link-option) :file (Files/isRegularFile java-path fs/no-link-option) :file
:else :unknown)})) :else :unknown)}))
(s/defn create-cp-resource :- Resource (s/defn create-cp-resource :- type/Resource
([virtual-path :- VirtualPath ([virtual-path :- type/VirtualPath
java-path :- JavaPath] java-path :- type/JavaPath]
(let [java-uri (.toUri java-path)] (let [java-uri (.toUri java-path)]
{:virtual-path virtual-path {:virtual-path virtual-path
:java-uri java-uri :java-uri java-uri
:java-path java-path :java-path java-path
:source-type (cond (is-from-classpath-jar? java-uri) :source-type (cond (jar/is-from-classpath-jar? java-uri)
:java-classpath-jar :java-classpath-jar
:else :java-classpath-filesystem) :else :java-classpath-filesystem)
:resource-type (cond :resource-type (cond
(Files/isDirectory java-path no-link-option) :dir (Files/isDirectory java-path fs/no-link-option) :dir
(Files/isRegularFile java-path no-link-option) :file (Files/isRegularFile java-path fs/no-link-option) :file
:else :unknown)}))) :else :unknown)})))
(s/defn is-file? :- s/Bool
[resource :- Resource]
(= :file (:resource-type resource)))
(defn filter-for-ignore-patterns (defn filter-for-ignore-patterns
[ignore-patterns source-list] [ignore-patterns source-list]
(filter #(not (re-matches ignore-patterns %)) source-list)) (filter #(not (re-matches ignore-patterns %)) source-list))
; ------------------- infra --------------------------------- ; ------------------- infra ---------------------------------
(defn user-dir []
(java.lang.System/getProperty "user.dir"))
(defn absolut-path
[& path-elements]
(let [path (.normalize
(Paths/get (first path-elements)
(into-array String (rest path-elements))))]
(if (.isAbsolute path)
path
(Paths/get (user-dir) (into-array String path-elements)))))
; TODO replace this fn ? ; TODO replace this fn ?
(defn path (defn path
@ -95,35 +61,23 @@
(st/join "/") (st/join "/")
(#(st/replace % #"/+" "/")))) (#(st/replace % #"/+" "/"))))
(s/defn
filesystem-uri
[resource-uri :- JavaUri]
(URI. (first (st/split (.toString resource-uri) #"!"))))
(s/defn init-file-system
[resource-uri :- JavaUri]
(try
(FileSystems/getFileSystem (filesystem-uri resource-uri))
(catch Exception e
(FileSystems/newFileSystem (filesystem-uri resource-uri) {}))))
; contains either a jar or a file ; contains either a jar or a file
(s/defn path-from-cp ;:- JavaPath (s/defn path-from-cp ;:- JavaPath
[resource-path :- VirtualPath] [resource-path :- type/VirtualPath]
(try (try
(let [resource-uri (.toURI (io/resource resource-path))] (let [resource-uri (.toURI (io/resource resource-path))]
(when (is-from-classpath-jar? resource-uri) (when (jar/is-from-classpath-jar? resource-uri)
(init-file-system resource-uri)) (jar/init-file-system resource-uri))
(when (Files/exists (Paths/get resource-uri) no-link-option) (when (Files/exists (Paths/get resource-uri) fs/no-link-option)
(Paths/get resource-uri))) (Paths/get resource-uri)))
(catch Exception e (catch Exception e
nil))) nil)))
(s/defn path-from-fs ;:- JavaPath (s/defn path-from-fs ;:- JavaPath
[full-path :- VirtualPath] [full-path :- type/VirtualPath]
(let [path-from-fs (Paths/get (URI. (str "file://" full-path)))] ;fragile (let [path-from-fs (Paths/get (URI. (str "file://" full-path)))] ;fragile
(try (try
(when (Files/exists path-from-fs no-link-option) (when (Files/exists path-from-fs fs/no-link-option)
path-from-fs) path-from-fs)
(catch Exception e (catch Exception e
nil)))) nil))))
@ -135,7 +89,7 @@
& {:keys [from-cp from-fs] & {:keys [from-cp from-fs]
:or {from-cp true :or {from-cp true
from-fs true}}] from-fs true}}]
(let [full-path (.toString (absolut-path fs-prefix base-path resource-path)) (let [full-path (.toString (fs/absolut-path fs-prefix base-path resource-path))
cp-path (if (empty? base-path) cp-path (if (empty? base-path)
resource-path resource-path
(str base-path "/" resource-path)) (str base-path "/" resource-path))
@ -177,59 +131,63 @@
(not (= element norm-path-to-filter-for)))) (not (= element norm-path-to-filter-for))))
elements-list)))) elements-list))))
(defn jar-file-for-resource (s/defn
[resource] list-entries-for-dir ;:- [VirtualPath]
(JarFile. [resource :- type/Resource]
(.toFile (if (= :java-classpath-jar (:source-type resource))
(Paths/get (filter-and-remove-for-dir
(URI. (:virtual-path resource)
(.getSchemeSpecificPart (map #(.getName ^JarEntry %)
(filesystem-uri (:java-uri resource)))))))) (enumeration-seq
(.entries
(jar/jar-file-for-resource resource)))))
(.list (.toFile (:java-path resource)))))
(s/defn (defn get-resources-recursive ;:- [Resource]
list-entries-for-dir ;:- [VirtualPath] [fs-prefix ;:- Prefix
[resource :- Resource] base-path ;:- VirtualPath
(if (= :java-classpath-jar (:source-type resource)) paths ;:- [VirtualPath]
(filter-and-remove-for-dir & {:keys [from-cp from-fs]
(:virtual-path resource) :or {from-cp true
(map #(.getName ^JarEntry %) from-fs true}}]
(enumeration-seq (loop [paths paths
(.entries result []]
(jar-file-for-resource resource))))) (if (not (empty? paths))
(.list (.toFile (:java-path resource))))) (do
(let [path-to-work-with (first paths)
(defn get-resources-recursive ;:- [Resource] resource-to-work-with (resource-from-cp-or-fs
[fs-prefix ;:- Prefix fs-prefix
base-path ;:- VirtualPath base-path
paths ;:- [VirtualPath] path-to-work-with
& {:keys [from-cp from-fs] :from-cp from-cp
:or {from-cp true :from-fs from-fs)
from-fs true}}] result (into result
(loop [paths paths [resource-to-work-with])]
result []]
(if (not (empty? paths))
(do
(let [path-to-work-with (first paths)
resource-to-work-with (resource-from-cp-or-fs
fs-prefix
base-path
path-to-work-with
:from-cp from-cp
:from-fs from-fs)
result (into result
[resource-to-work-with])]
; (println path-to-work-with) ; (println path-to-work-with)
; (println (:java-path resource-to-work-with)) ; (println (:java-path resource-to-work-with))
(cond (cond
(nil? resource-to-work-with) [] (nil? resource-to-work-with) []
(is-file? resource-to-work-with) (type/is-file? resource-to-work-with)
(recur (drop 1 paths) result) (recur (drop 1 paths) result)
:else :else
(recur (into (drop 1 paths) (recur (into (drop 1 paths)
(map #(str path-to-work-with "/" %) (map #(str path-to-work-with "/" %)
(list-entries-for-dir resource-to-work-with))) (list-entries-for-dir resource-to-work-with)))
result)))) result))))
result))) result)))
; TODO: rename? Allow base-path to be ""?
; base-path must not be ""
(defn get-resources-recursive-new ;:- [Resource]
[fs-prefix ;:- Prefix
base-path ;:- VirtualPath
paths ;:- [VirtualPath]
& {:keys [from-cp from-fs]
:or {from-cp true
from-fs true}}]
(let [fs-resources (fs/get-resources fs-prefix base-path paths)
jar-resources (jar/get-resources base-path paths)])
)
(defn get-resource-paths-recursive ;:- [VirtualPath] (defn get-resource-paths-recursive ;:- [VirtualPath]
[fs-prefix ;:- Prefix [fs-prefix ;:- Prefix
@ -249,12 +207,12 @@
[virtual-path :- s/Str] [virtual-path :- s/Str]
(let [resource-paths (let [resource-paths
(reverse (get-resource-paths-recursive (reverse (get-resource-paths-recursive
(str (user-dir) "/") (str (fs/user-dir) "/")
virtual-path virtual-path
[""] [""]
:from-cp false))] :from-cp false))]
(doseq [resource-path resource-paths] (doseq [resource-path resource-paths]
(Files/delete (absolut-path virtual-path resource-path)) (Files/delete (fs/absolut-path virtual-path resource-path))
))) )))
; TODO: add ignore patterns filtering ; TODO: add ignore patterns filtering
@ -271,14 +229,14 @@
(throw (IllegalArgumentException. (str "resource " resource-paths ", " (throw (IllegalArgumentException. (str "resource " resource-paths ", "
source-paths " not found"))) source-paths " not found")))
(doseq [resource-path resource-paths] (doseq [resource-path resource-paths]
(let [target-file (absolut-path target-path resource-path) (let [target-file (fs/absolut-path target-path resource-path)
source-file (path-from-cp-or-fs source-file (path-from-cp-or-fs
fs-prefix fs-prefix
base-path base-path
resource-path)] resource-path)]
(when (Files/isDirectory source-file no-link-option) (when (Files/isDirectory source-file fs/no-link-option)
(Files/createDirectories target-file (into-array FileAttribute []))) (Files/createDirectories target-file (into-array FileAttribute [])))
(when (Files/isRegularFile source-file no-link-option) (when (Files/isRegularFile source-file fs/no-link-option)
(Files/copy source-file target-file (into-array StandardCopyOption [StandardCopyOption/COPY_ATTRIBUTES StandardCopyOption/REPLACE_EXISTING])) (Files/copy source-file target-file (into-array StandardCopyOption [StandardCopyOption/COPY_ATTRIBUTES StandardCopyOption/REPLACE_EXISTING]))
)))))) ))))))

View file

@ -36,14 +36,16 @@
(defn create-resource (defn create-resource
([virtual-path ([virtual-path
java-path] java-path]
{:virtual-path virtual-path (if (nil? java-path)
:java-uri (.toUri java-path) nil
:java-path java-path {:virtual-path virtual-path
:source-type :filesystem :java-uri (.toUri java-path)
:resource-type (cond :java-path java-path
(Files/isDirectory java-path follow-link-option) :dir :source-type :filesystem
(Files/isRegularFile java-path follow-link-option) :file :resource-type (cond
:else :unknown)}) (Files/isDirectory java-path follow-link-option) :dir
(Files/isRegularFile java-path follow-link-option) :file
:else :unknown)}))
([fs-prefix ([fs-prefix
base-path base-path
virtual-path] virtual-path]
@ -70,7 +72,7 @@
result (into result result (into result
[resource-to-work-with])] [resource-to-work-with])]
(cond (cond
(nil? resource-to-work-with) [] (nil? resource-to-work-with) (recur (drop 1 paths) result)
(type/is-file? resource-to-work-with) (type/is-file? resource-to-work-with)
(recur (drop 1 paths) result) (recur (drop 1 paths) result)
(type/is-dir? resource-to-work-with) (type/is-dir? resource-to-work-with)
@ -79,4 +81,4 @@
(list-entries-for-dir resource-to-work-with))) (list-entries-for-dir resource-to-work-with)))
result) result)
:else [])) :else []))
result))) (remove nil? result))))

View file

@ -24,15 +24,17 @@
([virtual-path ;:- VirtualPath ([virtual-path ;:- VirtualPath
java-path ;:- JavaPath java-path ;:- JavaPath
] ]
(let [java-uri (.toUri java-path)] (if (nil? java-path)
{:virtual-path virtual-path nil
:java-uri java-uri (let [java-uri (.toUri java-path)]
:java-path java-path {:virtual-path virtual-path
:source-type :java-classpath-jar :java-uri java-uri
:resource-type (cond :java-path java-path
(Files/isDirectory java-path fs/no-link-option) :dir :source-type :java-classpath-jar
(Files/isRegularFile java-path fs/no-link-option) :file :resource-type (cond
:else :unknown)}))) (Files/isDirectory java-path fs/no-link-option) :dir
(Files/isRegularFile java-path fs/no-link-option) :file
:else :unknown)}))))
(defn (defn
filesystem-uri filesystem-uri
@ -101,9 +103,11 @@
[base-path ;:- VirtualPath [base-path ;:- VirtualPath
resource ;:- Resource resource ;:- Resource
] ]
(filter-and-remove-for-dir (if (nil? resource)
base-path []
(list-entries resource))) (filter-and-remove-for-dir
base-path
(list-entries resource))))
(defn get-resources;:- [Resource] (defn get-resources;:- [Resource]
"base-path is sensible for getting the right jar from classpath. So base-path "base-path is sensible for getting the right jar from classpath. So base-path

View file

@ -32,14 +32,22 @@
(deftest test-list-entries-for-dir (deftest test-list-entries-for-dir
(is (is
(= ["dummy_from_fs"] (= ["dummy_from_fs" "dummy2"]
(seq (seq
(sut/list-entries-for-dir (sut/list-entries-for-dir
(sut/create-resource "dummy" (sut/path-if-exists (str fs-root "/dummy")))))))) (sut/create-resource "dummy" (sut/path-if-exists fs-root "dummy")))))))
(deftest test-get-resources (deftest test-get-resources
;(is
; (= [{:virtual-path "dummy" :source-type :filesystem :resource-type :dir}
; {:virtual-path "dummy/dummy_from_fs" :source-type :filesystem :resource-type :file}]
; (map ftt/filter-object
; (sut/get-resources fs-root "" ["dummy"]))))
(is (is
(= [{:virtual-path "dummy" :source-type :filesystem :resource-type :dir} (= [{:virtual-path "dummy_from_fs" :source-type :filesystem :resource-type :file}]
{:virtual-path "dummy/dummy_from_fs" :source-type :filesystem :resource-type :file}]
(map ftt/filter-object (map ftt/filter-object
(sut/get-resources fs-root "" ["dummy"]))))) (sut/get-resources fs-root "dummy" ["dummy_from_fs"]))))
(is
(= [{:virtual-path "dummy_from_fs" :source-type :filesystem :resource-type :file}]
(map ftt/filter-object
(sut/get-resources fs-root "dummy" ["dummy_from_fs" "not_existing"])))))

View file

@ -78,16 +78,16 @@
[] []
(sut/get-resources-recursive "" "templates/themes/bootstrap4-test" ["not-existing"]))) (sut/get-resources-recursive "" "templates/themes/bootstrap4-test" ["not-existing"])))
(is (= (is (=
[{:virtual-path "dummy", :source-type :java-classpath-jar, :resource-type :dir} [{:virtual-path "dummy_from_jar", :source-type :java-classpath-jar, :resource-type :file}]
{:virtual-path "dummy/dummy_from_jar", :source-type :java-classpath-jar, :resource-type :file}]
(map ftt/filter-object (map ftt/filter-object
(sut/get-resources-recursive "not-existing" "" ["dummy"])))) (sut/get-resources-recursive "not-existing" "dummy" ["dummy_from_jar"]))))
(is (= (is (=
[{:virtual-path "dummy", :source-type :java-classpath-jar, :resource-type :dir} [{:virtual-path "dummy_from_jar", :source-type :java-classpath-jar, :resource-type :file}
{:virtual-path "dummy/dummy_from_jar", :source-type :java-classpath-jar, :resource-type :file} {:virtual-path "dummy_from_fs", :source-type :filesystem, :resource-type :file}
{:virtual-path "dummy/dummy_from_fs", :source-type :java-classpath-jar, :resource-type :file}] {:virtual-path "dummy2", :source-type :filesystem, :resource-type :dir}
{:virtual-path "dummy2/dummy_common", :source-type :filesystem, :resource-type :file}]
(map ftt/filter-object (map ftt/filter-object
(sut/get-resources-recursive "fs_root" "" ["dummy"])))) (sut/get-resources-recursive "fs_root" "dummy" ["dummy_from_jar" "dummy_from_fs" "dummy2"]))))
(is (= (is (=
[{:virtual-path "js/dummy.js" [{:virtual-path "js/dummy.js"
:source-type :java-classpath-filesystem :source-type :java-classpath-filesystem