102 lines
3.1 KiB
Clojure
102 lines
3.1 KiB
Clojure
|
(ns swank.loader
|
||
|
(:require [swank.util.sys :as sys]
|
||
|
[swank.util.clojure :as clj])
|
||
|
(:import [java.io File]))
|
||
|
|
||
|
(defonce #^File *swank-source-path*
|
||
|
(if-let [resource (.getResource (clojure.lang.RT/baseLoader)
|
||
|
#^String *file*)]
|
||
|
(.getParentFile (File. (.getFile resource)))))
|
||
|
|
||
|
(defonce #^File *swank-compile-path*
|
||
|
(File. (str (sys/user-home-path)
|
||
|
File/separator
|
||
|
".slime"
|
||
|
File/separator
|
||
|
"cljclass")))
|
||
|
|
||
|
(defn file-directory? [#^File f]
|
||
|
(.isDirectory f))
|
||
|
|
||
|
(defn file-last-modified [#^File f]
|
||
|
(.lastModified f))
|
||
|
|
||
|
(defn all-files-in-directory [#^File f]
|
||
|
(let [list-files (.listFiles f)
|
||
|
files (remove file-directory? list-files)
|
||
|
directories (filter file-directory? list-files)]
|
||
|
(concat files (mapcat all-files-in-directory directories))))
|
||
|
|
||
|
(defn clj-file? [#^File f]
|
||
|
(.endsWith (str f) ".clj"))
|
||
|
|
||
|
(defn swank-source-files [#^File path]
|
||
|
(filter clj-file? (all-files-in-directory path)))
|
||
|
|
||
|
(defn relative-path-name [#^File parent #^File file]
|
||
|
(let [file-name (str file)
|
||
|
parent-name (str parent)]
|
||
|
(when (.startsWith file-name parent-name)
|
||
|
(.substring file-name (inc (.length parent-name))))))
|
||
|
|
||
|
(defn file-name-to-swank-package-sym [#^String file-name]
|
||
|
(assert (clj-file? file-name))
|
||
|
(symbol
|
||
|
(str "swank."
|
||
|
(clj/unmunge
|
||
|
(.replaceAll (.substring file-name 0 (- (.length file-name) 4))
|
||
|
File/separator
|
||
|
".")))))
|
||
|
|
||
|
(defn swank-packages []
|
||
|
(map #(file-name-to-swank-package-sym (relative-path-name *swank-source-path* %))
|
||
|
(swank-source-files *swank-source-path*)))
|
||
|
|
||
|
(defn swank-version
|
||
|
"A likely bad way of calculating a version number for swank clojure"
|
||
|
([]
|
||
|
(str (reduce + (map file-last-modified (swank-source-files *swank-source-path*)))
|
||
|
"+" (clojure-version))))
|
||
|
|
||
|
(defn delete-file-recursive [& paths]
|
||
|
(when-not (empty? paths)
|
||
|
(let [f #^File (first paths)]
|
||
|
(if (and f (.exists f))
|
||
|
(if (.isDirectory f)
|
||
|
(if-let [files (seq (.listFiles f))]
|
||
|
(recur (concat files paths))
|
||
|
(do
|
||
|
(.delete f)
|
||
|
(recur (rest paths))))
|
||
|
(do
|
||
|
(.delete f)
|
||
|
(recur (rest paths))))
|
||
|
(recur (rest paths))))))
|
||
|
|
||
|
(defn clean-up []
|
||
|
(let [current-path (File. *swank-compile-path* (str (swank-version)))]
|
||
|
(doseq [compiled-path (.listFiles *swank-compile-path*)
|
||
|
:when (not= current-path compiled-path)]
|
||
|
(delete-file-recursive compiled-path))))
|
||
|
|
||
|
(defn swank-ns? [ns]
|
||
|
(.startsWith (name (ns-name ns)) "swank."))
|
||
|
|
||
|
(defn all-swank-ns []
|
||
|
(filter swank-ns? (all-ns)))
|
||
|
|
||
|
(defn compile-swank [#^String path]
|
||
|
(binding [*compile-path* path]
|
||
|
(doseq [sym (swank-packages)]
|
||
|
(println "Compiling" (name sym))
|
||
|
(compile sym))))
|
||
|
|
||
|
(defn init []
|
||
|
(let [path (File. *swank-compile-path* (str (swank-version)))
|
||
|
path-already-exists? (.exists path)]
|
||
|
(when-not path-already-exists?
|
||
|
(.mkdirs path))
|
||
|
(add-classpath (-> path .toURI .toURL))
|
||
|
(when-not path-already-exists?
|
||
|
(compile-swank (str path)))))
|