Add support for reader conditional files (cljc)

Clojure 1.7.0 will add support for reader conditionals:

http://dev.clojure.org/display/design/Reader+Conditionals

This patch adds reader conditional support to leiningen, in particular for
compilation (including aot and stale files) and testing.
This commit is contained in:
Stephen Nelson 2015-05-31 02:05:29 +12:00
parent 6e0ebc20f7
commit f413b6d73f
15 changed files with 73 additions and 14 deletions

View file

@ -4,7 +4,7 @@
:url "http://www.eclipse.org/legal/epl-v10.html"}
:description "Library for core functionality of Leiningen."
:dependencies [[org.clojure/clojure "1.7.0"]
[bultitude "0.2.6"]
[bultitude "0.2.8"]
[classlojure "0.6.6"]
[robert/hooke "1.3.0"]
[com.cemerick/pomegranate "0.3.0"]

View file

@ -64,7 +64,7 @@
(subs 1)
(str suffix)
io/resource))
[".clj" (str clojure.lang.RT/LOADER_SUFFIX ".class")]))
[".clj" ".cljc" (str clojure.lang.RT/LOADER_SUFFIX ".class")]))
(defn error [& args]
(binding [*out* *err*] ;; TODO: use main/warn for this in 3.0

View file

@ -6,10 +6,10 @@
:url "https://github.com/technomancy/leiningen"
:license {:name "Eclipse Public License"
:url "http://www.eclipse.org/legal/epl-v10.html"}
:dependencies [[leiningen-core "2.5.1"]
:dependencies [[leiningen-core "2.5.2-SNAPSHOT"]
[org.clojure/data.xml "0.0.3"]
[commons-io "2.4"]
[bultitude "0.2.6"]
[bultitude "0.2.8"]
[stencil "0.3.5" :exclusions [org.clojure/core.cache]]
[org.apache.maven.indexer/indexer-core "4.1.3"
:exclusions [org.apache.maven/maven-model

View file

@ -5,7 +5,7 @@
[bultitude.core :as b]
[clojure.java.io :as io])
(:refer-clojure :exclude [compile])
(:import (java.io PushbackReader)))
(:import (java.io PushbackReader File)))
(defn- regex? [str-or-re]
(instance? java.util.regex.Pattern str-or-re))
@ -34,13 +34,17 @@
out-of-date class files."
[project]
(for [namespace (compilable-namespaces project)
:let [rel-source (b/path-for namespace)
source (first (sort-by (fn [f] (not (.exists f)))
(for [source-path (:source-paths project)
:let [file (io/file source-path rel-source)]]
file)))]
:let [[rel-source source]
(or (first (for [source-path (:source-paths project)
rel-source (map (partial b/path-for namespace) ["clj" "cljc"])
:let [file (io/file source-path rel-source)]
:when (.exists ^File file)]
[rel-source file]))
(let [rel-source (b/path-for namespace)]
;; always return a source file location (#1205)
[rel-source (io/file (first (:source-paths project)) rel-source)]))]
:when source
:let [rel-compiled (.replaceFirst rel-source "\\.clj$" "__init.class")
:let [rel-compiled (.replaceFirst rel-source "\\.cljc?$" "__init.class")
compiled (io/file (:compile-path project) rel-compiled)]
:when (>= (.lastModified source) (.lastModified compiled))]
namespace))
@ -68,7 +72,9 @@
(defn- source-in-project?
"Tests if a file found in the compile path exists in the source path."
[parent compile-path source-path]
(.exists (io/file (str (.replace parent compile-path source-path) ".clj"))))
(let [path (.replace parent compile-path source-path)]
(or (.exists (io/file (str path ".clj")))
(.exists (io/file (str path ".cljc"))))))
(defn- class-in-project? [project f]
(or (has-source-package? project f (:source-paths project))

View file

@ -231,7 +231,8 @@
(defn- compile-main? [{:keys [main source-paths] :as project}]
(and main (not (:skip-aot (meta main)))
(some #(.exists (io/file % (b/path-for main))) source-paths)))
(some #(or (.exists (io/file % (b/path-for main "clj")))
(.exists (io/file % (b/path-for main "cljc")))) source-paths)))
(def ^:private implicit-aot-warning
(delay

View file

@ -134,7 +134,7 @@
vars))])
(defn- convert-to-ns [possible-file]
(if (and (.endsWith possible-file ".clj") (.exists (io/file possible-file)))
(if (and (re-matches #".*\.cljc?" possible-file) (.exists (io/file possible-file)))
(str (second (b/ns-form-for-file possible-file)))
possible-file))

View file

@ -6,6 +6,7 @@
[leiningen.compile]
[leiningen.test.helper :only [sample-project delete-file-recursively
sample-failing-project
sample-reader-cond-project
tricky-name-project
more-gen-classes-project
with-system-err-str]])
@ -39,6 +40,13 @@
(is (not (.exists (file "test_projects" "more-gen-classes" "target"
"classes" "more_gen_classes" "foo.class")))))
(deftest test-compile-cljc
(compile sample-reader-cond-project)
(is (.exists (file "test_projects" "sample-reader-cond" "target"
"classes" "nom" "nom" "clj__init.class")))
(is (.exists (file "test_projects" "sample-reader-cond" "target"
"classes" "nom" "nom" "cljc__init.class"))))
(def eip-check (atom false))
(deftest ^:online test-plugin

View file

@ -36,6 +36,8 @@
(def sample-profile-meta-project (read-test-project "sample-profile-meta"))
(def sample-reader-cond-project (read-test-project "sample-reader-cond"))
(def tricky-name-project (read-test-project "tricky-name"))
(def native-project (read-test-project "native"))

View file

@ -3,6 +3,7 @@
(:require [clojure.test :refer :all]
[leiningen.test :refer :all]
[leiningen.test.helper :refer [tmp-dir sample-no-aot-project
sample-reader-cond-project
sample-failing-project
with-system-err-str]]
[clojure.java.io :as io]
@ -68,6 +69,10 @@
(test sample-no-aot-project "selectors")
(is (= (ran?) #{:regular :not-custom :int2 :fixture})))
(deftest test-reader-conditional-tests
(test sample-reader-cond-project)
(is (= (ran?) #{:clj-test :cljc-test})))
(deftest test-invalid-namespace-argument
(is (.contains
(with-system-err-str

View file

@ -0,0 +1,10 @@
;; This project is used for leiningen's test suite, so don't change
;; any of these values without updating the relevant tests. If you
;; just want a basic project to work from, generate a new one with
;; "lein new".
(defproject nomnomnom "0.5.0-SNAPSHOT"
:dependencies [[org.clojure/clojure "1.7.0"]
[janino "2.5.15"]]
:aot :all
:uberjar-exclusions [#"DUMMY"])

View file

@ -0,0 +1 @@
(ns nom.nom.clj)

View file

@ -0,0 +1 @@
(ns nom.nom.cljc)

View file

@ -0,0 +1,7 @@
(ns clj-test
(:use [clojure.test]
[selectors :only [record-ran]]))
(deftest clojure-test
(record-ran :clj-test)
(is true))

View file

@ -0,0 +1,8 @@
(ns cljc-test
(:use #?(:clj [clojure.test]
:cljs [cljs.test])
[selectors :only [record-ran]]))
(deftest conditional-test
(record-ran :cljc-test)
(is true))

View file

@ -0,0 +1,10 @@
(ns selectors
(:use [clojure.test]
[clojure.java.io]))
(defn record-ran [t]
(let [file-name (format "%s/lein-test-ran"
(System/getProperty "java.io.tmpdir"))]
(with-open [w (writer file-name :append true)]
(.write w (str t "\n")))))