From 30c15ef248f78acce7fc133f77e4220014a9c9d5 Mon Sep 17 00:00:00 2001 From: Stuart Sierra Date: Fri, 17 Jul 2015 16:33:40 -0400 Subject: [PATCH 01/19] Use java.classpath Instead of relying on local functions to inspect the classpath, use the more robust, extensible versions in org.clojure/java.classpath. See also http://dev.clojure.org/jira/browse/CLASSPATH-5 --- pom.xml | 8 +++++ .../clojure/clojure/tools/namespace/dir.clj | 12 ++----- .../clojure/clojure/tools/namespace/file.clj | 27 +++++++++++----- .../clojure/clojure/tools/namespace/find.clj | 31 +++---------------- 4 files changed, 35 insertions(+), 43 deletions(-) diff --git a/pom.xml b/pom.xml index 80cc93a..4bd8cea 100644 --- a/pom.xml +++ b/pom.xml @@ -10,6 +10,14 @@ 0.1.2 + + + org.clojure + java.classpath + 0.2.2 + + + true diff --git a/src/main/clojure/clojure/tools/namespace/dir.clj b/src/main/clojure/clojure/tools/namespace/dir.clj index 9f9b0f1..87dd61d 100644 --- a/src/main/clojure/clojure/tools/namespace/dir.clj +++ b/src/main/clojure/clojure/tools/namespace/dir.clj @@ -12,6 +12,7 @@ clojure.tools.namespace.dir (:require [clojure.tools.namespace.file :as file] [clojure.tools.namespace.track :as track] + [clojure.java.classpath :refer [classpath-directories]] [clojure.java.io :as io] [clojure.set :as set] [clojure.string :as string]) @@ -40,13 +41,6 @@ (file/add-files modified) (assoc ::time now)))) -(defn- dirs-on-classpath [] - (filter #(.isDirectory ^File %) - (map #(File. ^String %) - (string/split - (System/getProperty "java.class.path") - (Pattern/compile (Pattern/quote File/pathSeparator)))))) - (defn scan "Scans directories for files which have changed since the last time 'scan' was run; update the dependency tracker with @@ -54,7 +48,7 @@ If no dirs given, defaults to all directories on the classpath." [tracker & dirs] - (let [ds (or (seq dirs) (dirs-on-classpath)) + (let [ds (or (seq dirs) (classpath-directories)) files (find-files ds) deleted (seq (deleted-files tracker files)) modified (seq (modified-files tracker files))] @@ -67,7 +61,7 @@ dependency tracker to reload files. If no dirs given, defaults to all directories on the classpath." [tracker & dirs] - (let [ds (or (seq dirs) (dirs-on-classpath)) + (let [ds (or (seq dirs) (classpath-directories)) files (find-files ds) deleted (seq (deleted-files tracker files))] (update-files tracker deleted files))) diff --git a/src/main/clojure/clojure/tools/namespace/file.clj b/src/main/clojure/clojure/tools/namespace/file.clj index 2d9c859..75be47f 100644 --- a/src/main/clojure/clojure/tools/namespace/file.clj +++ b/src/main/clojure/clojure/tools/namespace/file.clj @@ -16,21 +16,34 @@ (defn read-file-ns-decl "Attempts to read a (ns ...) declaration from file, and returns the - unevaluated form. Returns nil if read fails, or if the first form - is not a ns declaration." - [file] - (with-open [rdr (PushbackReader. (io/reader file))] - (parse/read-ns-decl rdr))) + unevaluated form. Returns nil if read fails due to invalid syntax or + if a ns declaration cannot be found. read-opts is passed through to + clojure.core/read if this version of Clojure supports it." + ([file] + (read-file-ns-decl file nil)) + ([file read-opts] + (with-open [rdr (PushbackReader. (io/reader file))] + (parse/read-ns-decl rdr read-opts)))) (defn clojure-file? - "Returns true if the java.io.File represents a normal Clojure source - file." + "Returns true if the java.io.File represents a file which will be + read by the Clojure (JVM) compiler." [^java.io.File file] (and (.isFile file) (or (.endsWith (.getName file) ".clj") (.endsWith (.getName file) ".cljc")))) +(defn clojurescript-file? + "Returns true if the java.io.File represents a file which will be + read by the ClojureScript compiler." + {:added "0.3.0"} + [^java.io.File file] + (and (.isFile file) + (or + (.endsWith (.getName file) ".cljs") + (.endsWith (.getName file) ".cljc")))) + ;;; Dependency tracker (defn- files-and-deps [files] diff --git a/src/main/clojure/clojure/tools/namespace/find.clj b/src/main/clojure/clojure/tools/namespace/find.clj index e22abbc..0ef73f2 100644 --- a/src/main/clojure/clojure/tools/namespace/find.clj +++ b/src/main/clojure/clojure/tools/namespace/find.clj @@ -10,7 +10,8 @@ ^{:author "Stuart Sierra", :doc "Search for namespace declarations in directories and JAR files."} clojure.tools.namespace.find - (:require [clojure.java.io :as io] + (:require [clojure.java.classpath :as classpath] + [clojure.java.io :as io] [clojure.set :as set] [clojure.tools.namespace.file :as file] [clojure.tools.namespace.parse :as parse]) @@ -18,30 +19,6 @@ InputStreamReader) (java.util.jar JarFile JarEntry))) -;;; JAR-file utilities, adapted from clojure.java.classpath - -(defn- jar-file? - "Returns true if file is a normal file with a .jar or .JAR extension." - [f] - (let [file (io/file f)] - (and (.isFile file) - (or (.endsWith (.getName file) ".jar") - (.endsWith (.getName file) ".JAR"))))) - -(defn- jar-files - "Given a sequence of File objects, filters it for JAR files, returns - a sequence of java.util.jar.JarFile objects." - [files] - (map #(JarFile. ^File %) (filter jar-file? files))) - -(defn- filenames-in-jar - "Returns a sequence of Strings naming the non-directory entries in - the JAR file." - [^JarFile jar-file] - (map #(.getName ^JarEntry %) - (filter #(not (.isDirectory ^JarEntry %)) - (enumeration-seq (.entries jar-file))))) - ;;; Finding namespaces in a directory tree (defn find-clojure-sources-in-dir @@ -70,7 +47,7 @@ "Returns a sequence of filenames ending in .clj or .cljc found in the JAR file." [^JarFile jar-file] (filter #(or (.endsWith ^String % ".clj") (.endsWith ^String % ".cljc")) - (filenames-in-jar jar-file))) + (classpath/filenames-in-jar jar-file))) (defn read-ns-decl-from-jarfile-entry "Attempts to read a (ns ...) declaration from the named entry in the @@ -108,7 +85,7 @@ [files] (concat (mapcat find-ns-decls-in-dir (filter #(.isDirectory ^File %) files)) - (mapcat find-ns-decls-in-jarfile (jar-files files)))) + (mapcat find-ns-decls-in-jarfile (filter classpath/jar-file? files)))) (defn find-namespaces "Searches a sequence of java.io.File objects (both directories and From df347c1d5ff9e6fc83bb7bef27c92ba650008e52 Mon Sep 17 00:00:00 2001 From: Stuart Sierra Date: Fri, 24 Jul 2015 12:23:06 -0400 Subject: [PATCH 02/19] c.t.n.file: extensions for Clojure & ClojureScript --- .../clojure/clojure/tools/namespace/file.clj | 29 ++++++++++++++----- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/src/main/clojure/clojure/tools/namespace/file.clj b/src/main/clojure/clojure/tools/namespace/file.clj index 75be47f..6f092d0 100644 --- a/src/main/clojure/clojure/tools/namespace/file.clj +++ b/src/main/clojure/clojure/tools/namespace/file.clj @@ -25,24 +25,37 @@ (with-open [rdr (PushbackReader. (io/reader file))] (parse/read-ns-decl rdr read-opts)))) +(defn file-with-extension? + "Returns true if the java.io.File represents a file whose name ends + with one of the Strings in extensions." + {:added "0.3.0"} + [^java.io.File file extensions] + (and (.isFile file) + (let [name (.getName file)] + (some #(.endsWith name %) extensions)))) + +(def ^{:added "0.3.0"} + clojure-extensions + "File extensions for Clojure (JVM) files." + (list ".clj" ".cljc")) + +(def ^{:added "0.3.0"} + clojurescript-extensions + "File extensions for ClojureScript files." + (list ".cljs" ".cljc")) + (defn clojure-file? "Returns true if the java.io.File represents a file which will be read by the Clojure (JVM) compiler." [^java.io.File file] - (and (.isFile file) - (or - (.endsWith (.getName file) ".clj") - (.endsWith (.getName file) ".cljc")))) + (file-with-extension? file clojure-extensions)) (defn clojurescript-file? "Returns true if the java.io.File represents a file which will be read by the ClojureScript compiler." {:added "0.3.0"} [^java.io.File file] - (and (.isFile file) - (or - (.endsWith (.getName file) ".cljs") - (.endsWith (.getName file) ".cljc")))) + (file-with-extension? file clojurescript-extensions)) ;;; Dependency tracker From e3aa01507594d699f7702ebb778dcf03b110df49 Mon Sep 17 00:00:00 2001 From: Stuart Sierra Date: Fri, 17 Jul 2015 16:26:46 -0400 Subject: [PATCH 03/19] Port dependency, parse, and track to .cljc Affects these namespaces: - clojure.tools.namespace.dependency - clojure.tools.namespace.parse - clojure.tools.namespace.track With minor changes, these files are platform-neutral. c.t.n.dependency is a general-purpose library which has many applications outside of tools.namespace. The uses for c.t.n.parse and c.t.n.track in ClojureScript are less apparent, but they are easy to port. Perhaps by porting other namespaces it will be possible in the future to have a version of c.t.n.repl that works on non-JVM platforms. Use tools.reader for platform-independent read. --- pom.xml | 13 +++- .../{dependency.clj => dependency.cljc} | 9 ++- .../tools/namespace/{parse.clj => parse.cljc} | 70 +++++++++---------- .../tools/namespace/{track.clj => track.cljc} | 0 4 files changed, 53 insertions(+), 39 deletions(-) rename src/main/clojure/clojure/tools/namespace/{dependency.clj => dependency.cljc} (97%) rename src/main/clojure/clojure/tools/namespace/{parse.clj => parse.cljc} (63%) rename src/main/clojure/clojure/tools/namespace/{track.clj => track.cljc} (100%) diff --git a/pom.xml b/pom.xml index 4bd8cea..4be4a10 100644 --- a/pom.xml +++ b/pom.xml @@ -1,7 +1,7 @@ 4.0.0 tools.namespace - 0.2.12-SNAPSHOT + 0.3.0-SNAPSHOT ${artifactId} @@ -11,11 +11,21 @@ + + clojure + 1.7.0 + provided + org.clojure java.classpath 0.2.2 + + org.clojure + tools.reader + 0.9.2 + @@ -34,4 +44,5 @@ git@github.com:clojure/tools.namespace.git HEAD + diff --git a/src/main/clojure/clojure/tools/namespace/dependency.clj b/src/main/clojure/clojure/tools/namespace/dependency.cljc similarity index 97% rename from src/main/clojure/clojure/tools/namespace/dependency.clj rename to src/main/clojure/clojure/tools/namespace/dependency.cljc index 96a5e9e..3c6b54a 100644 --- a/src/main/clojure/clojure/tools/namespace/dependency.clj +++ b/src/main/clojure/clojure/tools/namespace/dependency.cljc @@ -142,6 +142,10 @@ (remove-node g' node) (clojure.set/union (set more) (set add))))))) +(def ^:private max-number + #?(:clj Long/MAX_VALUE + :cljs js/Number.MAX_VALUE)) + (defn topo-comparator "Returns a comparator fn which produces a topological sort based on the dependencies in graph. Nodes not present in the graph will sort @@ -149,6 +153,5 @@ [graph] (let [pos (zipmap (topo-sort graph) (range))] (fn [a b] - (compare (get pos a Long/MAX_VALUE) - (get pos b Long/MAX_VALUE))))) - + (compare (get pos a max-number) + (get pos b max-number))))) diff --git a/src/main/clojure/clojure/tools/namespace/parse.clj b/src/main/clojure/clojure/tools/namespace/parse.cljc similarity index 63% rename from src/main/clojure/clojure/tools/namespace/parse.clj rename to src/main/clojure/clojure/tools/namespace/parse.cljc index 78a8fc0..846981b 100644 --- a/src/main/clojure/clojure/tools/namespace/parse.clj +++ b/src/main/clojure/clojure/tools/namespace/parse.cljc @@ -10,24 +10,9 @@ :doc "Parse Clojure namespace (ns) declarations and extract dependencies."} clojure.tools.namespace.parse - (:require [clojure.set :as set])) - -(defn- read-clj - "Calls clojure.core/read. If reader conditionals are - supported (Clojure 1.7) then adds options {:read-cond :allow}." - [rdr] - (if (resolve 'clojure.core/reader-conditional?) - (read {:read-cond :allow} rdr) - (read rdr))) - -(defn- force-errors - "Forces reader errors to be thrown immediately. Some versions of - Clojure accept invalid forms in the reader and only throw an - exception when they are printed. - See http://dev.clojure.org/jira/browse/TNS-1" - [form] - (str form) ; str forces errors - form) + (:require #?(:clj [clojure.tools.reader :as reader] + :cljs [cljs.tools.reader :as reader]) + [clojure.set :as set])) (defn comment? "Returns true if form is a (comment ...)" @@ -40,21 +25,23 @@ (and (list? form) (= 'ns (first form)))) (defn read-ns-decl - "Attempts to read a (ns ...) declaration from a - java.io.PushbackReader, and returns the unevaluated form. Returns - the first top-level ns form found. Returns nil if read fails or if a - ns declaration cannot be found. Note that read can execute code - (controlled by *read-eval*), and as such should be used only with - trusted sources." - [rdr] - {:pre [(instance? java.io.PushbackReader rdr)]} - (try + "Attempts to read a (ns ...) declaration from a reader, and returns + the unevaluated form. Returns the first top-level ns form found. + Returns nil if a ns declaration cannot be found. Note that read can + execute code (controlled by tools.reader/*read-eval*), and as such + should be used only with trusted sources. read-opts is passed + through to tools.reader/read, defaults to allow conditional reader + expressions with :clj" + ([rdr] + (read-ns-decl rdr {:read-cond :allow + :features #{:clj}})) + ([rdr read-opts] (loop [] - (let [form (force-errors (read-clj rdr))] - (if (ns-decl? form) - form - (recur)))) - (catch Exception e nil))) + (let [form (reader/read (assoc read-opts :eof ::eof) rdr)] + (cond + (ns-decl? form) form + (= ::eof form) nil + :else (recur)))))) ;;; Parsing dependencies @@ -91,12 +78,25 @@ (keyword? form) ; Some people write (:require ... :reload-all) nil :else - (throw (IllegalArgumentException. - (pr-str "Unparsable namespace form:" form))))) + (throw (ex-info "Unparsable namespace form" + {:reason ::unparsable-ns-form + :form form})))) + +(def ^:private ns-clause-head-names + "Set of symbol/keyword names which can appear as the head of a + clause in the ns form." + #{"use" "require" "use-macros" "require-macros"}) + +(def ^:private ns-clause-heads + "Set of all symbols and keywords which can appear at the head of a + dependency clause in the ns form." + (set (mapcat (fn [name] (list (keyword name) + (symbol name))) + ns-clause-head-names))) (defn- deps-from-ns-form [form] (when (and (sequential? form) ; should be list but sometimes is not - (contains? #{:use :require 'use 'require} (first form))) + (contains? ns-clause-heads (first form))) (mapcat #(deps-from-libspec nil %) (rest form)))) (defn deps-from-ns-decl diff --git a/src/main/clojure/clojure/tools/namespace/track.clj b/src/main/clojure/clojure/tools/namespace/track.cljc similarity index 100% rename from src/main/clojure/clojure/tools/namespace/track.clj rename to src/main/clojure/clojure/tools/namespace/track.cljc From 162decf44e2e9086dc4ee155f026f6bf32e8e53a Mon Sep 17 00:00:00 2001 From: Stuart Sierra Date: Sat, 25 Jul 2015 20:02:17 -0400 Subject: [PATCH 04/19] c.t.n.file: docstring fix: tools.reader Instead of clojure.core/read --- src/main/clojure/clojure/tools/namespace/file.clj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/clojure/clojure/tools/namespace/file.clj b/src/main/clojure/clojure/tools/namespace/file.clj index 6f092d0..3395318 100644 --- a/src/main/clojure/clojure/tools/namespace/file.clj +++ b/src/main/clojure/clojure/tools/namespace/file.clj @@ -18,7 +18,7 @@ "Attempts to read a (ns ...) declaration from file, and returns the unevaluated form. Returns nil if read fails due to invalid syntax or if a ns declaration cannot be found. read-opts is passed through to - clojure.core/read if this version of Clojure supports it." + tools.reader/read." ([file] (read-file-ns-decl file nil)) ([file read-opts] From 60f6209746c7770f2fa2c6023d5d176f08206d64 Mon Sep 17 00:00:00 2001 From: Stuart Sierra Date: Sat, 25 Jul 2015 20:02:42 -0400 Subject: [PATCH 05/19] c.t.n.file: make file-with-extension? private This is trivial to write and is specific to the implementation of `clojure-file?` and `clojurescript-file?` --- src/main/clojure/clojure/tools/namespace/file.clj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/clojure/clojure/tools/namespace/file.clj b/src/main/clojure/clojure/tools/namespace/file.clj index 3395318..22f5e95 100644 --- a/src/main/clojure/clojure/tools/namespace/file.clj +++ b/src/main/clojure/clojure/tools/namespace/file.clj @@ -25,7 +25,7 @@ (with-open [rdr (PushbackReader. (io/reader file))] (parse/read-ns-decl rdr read-opts)))) -(defn file-with-extension? +(defn- file-with-extension? "Returns true if the java.io.File represents a file whose name ends with one of the Strings in extensions." {:added "0.3.0"} From 33741916d9537d589aefebfcdce084ebe4fb5cb6 Mon Sep 17 00:00:00 2001 From: Stuart Sierra Date: Sat, 25 Jul 2015 20:03:39 -0400 Subject: [PATCH 06/19] c.t.n.parse: docstring clarify :features --- src/main/clojure/clojure/tools/namespace/parse.cljc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/clojure/clojure/tools/namespace/parse.cljc b/src/main/clojure/clojure/tools/namespace/parse.cljc index 846981b..b8e114c 100644 --- a/src/main/clojure/clojure/tools/namespace/parse.cljc +++ b/src/main/clojure/clojure/tools/namespace/parse.cljc @@ -31,7 +31,7 @@ execute code (controlled by tools.reader/*read-eval*), and as such should be used only with trusted sources. read-opts is passed through to tools.reader/read, defaults to allow conditional reader - expressions with :clj" + expressions with :features #{:clj}" ([rdr] (read-ns-decl rdr {:read-cond :allow :features #{:clj}})) From c5c5c0df928f2fdebd20cbb71928fd301d3bfd31 Mon Sep 17 00:00:00 2001 From: Stuart Sierra Date: Sat, 25 Jul 2015 20:03:53 -0400 Subject: [PATCH 07/19] c.t.n.parse: use `or` for default instead of arity Since a `nil` value for `read-opts` may be passed in by another function such as c.t.n.file/read-file-ns-decl. --- .../clojure/clojure/tools/namespace/parse.cljc | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/main/clojure/clojure/tools/namespace/parse.cljc b/src/main/clojure/clojure/tools/namespace/parse.cljc index b8e114c..0b1a442 100644 --- a/src/main/clojure/clojure/tools/namespace/parse.cljc +++ b/src/main/clojure/clojure/tools/namespace/parse.cljc @@ -33,15 +33,17 @@ through to tools.reader/read, defaults to allow conditional reader expressions with :features #{:clj}" ([rdr] - (read-ns-decl rdr {:read-cond :allow - :features #{:clj}})) + (read-ns-decl rdr nil)) ([rdr read-opts] - (loop [] - (let [form (reader/read (assoc read-opts :eof ::eof) rdr)] - (cond - (ns-decl? form) form - (= ::eof form) nil - :else (recur)))))) + (let [opts (assoc (or read-opts {:read-cond :allow + :features #{:clj}}) + :eof ::eof)] + (loop [] + (let [form (reader/read opts rdr)] + (cond + (ns-decl? form) form + (= ::eof form) nil + :else (recur))))))) ;;; Parsing dependencies From b188bc7e6f91f46564086a092c6f6ed1b21c4495 Mon Sep 17 00:00:00 2001 From: Stuart Sierra Date: Sat, 25 Jul 2015 20:15:51 -0400 Subject: [PATCH 08/19] Revert "c.t.n.file: make file-with-extension? private" This reverts commit 60f6209746c7770f2fa2c6023d5d176f08206d64. Need this to be public to use in c.t.n.find for different platforms. --- src/main/clojure/clojure/tools/namespace/file.clj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/clojure/clojure/tools/namespace/file.clj b/src/main/clojure/clojure/tools/namespace/file.clj index 22f5e95..3395318 100644 --- a/src/main/clojure/clojure/tools/namespace/file.clj +++ b/src/main/clojure/clojure/tools/namespace/file.clj @@ -25,7 +25,7 @@ (with-open [rdr (PushbackReader. (io/reader file))] (parse/read-ns-decl rdr read-opts)))) -(defn- file-with-extension? +(defn file-with-extension? "Returns true if the java.io.File represents a file whose name ends with one of the Strings in extensions." {:added "0.3.0"} From 19893e80b457554b8493e8e632267b672b89a8c8 Mon Sep 17 00:00:00 2001 From: Stuart Sierra Date: Sat, 25 Jul 2015 20:33:55 -0400 Subject: [PATCH 09/19] Fix POM: missing groupId for clojure --- pom.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/pom.xml b/pom.xml index 4be4a10..b912e4e 100644 --- a/pom.xml +++ b/pom.xml @@ -12,6 +12,7 @@ + org.clojure clojure 1.7.0 provided From 9bb35a5f2c655218aadd8a798f8dd1cccaa2d653 Mon Sep 17 00:00:00 2001 From: Stuart Sierra Date: Sat, 25 Jul 2015 20:35:29 -0400 Subject: [PATCH 10/19] c.t.n.parse: define reader-opts for each platform To be used in c.t.n.find --- src/main/clojure/clojure/tools/namespace/parse.cljc | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/main/clojure/clojure/tools/namespace/parse.cljc b/src/main/clojure/clojure/tools/namespace/parse.cljc index 0b1a442..86843d5 100644 --- a/src/main/clojure/clojure/tools/namespace/parse.cljc +++ b/src/main/clojure/clojure/tools/namespace/parse.cljc @@ -24,6 +24,14 @@ [form] (and (list? form) (= 'ns (first form)))) +(def clojure-read-opts + {:read-cond :allow + :features #{:clj}}) + +(def clojurescript-read-opts + {:read-cond :allow + :features #{:cljs}}) + (defn read-ns-decl "Attempts to read a (ns ...) declaration from a reader, and returns the unevaluated form. Returns the first top-level ns form found. @@ -35,8 +43,7 @@ ([rdr] (read-ns-decl rdr nil)) ([rdr read-opts] - (let [opts (assoc (or read-opts {:read-cond :allow - :features #{:clj}}) + (let [opts (assoc (or read-opts clojure-read-opts) :eof ::eof)] (loop [] (let [form (reader/read opts rdr)] From e928d78a9ca18a2191cf27539fafa4ceb81b182f Mon Sep 17 00:00:00 2001 From: Stuart Sierra Date: Sat, 25 Jul 2015 20:35:47 -0400 Subject: [PATCH 11/19] c.t.n.find: parameterize by platform (clj/cljs) --- .../clojure/clojure/tools/namespace/find.clj | 133 +++++++++++++----- 1 file changed, 97 insertions(+), 36 deletions(-) diff --git a/src/main/clojure/clojure/tools/namespace/find.clj b/src/main/clojure/clojure/tools/namespace/find.clj index 0ef73f2..d243a53 100644 --- a/src/main/clojure/clojure/tools/namespace/find.clj +++ b/src/main/clojure/clojure/tools/namespace/find.clj @@ -19,80 +19,141 @@ InputStreamReader) (java.util.jar JarFile JarEntry))) +(def clojure-platform + "Definition of file extensions and reader options for Clojure (.clj + and .cljc) source files." + {:read-opts parse/clojure-read-opts + :extensions file/clojure-extensions}) + +(def clojurescript-platform + "Definition of file extensions and reader options for ClojureScript + (.cljs and .cljc) source files." + {:read-opts parse/clojurescript-read-opts + :extensions file/clojurescript-extensions}) + ;;; Finding namespaces in a directory tree +(defn- sort-files-breadth-first + [files] + (sort-by #(.getAbsolutePath ^File %) files)) + +(defn find-sources-in-dir + "Searches recursively under dir for source files. Returns a sequence + of File objects, in breadth-first sort order." + ([dir] + (find-sources-in-dir dir nil)) + ([^File dir platform] + (let [{:keys [extensions]} (or platform clojure-platform)] + (->> (file-seq dir) + (filter #(file/file-with-extension? % extensions)) + sort-files-breadth-first)))) + (defn find-clojure-sources-in-dir - "Searches recursively under dir for Clojure source files (.clj, .cljc). + "DEPRECATED: replaced by find-sources-in-dir + + Searches recursively under dir for Clojure source files (.clj, .cljc). Returns a sequence of File objects, in breadth-first sort order." [^File dir] - ;; Use sort by absolute path to get breadth-first search. - (sort-by #(.getAbsolutePath ^File %) - (filter file/clojure-file? (file-seq dir)))) + (find-sources-in-dir dir clojure-platform)) (defn find-ns-decls-in-dir "Searches dir recursively for (ns ...) declarations in Clojure source files; returns the unevaluated ns declarations." - [^File dir] - (keep file/read-file-ns-decl (find-clojure-sources-in-dir dir))) + ([dir] (find-ns-decls-in-dir dir nil)) + ([dir options] + (keep #(file/read-file-ns-decl % options) + (find-clojure-sources-in-dir dir)))) (defn find-namespaces-in-dir "Searches dir recursively for (ns ...) declarations in Clojure source files; returns the symbol names of the declared namespaces." - [^File dir] - (map second (find-ns-decls-in-dir dir))) + ([dir] (find-namespaces-in-dir dir)) + ([dir options] + (map second (find-ns-decls-in-dir dir options)))) ;;; Finding namespaces in JAR files +(defn- ends-with-extension + [^String filename extensions] + (some #(.endsWith filename %) extensions)) + +(defn sources-in-jar + "Returns a sequence of source file names found in the JAR file. + Optional second argument is either clojure-platform or + clojurescript-platform, both defined in this namespace.. Controls + which file extensions are included." + ([jar-file] + (sources-in-jar jar-file nil)) + ([^JarFile jar-file platform] + (let [{:keys [extensions]} (or platform clojure-platform)] + (filter #(ends-with-extension % extensions) + (classpath/filenames-in-jar jar-file))))) + (defn clojure-sources-in-jar - "Returns a sequence of filenames ending in .clj or .cljc found in the JAR file." - [^JarFile jar-file] - (filter #(or (.endsWith ^String % ".clj") (.endsWith ^String % ".cljc")) - (classpath/filenames-in-jar jar-file))) + "DEPRECATED: replaced by sources-in-jar + + Returns a sequence of filenames ending in .clj or .cljc found in the + JAR file." + [jar-file] + (sources-in-jar jar-file clojure-platform)) (defn read-ns-decl-from-jarfile-entry "Attempts to read a (ns ...) declaration from the named entry in the JAR file, and returns the unevaluated form. Returns nil if the read fails, or if the first form is not a ns declaration." - [^JarFile jarfile ^String entry-name] - (with-open [rdr (PushbackReader. - (io/reader - (.getInputStream jarfile (.getEntry jarfile entry-name))))] - (parse/read-ns-decl rdr))) + ([jarfile entry-name] + (read-ns-decl-from-jarfile-entry jarfile entry-name nil)) + ([^JarFile jarfile ^String entry-name platform] + (let [{:keys [read-opts]} (or platform clojure-platform)] + (with-open [rdr (PushbackReader. + (io/reader + (.getInputStream jarfile (.getEntry jarfile entry-name))))] + (parse/read-ns-decl rdr read-opts))))) (defn find-ns-decls-in-jarfile - "Searches the JAR file for Clojure source files containing (ns ...) + "Searches the JAR file for platform source files containing (ns ...) declarations; returns the unevaluated ns declarations." - [^JarFile jarfile] - (filter identity - (map #(read-ns-decl-from-jarfile-entry jarfile %) - (clojure-sources-in-jar jarfile)))) + ([jarfile] + (find-ns-decls-in-jarfile jarfile nil)) + ([^JarFile jarfile platform] + (keep #(read-ns-decl-from-jarfile-entry jarfile % platform) + (sources-in-jar jarfile platform)))) (defn find-namespaces-in-jarfile - "Searches the JAR file for Clojure source files containing (ns ...) + "Searches the JAR file for platform source files containing (ns ...) declarations. Returns a sequence of the symbol names of the declared namespaces." - [^JarFile jarfile] - (map second (find-ns-decls-in-jarfile jarfile))) + ([jarfile] + (find-namespaces-in-jarfile jarfile nil)) + ([^JarFile jarfile platform] + (map second (find-ns-decls-in-jarfile jarfile platform)))) ;;; Finding namespaces (defn find-ns-decls "Searches a sequence of java.io.File objects (both directories and - JAR files) for .clj or .cljc source files containing (ns...) declarations. - Returns a sequence of the unevaluated ns declaration forms. Use with - clojure.java.classpath to search Clojure's classpath." - [files] - (concat - (mapcat find-ns-decls-in-dir (filter #(.isDirectory ^File %) files)) - (mapcat find-ns-decls-in-jarfile (filter classpath/jar-file? files)))) + JAR files) for platform source files containing (ns...) + declarations. Returns a sequence of the unevaluated ns declaration + forms. Use with clojure.java.classpath to search Clojure's + classpath." + ([files] + (find-ns-decls files nil)) + ([files platform] + (concat + (mapcat #(find-ns-decls-in-dir % platform) + (filter #(.isDirectory ^File %) files)) + (mapcat #(find-ns-decls-in-jarfile % platform) + (filter classpath/jar-file? files))))) (defn find-namespaces "Searches a sequence of java.io.File objects (both directories and - JAR files) for .clj or .cljc source files containing (ns...) declarations. - Returns a sequence of the symbol names of the declared + JAR files) for platform source files containing (ns...) + declarations. Returns a sequence of the symbol names of the declared namespaces. Use with clojure.java.classpath to search Clojure's classpath." - [files] - (map second (find-ns-decls files))) + ([files] + (find-namespaces files nil)) + ([files platform] + (map second (find-ns-decls files platform)))) From dca2e36705d67186d00cd117fd373e1a4a40a793 Mon Sep 17 00:00:00 2001 From: Stuart Sierra Date: Fri, 31 Jul 2015 11:03:28 -0400 Subject: [PATCH 12/19] c.t.n.find: shorter names for platforms; docs Rename 'clojure-platform' to 'clj' and 'clojurescript-platform' to 'cljs'. Add docs and metadata for versions added/deprecated. --- .../clojure/clojure/tools/namespace/find.clj | 93 +++++++++++++------ 1 file changed, 63 insertions(+), 30 deletions(-) diff --git a/src/main/clojure/clojure/tools/namespace/find.clj b/src/main/clojure/clojure/tools/namespace/find.clj index d243a53..b7f6449 100644 --- a/src/main/clojure/clojure/tools/namespace/find.clj +++ b/src/main/clojure/clojure/tools/namespace/find.clj @@ -19,15 +19,17 @@ InputStreamReader) (java.util.jar JarFile JarEntry))) -(def clojure-platform - "Definition of file extensions and reader options for Clojure (.clj - and .cljc) source files." +(def ^{:added "0.3.0"} + clj + "Platform definition of file extensions and reader options for + Clojure (.clj and .cljc) source files." {:read-opts parse/clojure-read-opts :extensions file/clojure-extensions}) -(def clojurescript-platform - "Definition of file extensions and reader options for ClojureScript - (.cljs and .cljc) source files." +(def ^{:added "0.3.0"} + cljs + "Platform definition of file extensions and reader options for + ClojureScript (.cljs and .cljc) source files." {:read-opts parse/clojurescript-read-opts :extensions file/clojurescript-extensions}) @@ -39,11 +41,15 @@ (defn find-sources-in-dir "Searches recursively under dir for source files. Returns a sequence - of File objects, in breadth-first sort order." + of File objects, in breadth-first sort order. + + Optional second argument is either clj (default) or cljs, both + defined in clojure.tools.namespace.find." + {:added "0.3.0"} ([dir] (find-sources-in-dir dir nil)) ([^File dir platform] - (let [{:keys [extensions]} (or platform clojure-platform)] + (let [{:keys [extensions]} (or platform clj)] (->> (file-seq dir) (filter #(file/file-with-extension? % extensions)) sort-files-breadth-first)))) @@ -53,23 +59,33 @@ Searches recursively under dir for Clojure source files (.clj, .cljc). Returns a sequence of File objects, in breadth-first sort order." + {:added "0.2.0" + :deprecated "0.3.0"} [^File dir] - (find-sources-in-dir dir clojure-platform)) + (find-sources-in-dir dir clj)) (defn find-ns-decls-in-dir "Searches dir recursively for (ns ...) declarations in Clojure - source files; returns the unevaluated ns declarations." + source files; returns the unevaluated ns declarations. + + Optional second argument platform is either clj (default) or cljs, + both defined in clojure.tools.namespace.find." + {:added "0.2.0"} ([dir] (find-ns-decls-in-dir dir nil)) - ([dir options] - (keep #(file/read-file-ns-decl % options) - (find-clojure-sources-in-dir dir)))) + ([dir platform] + (keep #(file/read-file-ns-decl % (:read-opts platform)) + (find-sources-in-dir dir platform)))) (defn find-namespaces-in-dir "Searches dir recursively for (ns ...) declarations in Clojure - source files; returns the symbol names of the declared namespaces." - ([dir] (find-namespaces-in-dir dir)) - ([dir options] - (map second (find-ns-decls-in-dir dir options)))) + source files; returns the symbol names of the declared namespaces. + + Optional second argument platform is either clj (default) or cljs, + both defined in clojure.tools.namespace.find." + {:added "0.3.0"} + ([dir] (find-namespaces-in-dir dir nil)) + ([dir platform] + (map second (find-ns-decls-in-dir dir platform)))) ;;; Finding namespaces in JAR files @@ -79,13 +95,14 @@ (defn sources-in-jar "Returns a sequence of source file names found in the JAR file. - Optional second argument is either clojure-platform or - clojurescript-platform, both defined in this namespace.. Controls - which file extensions are included." + + Optional second argument platform is either clj (default) or cljs, + both defined in clojure.tools.namespace.find." + {:added "0.3.0"} ([jar-file] (sources-in-jar jar-file nil)) ([^JarFile jar-file platform] - (let [{:keys [extensions]} (or platform clojure-platform)] + (let [{:keys [extensions]} (or platform clj)] (filter #(ends-with-extension % extensions) (classpath/filenames-in-jar jar-file))))) @@ -94,25 +111,32 @@ Returns a sequence of filenames ending in .clj or .cljc found in the JAR file." + {:added "0.2.0" + :deprecated "0.3.0"} [jar-file] - (sources-in-jar jar-file clojure-platform)) + (sources-in-jar jar-file clj)) (defn read-ns-decl-from-jarfile-entry "Attempts to read a (ns ...) declaration from the named entry in the - JAR file, and returns the unevaluated form. Returns nil if the read - fails, or if the first form is not a ns declaration." + JAR file, and returns the unevaluated form. + + Optional third argument platform is either clj (default) or cljs, + both defined in clojure.tools.namespace.find." ([jarfile entry-name] (read-ns-decl-from-jarfile-entry jarfile entry-name nil)) ([^JarFile jarfile ^String entry-name platform] - (let [{:keys [read-opts]} (or platform clojure-platform)] + (let [{:keys [read-opts]} (or platform clj)] (with-open [rdr (PushbackReader. (io/reader (.getInputStream jarfile (.getEntry jarfile entry-name))))] (parse/read-ns-decl rdr read-opts))))) (defn find-ns-decls-in-jarfile - "Searches the JAR file for platform source files containing (ns ...) - declarations; returns the unevaluated ns declarations." + "Searches the JAR file for source files containing (ns ...) + declarations; returns the unevaluated ns declarations. + + Optional second argument platform is either clj (default) or cljs, + both defined in clojure.tools.namespace.find." ([jarfile] (find-ns-decls-in-jarfile jarfile nil)) ([^JarFile jarfile platform] @@ -122,7 +146,10 @@ (defn find-namespaces-in-jarfile "Searches the JAR file for platform source files containing (ns ...) declarations. Returns a sequence of the symbol names of the - declared namespaces." + declared namespaces. + + Optional second argument platform is either clj (default) or cljs, + both defined in clojure.tools.namespace.find." ([jarfile] (find-namespaces-in-jarfile jarfile nil)) ([^JarFile jarfile platform] @@ -136,7 +163,10 @@ JAR files) for platform source files containing (ns...) declarations. Returns a sequence of the unevaluated ns declaration forms. Use with clojure.java.classpath to search Clojure's - classpath." + classpath. + + Optional second argument platform is either clj (default) or cljs, + both defined in clojure.tools.namespace.find." ([files] (find-ns-decls files nil)) ([files platform] @@ -151,7 +181,10 @@ JAR files) for platform source files containing (ns...) declarations. Returns a sequence of the symbol names of the declared namespaces. Use with clojure.java.classpath to search Clojure's - classpath." + classpath. + + Optional second argument platform is either clj (default) or cljs, + both defined in clojure.tools.namespace.find." ([files] (find-namespaces files nil)) ([files platform] From 2d1bf0254161b5da340c5524f91f945db3c10e8a Mon Sep 17 00:00:00 2001 From: Stuart Sierra Date: Fri, 31 Jul 2015 11:39:44 -0400 Subject: [PATCH 13/19] c.t.n.file: pass read-opts through from add-files --- .../clojure/clojure/tools/namespace/file.clj | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/src/main/clojure/clojure/tools/namespace/file.clj b/src/main/clojure/clojure/tools/namespace/file.clj index 3395318..da76e97 100644 --- a/src/main/clojure/clojure/tools/namespace/file.clj +++ b/src/main/clojure/clojure/tools/namespace/file.clj @@ -59,9 +59,9 @@ ;;; Dependency tracker -(defn- files-and-deps [files] +(defn- files-and-deps [files read-opts] (reduce (fn [m file] - (if-let [decl (read-file-ns-decl file)] + (if-let [decl (read-file-ns-decl file read-opts)] (let [deps (parse/deps-from-ns-decl decl) name (second decl)] (-> m @@ -74,12 +74,15 @@ (defn add-files "Reads ns declarations from files; returns an updated dependency - tracker with those files added." - [tracker files] - (let [{:keys [depmap filemap]} (files-and-deps files)] - (-> tracker - (track/add depmap) - (update-in [::filemap] merge-map filemap)))) + tracker with those files added. read-opts is passed through to + tools.reader." + ([tracker files] + (add-files tracker files nil)) + ([tracker files read-opts] + (let [{:keys [depmap filemap]} (files-and-deps files read-opts)] + (-> tracker + (track/add depmap) + (update-in [::filemap] merge-map filemap))))) (defn remove-files "Returns an updated dependency tracker with files removed. The files From 504e796f6b0ad40d8ad52399a1a6574dd75769ec Mon Sep 17 00:00:00 2001 From: Stuart Sierra Date: Fri, 31 Jul 2015 11:49:33 -0400 Subject: [PATCH 14/19] c.t.n.dir: add scan-dirs/scan-files with platform Deprecate 'scan' and 'scan-all', replace with 'scan-dirs' and 'scan-files' taking optional argument for clj/cljs platform. --- .../clojure/clojure/tools/namespace/dir.clj | 89 ++++++++++++++----- 1 file changed, 68 insertions(+), 21 deletions(-) diff --git a/src/main/clojure/clojure/tools/namespace/dir.clj b/src/main/clojure/clojure/tools/namespace/dir.clj index 87dd61d..e12288d 100644 --- a/src/main/clojure/clojure/tools/namespace/dir.clj +++ b/src/main/clojure/clojure/tools/namespace/dir.clj @@ -11,6 +11,7 @@ file-modification timestamps"} clojure.tools.namespace.dir (:require [clojure.tools.namespace.file :as file] + [clojure.tools.namespace.find :as find] [clojure.tools.namespace.track :as track] [clojure.java.classpath :refer [classpath-directories]] [clojure.java.io :as io] @@ -18,13 +19,11 @@ [clojure.string :as string]) (:import (java.io File) (java.util.regex Pattern))) -(defn- find-files [dirs] +(defn- find-files [dirs platform] (->> dirs (map io/file) (filter #(.exists ^File %)) - (mapcat file-seq) - (filter file/clojure-file?) - (map #(.getCanonicalFile ^File %)))) + (mapcat #(find/find-sources-in-dir % platform)))) (defn- modified-files [tracker files] (filter #(< (::time tracker 0) (.lastModified ^File %)) files)) @@ -32,36 +31,84 @@ (defn- deleted-files [tracker files] (set/difference (::files tracker #{}) (set files))) -(defn- update-files [tracker deleted modified] +(defn- update-files [tracker deleted modified {:keys [read-opts]}] (let [now (System/currentTimeMillis)] (-> tracker (update-in [::files] #(if % (apply disj % deleted) #{})) (file/remove-files deleted) (update-in [::files] into modified) - (file/add-files modified) + (file/add-files modified read-opts) (assoc ::time now)))) -(defn scan - "Scans directories for files which have changed since the last time - 'scan' was run; update the dependency tracker with +(defn scan-files + "Scans files to find those which have changed since the last time + 'scan-files' was run; updates the dependency tracker with new/changed/deleted files. + files is the collection of files to scan. + + Optional third argument is map of options: + + :platform Either clj (default) or cljs, both defined in + clojure.tools.namespace.find, controls reader options for + parsing files. + + :add-all? If true, assumes all extant files are modified regardless + of filesystem timestamps." + {:added "0.3.0"} + ([tracker files] (scan-files tracker files nil)) + ([tracker files {:keys [platform add-all?]}] + (let [deleted (seq (deleted-files tracker files)) + modified (if add-all? + files + (seq (modified-files tracker files)))] + (if (or deleted modified) + (update-files tracker deleted modified platform) + tracker)))) + +(defn scan-dirs + "Scans directories for files which have changed since the last time + 'scan-dirs' or 'scan-files' was run; updates the dependency tracker + with new/changed/deleted files. + + dirs is the collection of directories to scan, defaults to all + directories on Clojure's classpath. + + Optional third argument is map of options: + + :platform Either clj (default) or cljs, both defined in + clojure.tools.namespace.find, controls file extensions + and reader options. + + :add-all? If true, assumes all extant files are modified regardless + of filesystem timestamps." + {:added "0.3.0"} + ([tracker] (scan-dirs tracker nil nil)) + ([tracker dirs] (scan-dirs tracker dirs nil)) + ([tracker dirs {:keys [platform add-all?] :as options}] + (let [ds (or (seq dirs) (classpath-directories))] + (scan-files tracker (find-files ds platform) options)))) + +(defn scan + "DEPRECATED: replaced by scan-dirs. + + Scans directories for Clojure (.clj, .cljc) source files which have + changed since the last time 'scan' was run; update the dependency + tracker with new/changed/deleted files. + If no dirs given, defaults to all directories on the classpath." + {:added "0.2.0" + :deprecated "0.3.0"} [tracker & dirs] - (let [ds (or (seq dirs) (classpath-directories)) - files (find-files ds) - deleted (seq (deleted-files tracker files)) - modified (seq (modified-files tracker files))] - (if (or deleted modified) - (update-files tracker deleted modified) - tracker))) + (scan-dirs tracker dirs {:platform find/clj})) (defn scan-all - "Scans directories for all Clojure source files and updates the + "DEPRECATED: replaced by scan-dirs. + + Scans directories for all Clojure source files and updates the dependency tracker to reload files. If no dirs given, defaults to all directories on the classpath." + {:added "0.2.0" + :deprecated "0.3.0"} [tracker & dirs] - (let [ds (or (seq dirs) (classpath-directories)) - files (find-files ds) - deleted (seq (deleted-files tracker files))] - (update-files tracker deleted files))) + (scan-dirs tracker dirs {:platform find/clj :add-all? true})) From a5dcd6b6434c8b8c88ef8f3841eeb2c7d7659fc4 Mon Sep 17 00:00:00 2001 From: Stuart Sierra Date: Fri, 31 Jul 2015 11:50:32 -0400 Subject: [PATCH 15/19] c.t.n.repl: use dir/scan-dirs Replaces deprecated dir/scan and dir/scan-all. --- src/main/clojure/clojure/tools/namespace/repl.clj | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/main/clojure/clojure/tools/namespace/repl.clj b/src/main/clojure/clojure/tools/namespace/repl.clj index 5c3dc7b..663eb0d 100644 --- a/src/main/clojure/clojure/tools/namespace/repl.clj +++ b/src/main/clojure/clojure/tools/namespace/repl.clj @@ -79,7 +79,7 @@ (when (find-ns ns-name) (alias alias-sym ns-name)))) -(defn- do-refresh [scan-fn after-sym] +(defn- do-refresh [scan-opts after-sym] (when after-sym (assert (symbol? after-sym) ":after value must be a symbol") (assert (namespace after-sym) @@ -87,8 +87,7 @@ (let [current-ns-name (ns-name *ns*) current-ns-refers (referred *ns*) current-ns-aliases (aliased *ns*)] - (alter-var-root #'refresh-tracker - #(apply scan-fn % refresh-dirs)) + (alter-var-root #'refresh-tracker dir/scan-dirs refresh-dirs scan-opts) (alter-var-root #'refresh-tracker remove-disabled) (print-pending-reloads refresh-tracker) (alter-var-root #'refresh-tracker reload/track-reload) @@ -142,7 +141,7 @@ been reloaded." [& options] (let [{:keys [after]} options] - (do-refresh dir/scan after))) + (do-refresh {:platform find/clj} after))) (defn refresh-all "Scans source code directories for all Clojure source files and @@ -159,7 +158,7 @@ been reloaded." [& options] (let [{:keys [after]} options] - (do-refresh dir/scan-all after))) + (do-refresh {:platform find/clj :add-all? true} after))) (defn set-refresh-dirs "Sets the directories which are scanned by 'refresh'. Supports the From 5b4700cff7db3e862c1a6e78d73edd9c01495afd Mon Sep 17 00:00:00 2001 From: Stuart Sierra Date: Fri, 31 Jul 2015 11:51:18 -0400 Subject: [PATCH 16/19] c.t.n.repl: make tracker and dirs Vars public No reason for these not to be public, and it may be useful for inspection from the REPL. --- src/main/clojure/clojure/tools/namespace/repl.clj | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/clojure/clojure/tools/namespace/repl.clj b/src/main/clojure/clojure/tools/namespace/repl.clj index 663eb0d..d75a805 100644 --- a/src/main/clojure/clojure/tools/namespace/repl.clj +++ b/src/main/clojure/clojure/tools/namespace/repl.clj @@ -11,11 +11,12 @@ clojure.tools.namespace.repl (:require [clojure.tools.namespace.track :as track] [clojure.tools.namespace.dir :as dir] + [clojure.tools.namespace.find :as find] [clojure.tools.namespace.reload :as reload])) -(defonce ^:private refresh-tracker (track/tracker)) +(defonce refresh-tracker (track/tracker)) -(defonce ^:private refresh-dirs []) +(defonce refresh-dirs []) (defn- print-and-return [tracker] (if-let [e (::reload/error tracker)] From 7165b958d0d8bc2c3221f677645d568c41044593 Mon Sep 17 00:00:00 2001 From: Stuart Sierra Date: Fri, 31 Jul 2015 12:16:55 -0400 Subject: [PATCH 17/19] Move change log into separate file CHANGES.md And add change log entries for 0.3.0 --- CHANGES.md | 194 +++++++++++++++++++++++++++++++++++++++++++++++++++++ README.md | 159 ------------------------------------------- 2 files changed, 194 insertions(+), 159 deletions(-) create mode 100644 CHANGES.md diff --git a/CHANGES.md b/CHANGES.md new file mode 100644 index 0000000..7dec2d3 --- /dev/null +++ b/CHANGES.md @@ -0,0 +1,194 @@ +# Change Log for tools.namespace + + +## 0.3.x series + +### Version 0.3.0 + + * **ClojureScript Analysis Support** [TNS-35] + + * Platform-neutral namespaces were converted to conditional-read + (`.cljc`) files: c.t.n.dependency, c.t.n.track, and + c.t.n.parse. These namespaces can be used in ClojureScript + programs. + + * Added support for finding, parsing, and analyzing + ClojureScript source files (`.cljs` and `.cljc`) in + c.t.n.file, c.t.n.parse, c.t.n.dir, and c.t.n.find with + optional "platform" arguments. These namespaces still only + **run** on the Clojure(JVM) platform. + + * Reloading and interactive features remain Clojure(JVM) only + for now: c.t.n.move, c.t.n.reload, and c.t.n.repl + + * Uses [tools.reader] for platform-independent parsing and + conditional-reader support. + + * Enhancement [TNS-36]: Use java.classpath for better JVM classpath + resolution + + * Minimum Clojure version is 1.7.0 + + * Some definitions deprecated; see source code or Var metadata for + details. + + + +## 0.2.x series + +### Version 0.2.11 on 19-Jun-2015 + + * [TNS-34] Allow reader conditionals in parsed source files + +### Version 0.2.10 on 26-Feb-2015 + + * Widen existing functions to handle both clj and cljc files in + advance of reader conditional support in Clojure 1.7. + +### Version 0.2.9 on 31-Jan-2015 + + * Fix [TNS-20]: Undefined 'unload' order after namespaces are first + added to an new, empty tracker. + + * Improvement [TNS-21]: Support `ns` clauses which use vectors + instead of lists for clauses, contrary to docs. + + * Improvement [TNS-32]: Support `ns` clauses which use symbols as + clause heads instead of keywords, contrary to docs. + +### Version 0.2.8 on 19-Dec-2014 + + * Improvement [TNS-31]: Specific error message when `:after` symbol + passed to `refresh` cannot be resolved. + + * Fix [TNS-26]: namespace alias recovery after failed reload did not + work due to local binding shadowing global Var + +### Version 0.2.7 on 19-Sept-2014 + + * [Revert bad commit](https://github.com/clojure/tools.namespace/commit/27194f2edfe3f5f9e1343f993beca4b43f0bafe8) + mistakenly included in 0.2.6 which could cause the tracker's + 'unload' order to be incorrect. See discussion at [TNS-20]. + +### **BROKEN** Version 0.2.6 on 7-Sept-2014 **DO NOT USE** + + * `clojure.tools.namespace.parse/read-ns-decl` asserts that its + argument is a PushbackReader, instead of silently returning nil + + * Fix [TNS-22]: broken `clojure.string/replace` with Windows path + separator + +### Version 0.2.5 on 15-Jul-2014 + + * New `clojure.tools.namespace.repl/clear` empties the state of the + REPL dependency tracker. This can help repair the dependency + tracker after a failed load or a circular dependency error. + + * Enhancement [TNS-19]: `deps-from-ns-decl` should return an empty + set instead of nil. This may be a breaking change for some but + is consistent with the original docstring. + + * Enhancement [TNS-18]: Compute transitive dependencies in linear time. + + * Enhancement [TNS-17]: The `ns` form doesn't need to be the first + top-level form in a file. + + * Fix [TNS-16]: Don't depend on specific hash ordering in tests. + Exposed by new hash functions in Clojure 1.6.0. + + * Fix [TNS-15]: Handle spaces in classpath directories (old + `clojure.tools.namespace`) + + * Fix [TNS-12]: Duplicate definition of `jar-file?` + +### Version 0.2.4 on 19-Jul-2013 + + * Fix [TNS-10]: Forbid circular dependency when a namespace depends + on itself + + * Fix [TNS-9] and [TNS-11]: support other prefix-list forms + + * Fix [TNS-8]: In `move-ns`, do not modify files whose contents does + not change + +### Version 0.2.3 on 01-Apr-2013 + + * New: Attempt recovery of aliases/refers in REPL after error + +### Version 0.2.2 on 14-Dec-2012 + + * New: Add `:after` option to `refresh` + + * New: Add `clojure.tools.namespace.move` + + * Fix [TNS-4], reflection warnings + +### Version 0.2.1 on 26-Oct-2012 + + * Fix: Restore deprecated 0.1.x APIs in `clojure.tools.namespace` + + * Fix [TNS-3], actually use `refresh-dirs` + +### **BROKEN** Version 0.2.0 on 05-Oct-2012 **DO NOT USE** + + * Not recommended for use: this release introduced breaking API + changes (renaming core namespaces and functions) without + backwards-compatibility. Applications with dependencies on both + the 0.2.x and 0.1.x APIs cannot use this version. + + * New dependency tracking & reloading features + + * Eliminate dependency on [java.classpath] + + + +## 0.1.x series + +### Version 0.1.3 on 24-Apr-2012 + + * Fix [TNS-1] Workaround for Clojure 1.2 reader bug + +### Version 0.1.2 on 10-Feb-2012 + + * Fix: Eliminate reflection warnings + +### Version 0.1.1 on 18-May-2011 + +### Version 0.1.0 on 24-Apr-2011 + + * Source-compatible with clojure.contrib.find-namespaces in old + clojure-contrib 1.2.0 + +[TNS-1]: http://dev.clojure.org/jira/browse/TNS-1 +[TNS-3]: http://dev.clojure.org/jira/browse/TNS-3 +[TNS-4]: http://dev.clojure.org/jira/browse/TNS-4 +[TNS-8]: http://dev.clojure.org/jira/browse/TNS-8 +[TNS-9]: http://dev.clojure.org/jira/browse/TNS-9 +[TNS-10]: http://dev.clojure.org/jira/browse/TNS-10 +[TNS-11]: http://dev.clojure.org/jira/browse/TNS-11 +[TNS-12]: http://dev.clojure.org/jira/browse/TNS-12 +[TNS-15]: http://dev.clojure.org/jira/browse/TNS-15 +[TNS-16]: http://dev.clojure.org/jira/browse/TNS-16 +[TNS-17]: http://dev.clojure.org/jira/browse/TNS-17 +[TNS-18]: http://dev.clojure.org/jira/browse/TNS-18 +[TNS-19]: http://dev.clojure.org/jira/browse/TNS-19 +[TNS-20]: http://dev.clojure.org/jira/browse/TNS-20 +[TNS-21]: http://dev.clojure.org/jira/browse/TNS-21 +[TNS-22]: http://dev.clojure.org/jira/browse/TNS-22 +[TNS-23]: http://dev.clojure.org/jira/browse/TNS-23 +[TNS-24]: http://dev.clojure.org/jira/browse/TNS-24 +[TNS-25]: http://dev.clojure.org/jira/browse/TNS-25 +[TNS-26]: http://dev.clojure.org/jira/browse/TNS-26 +[TNS-27]: http://dev.clojure.org/jira/browse/TNS-27 +[TNS-28]: http://dev.clojure.org/jira/browse/TNS-28 +[TNS-29]: http://dev.clojure.org/jira/browse/TNS-29 +[TNS-30]: http://dev.clojure.org/jira/browse/TNS-30 +[TNS-31]: http://dev.clojure.org/jira/browse/TNS-31 +[TNS-32]: http://dev.clojure.org/jira/browse/TNS-32 +[TNS-33]: http://dev.clojure.org/jira/browse/TNS-33 +[TNS-34]: http://dev.clojure.org/jira/browse/TNS-34 +[TNS-35]: http://dev.clojure.org/jira/browse/TNS-35 +[TNS-36]: http://dev.clojure.org/jira/browse/TNS-36 +[java.classpath]: https://github.com/clojure/java.classpath +[tools.reader]: https://github.com/clojure/tools.reader +[JEP 122]: http://openjdk.java.net/jeps/122 diff --git a/README.md b/README.md index cc7761c..43e1479 100644 --- a/README.md +++ b/README.md @@ -533,165 +533,6 @@ Developer Information -Change Log ----------------------------------------- - -### Version 0.2.12-SNAPSHOT - - * In development, current Git master branch - -### Version 0.2.11 on 19-Jun-2015 - - * [TNS-34] Allow reader conditionals in parsed source files - -### Version 0.2.10 on 26-Feb-2015 - - * Widen existing functions to handle both clj and cljc files in - advance of reader conditional support in Clojure 1.7. - -### Version 0.2.9 on 31-Jan-2015 - - * Fix [TNS-20]: Undefined 'unload' order after namespaces are first - added to an new, empty tracker. - - * Improvement [TNS-21]: Support `ns` clauses which use vectors - instead of lists for clauses, contrary to docs. - - * Improvement [TNS-32]: Support `ns` clauses which use symbols as - clause heads instead of keywords, contrary to docs. - -### Version 0.2.8 on 19-Dec-2014 - - * Improvement [TNS-31]: Specific error message when `:after` symbol - passed to `refresh` cannot be resolved. - - * Fix [TNS-26]: namespace alias recovery after failed reload did not - work due to local binding shadowing global Var - -### Version 0.2.7 on 19-Sept-2014 - - * [Revert bad commit](https://github.com/clojure/tools.namespace/commit/27194f2edfe3f5f9e1343f993beca4b43f0bafe8) - mistakenly included in 0.2.6 which could cause the tracker's - 'unload' order to be incorrect. See discussion at [TNS-20]. - -### **BROKEN** Version 0.2.6 on 7-Sept-2014 **DO NOT USE** - - * `clojure.tools.namespace.parse/read-ns-decl` asserts that its - argument is a PushbackReader, instead of silently returning nil - - * Fix [TNS-22]: broken `clojure.string/replace` with Windows path - separator - -### Version 0.2.5 on 15-Jul-2014 - - * New `clojure.tools.namespace.repl/clear` empties the state of the - REPL dependency tracker. This can help repair the dependency - tracker after a failed load or a circular dependency error. - - * Enhancement [TNS-19]: `deps-from-ns-decl` should return an empty - set instead of nil. This may be a breaking change for some but - is consistent with the original docstring. - - * Enhancement [TNS-18]: Compute transitive dependencies in linear time. - - * Enhancement [TNS-17]: The `ns` form doesn't need to be the first - top-level form in a file. - - * Fix [TNS-16]: Don't depend on specific hash ordering in tests. - Exposed by new hash functions in Clojure 1.6.0. - - * Fix [TNS-15]: Handle spaces in classpath directories (old - `clojure.tools.namespace`) - - * Fix [TNS-12]: Duplicate definition of `jar-file?` - -### Version 0.2.4 on 19-Jul-2013 - - * Fix [TNS-10]: Forbid circular dependency when a namespace depends - on itself - - * Fix [TNS-9] and [TNS-11]: support other prefix-list forms - - * Fix [TNS-8]: In `move-ns`, do not modify files whose contents does - not change - -### Version 0.2.3 on 01-Apr-2013 - - * New: Attempt recovery of aliases/refers in REPL after error - -### Version 0.2.2 on 14-Dec-2012 - - * New: Add `:after` option to `refresh` - - * New: Add `clojure.tools.namespace.move` - - * Fix [TNS-4], reflection warnings - -### Version 0.2.1 on 26-Oct-2012 - - * Fix: Restore deprecated 0.1.x APIs in `clojure.tools.namespace` - - * Fix [TNS-3], actually use `refresh-dirs` - -### Version 0.2.0 on 05-Oct-2012 - - * **Not recommended for use**: this release introduced breaking API - changes (renaming core namespaces and functions) without - backwards-compatibility. Applications with dependencies on both - the 0.2.x and 0.1.x APIs cannot use this version. - - * New dependency tracking & reloading features - - * Eliminate dependency on [java.classpath] - -### Version 0.1.3 on 24-Apr-2012 - - * Fix [TNS-1] Workaround for Clojure 1.2 reader bug - -### Version 0.1.2 on 10-Feb-2012 - - * Fix: Eliminate reflection warnings - -### Version 0.1.1 on 18-May-2011 - -### Version 0.1.0 on 24-Apr-2011 - - * Source-compatible with clojure.contrib.find-namespaces in old - clojure-contrib 1.2.0 - -[TNS-1]: http://dev.clojure.org/jira/browse/TNS-1 -[TNS-3]: http://dev.clojure.org/jira/browse/TNS-3 -[TNS-4]: http://dev.clojure.org/jira/browse/TNS-4 -[TNS-8]: http://dev.clojure.org/jira/browse/TNS-8 -[TNS-9]: http://dev.clojure.org/jira/browse/TNS-9 -[TNS-10]: http://dev.clojure.org/jira/browse/TNS-10 -[TNS-11]: http://dev.clojure.org/jira/browse/TNS-11 -[TNS-12]: http://dev.clojure.org/jira/browse/TNS-12 -[TNS-15]: http://dev.clojure.org/jira/browse/TNS-15 -[TNS-16]: http://dev.clojure.org/jira/browse/TNS-16 -[TNS-17]: http://dev.clojure.org/jira/browse/TNS-17 -[TNS-18]: http://dev.clojure.org/jira/browse/TNS-18 -[TNS-19]: http://dev.clojure.org/jira/browse/TNS-19 -[TNS-20]: http://dev.clojure.org/jira/browse/TNS-20 -[TNS-21]: http://dev.clojure.org/jira/browse/TNS-21 -[TNS-22]: http://dev.clojure.org/jira/browse/TNS-22 -[TNS-23]: http://dev.clojure.org/jira/browse/TNS-23 -[TNS-24]: http://dev.clojure.org/jira/browse/TNS-24 -[TNS-25]: http://dev.clojure.org/jira/browse/TNS-25 -[TNS-26]: http://dev.clojure.org/jira/browse/TNS-26 -[TNS-27]: http://dev.clojure.org/jira/browse/TNS-27 -[TNS-28]: http://dev.clojure.org/jira/browse/TNS-28 -[TNS-29]: http://dev.clojure.org/jira/browse/TNS-29 -[TNS-30]: http://dev.clojure.org/jira/browse/TNS-30 -[TNS-31]: http://dev.clojure.org/jira/browse/TNS-31 -[TNS-32]: http://dev.clojure.org/jira/browse/TNS-32 -[TNS-33]: http://dev.clojure.org/jira/browse/TNS-33 -[TNS-34]: http://dev.clojure.org/jira/browse/TNS-34 -[java.classpath]: https://github.com/clojure/java.classpath -[JEP 122]: http://openjdk.java.net/jeps/122 - - - Copyright and License ---------------------------------------- From 8940605fd6714eb290e4a3a2f7513bca9590a1c7 Mon Sep 17 00:00:00 2001 From: Stuart Sierra Date: Fri, 31 Jul 2015 14:32:38 -0400 Subject: [PATCH 18/19] Rename clojure-read-opts to clj-read-opts And clojurescript-read-opts to cljs-read-opts --- src/main/clojure/clojure/tools/namespace/find.clj | 5 ++--- src/main/clojure/clojure/tools/namespace/parse.cljc | 6 +++--- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/main/clojure/clojure/tools/namespace/find.clj b/src/main/clojure/clojure/tools/namespace/find.clj index b7f6449..8b3f222 100644 --- a/src/main/clojure/clojure/tools/namespace/find.clj +++ b/src/main/clojure/clojure/tools/namespace/find.clj @@ -23,14 +23,14 @@ clj "Platform definition of file extensions and reader options for Clojure (.clj and .cljc) source files." - {:read-opts parse/clojure-read-opts + {:read-opts parse/clj-read-opts :extensions file/clojure-extensions}) (def ^{:added "0.3.0"} cljs "Platform definition of file extensions and reader options for ClojureScript (.cljs and .cljc) source files." - {:read-opts parse/clojurescript-read-opts + {:read-opts parse/cljs-read-opts :extensions file/clojurescript-extensions}) ;;; Finding namespaces in a directory tree @@ -189,4 +189,3 @@ (find-namespaces files nil)) ([files platform] (map second (find-ns-decls files platform)))) - diff --git a/src/main/clojure/clojure/tools/namespace/parse.cljc b/src/main/clojure/clojure/tools/namespace/parse.cljc index 86843d5..cba124e 100644 --- a/src/main/clojure/clojure/tools/namespace/parse.cljc +++ b/src/main/clojure/clojure/tools/namespace/parse.cljc @@ -24,11 +24,11 @@ [form] (and (list? form) (= 'ns (first form)))) -(def clojure-read-opts +(def clj-read-opts {:read-cond :allow :features #{:clj}}) -(def clojurescript-read-opts +(def cljs-read-opts {:read-cond :allow :features #{:cljs}}) @@ -43,7 +43,7 @@ ([rdr] (read-ns-decl rdr nil)) ([rdr read-opts] - (let [opts (assoc (or read-opts clojure-read-opts) + (let [opts (assoc (or read-opts clj-read-opts) :eof ::eof)] (loop [] (let [form (reader/read opts rdr)] From f94a3f7b10916ea6ee561c52a77ebce02de80c74 Mon Sep 17 00:00:00 2001 From: Stuart Sierra Date: Fri, 31 Jul 2015 14:36:01 -0400 Subject: [PATCH 19/19] c.t.n.find: add missing JarFile constructor --- src/main/clojure/clojure/tools/namespace/find.clj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/clojure/clojure/tools/namespace/find.clj b/src/main/clojure/clojure/tools/namespace/find.clj index 8b3f222..9ced9e5 100644 --- a/src/main/clojure/clojure/tools/namespace/find.clj +++ b/src/main/clojure/clojure/tools/namespace/find.clj @@ -174,7 +174,7 @@ (mapcat #(find-ns-decls-in-dir % platform) (filter #(.isDirectory ^File %) files)) (mapcat #(find-ns-decls-in-jarfile % platform) - (filter classpath/jar-file? files))))) + (map #(JarFile. %) (filter classpath/jar-file? files)))))) (defn find-namespaces "Searches a sequence of java.io.File objects (both directories and pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy