venantius/pyro

Evict cache on file change

Closed this issue · 2 comments

At the moment the caching mechanism only keeps track of the filename. But presumably people might discover a bug, change the file, and trigger a new stacktrace. In that case Pyro will currently still return the old file as part of the trace, which isn't helpful at all. So either Pyro needs some way of keeping track of which files have been reloaded (possible) or Pyro needs to keep track of some sort of hash of the file's contents.

Here is a take on retrieving lastModified for different types of filepaths.
This should be sufficient to determine if files have changed, I think. (?)

(defn filepath->lastModified
  [filepath]
  (let [url (io/resource filepath)
        file (io/file filepath)]
    (cond
      ; handle files inside JARs
      ; (io/resource "clojure/java/io.clj") =>
      ; URL "jar:file:/Users/ivref/.m2/repository/org/clojure/clojure/1.8.0/clojure-1.8.0.jar!/clojure/java/io.clj"
      (and url (= "jar" (.getProtocol url))) (-> url
                                                 (.getFile)
                                                 (str/split #"!")
                                                 (first)
                                                 (subs 5)
                                                 (io/file)
                                                 (.lastModified))

      ; handle local files loaded using require and similar
      ; (io/resource "pyro/source.clj") =>
      ; URL "file:/Users/ivref/clojure/pyro/src/pyro/source.clj"
      (and url (= "file" (.getProtocol url))) (-> url (.getFile) (io/file) (.lastModified))

      ; handle files loaded using Cursive, load-file and similar
      (.exists file) (.lastModified file)

      :else (throw (ex-info "Could not find lastModified for filepath" {:filepath filepath})))))

Hopefully resolved by #15.