|
3 | 3 | (:require [leiningen.core.project :as lp] |
4 | 4 | [leiningen.repl :as repl] |
5 | 5 | [clojure.string :as string] |
6 | | - [fs.core :as fs]) |
7 | | - (:use [leiningen.core.eval :only [eval-in-project]])) |
| 6 | + [fs.core :as fs])) |
8 | 7 |
|
9 | 8 | (defn parse-version [ver] |
10 | | - (when ver |
11 | | - (let [[major minor patch] (string/split ver #"\.") |
12 | | - [patch extra] (string/split patch #"-")] |
13 | | - {:major (Integer. major) |
14 | | - :minor (Integer. minor) |
15 | | - :patch (Integer. patch)}))) |
| 9 | + (assert (and ver (re-find #"^\d+\.\d+\.\d+" ver)) |
| 10 | + (str "Invalid version number: " (pr-str ver) ". Must be in format X.X.X")) |
| 11 | + (let [[major minor patch] (string/split ver #"\.") |
| 12 | + [patch extra] (string/split patch #"-")] |
| 13 | + {:major (Integer. major) |
| 14 | + :minor (Integer. minor) |
| 15 | + :patch (Integer. patch)})) |
16 | 16 |
|
17 | | -(defn valid-clojure? [ver] |
| 17 | +(defn at-least-version? [ver min-version] |
| 18 | + (let [{:keys [major minor patch]} (parse-version ver)] |
| 19 | + (or (> major (:major min-version)) |
| 20 | + (and (= major (:major min-version)) (> minor (:minor min-version))) |
| 21 | + (and (= major (:major min-version)) (= minor (:minor min-version)) (>= patch (:patch min-version)))))) |
| 22 | + |
| 23 | +(defn maintained-clojure-version? |
| 24 | + "Determine if Clojure version is supported for latest middleware. |
| 25 | + Return true for nil since there is no version and thus we are providing one" |
| 26 | + [ver] |
18 | 27 | (if-not ver |
19 | 28 | true |
20 | | - (let [{:keys [major minor patch]} (parse-version ver)] |
21 | | - ;;do this by negation. It's an invalid version if any of the |
22 | | - ;;following are true |
23 | | - (not |
24 | | - (or (< major 1) |
25 | | - (and (= major 1) (< minor 5)) |
26 | | - (and (= major 1) (= minor 5) (< patch 1))))))) |
27 | | - |
28 | | -(defn proj->name [proj] |
29 | | - (str (:name proj) " " (:version proj))) |
| 29 | + ;; 1.7.0 candidates conflict with 1.7.0 |
| 30 | + (and (not (.startsWith ver "1.7.0-")) |
| 31 | + (at-least-version? ver {:major 1 :minor 7 :patch 0})))) |
30 | 32 |
|
31 | | -(defn prep [project name] |
| 33 | +(defn prep |
| 34 | + "Build a project map for the repl with LT middleware injected" |
| 35 | + [project name clj-version] |
32 | 36 | (let [init `(swap! lighttable.nrepl.core/my-settings merge {:name ~(or name (str (:name project) " " (:version project))) :project (quote ~project)}) |
33 | 37 | init (if-let [cur-init (-> project :repl-options :init)] |
34 | 38 | (list 'do cur-init init) |
35 | 39 | init) |
36 | | - profile {:dependencies '[[lein-light-nrepl/lein-light-nrepl "0.1.3"] |
37 | | - [org.clojure/tools.reader "0.8.3"]] |
| 40 | + lein-light-version (if (maintained-clojure-version? clj-version) |
| 41 | + ;; Maintained lein-light-nrepl |
| 42 | + "0.2.0" |
| 43 | + ;; Deprecated/unmaintained lein-light-nrepl |
| 44 | + "0.1.3") |
| 45 | + profile {:dependencies [['lein-light-nrepl/lein-light-nrepl lein-light-version]] |
38 | 46 | :repl-options {:nrepl-middleware ['lighttable.nrepl.handler/lighttable-ops] |
39 | | - :init (with-meta init {:replace true})}} |
| 47 | + :init (with-meta init {:replace true})}} |
40 | 48 | project (lp/merge-profiles project [profile])] |
41 | 49 | (println "final project: " project) |
42 | | - project)) |
43 | | - |
44 | | -(defn find-clojure-version [proj] |
45 | | - (let [deps (:dependencies proj)] |
46 | | - (second (first (filter #(= (first %) 'org.clojure/clojure) deps))))) |
| 50 | + project)) |
47 | 51 |
|
48 | | -(defn light |
49 | | - "Start a Light Table client for this project" |
50 | | - [project & [name]] |
51 | | - (when-not (valid-clojure? (find-clojure-version project)) |
| 52 | +(defn abort-unsupported-versions [clj-version cljs-version] |
| 53 | + (when (and clj-version (not (at-least-version? clj-version {:major 1 :minor 5 :patch 1}))) |
52 | 54 | (binding [*out* *err*] |
53 | 55 | (println "Light Table requires Clojure Version 1.5.1 or higher") |
54 | 56 | (System/exit 0))) |
55 | | - (try |
56 | | - (repl/repl (prep project name) ":headless") |
57 | | - (catch Exception e |
58 | | - (.printStackTrace e) |
59 | | - (System/exit 1)))) |
| 57 | + (when (and cljs-version (at-least-version? cljs-version {:major 0 :minor 0 :patch 2341}) |
| 58 | + (not (maintained-clojure-version? clj-version))) |
| 59 | + (binding [*out* *err*] |
| 60 | + (println "Light Table requires Clojure Version >= 1.7.0 for ClojureScript versions >= 0.0-2341") |
| 61 | + (System/exit 0)))) |
| 62 | + |
| 63 | +(defn find-dependency-version [proj dep] |
| 64 | + (let [deps (:dependencies proj)] |
| 65 | + (second (first (filter #(= (first %) dep) deps))))) |
60 | 66 |
|
61 | | -(defn check-project [path] |
62 | | - (when (fs/exists? path) |
63 | | - path)) |
| 67 | +(defn light |
| 68 | + "Start a Light Table client for this project" |
| 69 | + [project name] |
| 70 | + (let [clj-version (find-dependency-version project 'org.clojure/clojure) |
| 71 | + cljs-version (some-> (find-dependency-version project 'org.clojure/clojurescript) |
| 72 | + ;; Make 0.0- conform to standard patch versions |
| 73 | + (string/replace "0.0-" "0.0."))] |
| 74 | + (abort-unsupported-versions clj-version cljs-version) |
| 75 | + (try |
| 76 | + (repl/repl (prep project name clj-version) ":headless") |
| 77 | + (catch Exception e |
| 78 | + (.printStackTrace e) |
| 79 | + (System/exit 1))))) |
64 | 80 |
|
65 | 81 | (defn -main [& [name]] |
66 | 82 | (let [path (str (fs/absolute-path fs/*cwd*) "/project.clj")] |
67 | | - (if (check-project path) |
| 83 | + (if (fs/exists? path) |
68 | 84 | (light (lp/init-project (lp/read path)) name) |
69 | 85 | (binding [*out* *err*] |
70 | 86 | (println "Could not find project.clj file at: " path))))) |
0 commit comments