Code Monkey home page Code Monkey logo

cljx's People

Contributors

bbatsov avatar cemerick avatar jarohen avatar jeluard avatar lbradstreet avatar lynaghk avatar michaelklishin avatar sumbach avatar thomasmulvaney avatar trptcolin avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

cljx's Issues

0.5.0: Seeing StackOverflowError

Hi Chas,

Thanks for the release of 0.5.0! Just tried it out, and I'm seeing a StackOverflowError on lein cljx once (running Leiningen 2.4.2):

lein cljx once
Exception in thread "main" java.lang.StackOverflowError
    at clojure.lang.Cons.next(Cons.java:39)
    at clojure.lang.RT.boundedLength(RT.java:1654)
    at clojure.lang.AFn.applyToHelper(AFn.java:148)
    at clojure.lang.AFn.applyTo(AFn.java:144)
    at clojure.core$apply.invoke(core.clj:626)
    at clojure.core$partial$fn__4228.doInvoke(core.clj:2468)
    at clojure.lang.RestFn.invoke(RestFn.java:408)
    at clojure.core$map$fn__4245.invoke(core.clj:2559)
    at clojure.lang.LazySeq.sval(LazySeq.java:40)
    at clojure.lang.LazySeq.seq(LazySeq.java:49)
    at clojure.lang.RT.seq(RT.java:484)
    at clojure.core$seq.invoke(core.clj:133)
    at clojure.core$apply.invoke(core.clj:624)
    at clojure.walk$walk.invoke(walk.clj:44)
    at clojure.walk$postwalk.invoke(walk.clj:58)
    at clojure.lang.AFn.applyToHelper(AFn.java:156)
    at clojure.lang.AFn.applyTo(AFn.java:144)
    at clojure.core$apply.invoke(core.clj:626)
    at clojure.core$partial$fn__4228.doInvoke(core.clj:2468)
    at clojure.lang.RestFn.invoke(RestFn.java:408)
    at clojure.core$map$fn__4245.invoke(core.clj:2559)
    at clojure.lang.LazySeq.sval(LazySeq.java:40)
    at clojure.lang.LazySeq.seq(LazySeq.java:49)
    at clojure.lang.Cons.next(Cons.java:39)
    at clojure.lang.RT.boundedLength(RT.java:1654)
    at clojure.lang.RestFn.applyTo(RestFn.java:130)
    at clojure.core$apply.invoke(core.clj:624)
    at clojure.walk$walk.invoke(walk.clj:44)
    at clojure.walk$postwalk.invoke(walk.clj:58)
    at clojure.lang.AFn.applyToHelper(AFn.java:156)
    at clojure.lang.AFn.applyTo(AFn.java:144)
    at clojure.core$apply.invoke(core.clj:626)
    at clojure.core$partial$fn__4228.doInvoke(core.clj:2468)
    at clojure.lang.RestFn.invoke(RestFn.java:408)
    at clojure.core$map$fn__4245.invoke(core.clj:2559)
    at clojure.lang.LazySeq.sval(LazySeq.java:40)
    at clojure.lang.LazySeq.seq(LazySeq.java:49)
    at clojure.lang.Cons.next(Cons.java:39)
    at clojure.lang.PersistentList$1.doInvoke(PersistentList.java:37)
    at clojure.lang.RestFn.applyTo(RestFn.java:137)
    at clojure.core$apply.invoke(core.clj:624)
    at clojure.walk$walk.invoke(walk.clj:44)
    at clojure.walk$postwalk.invoke(walk.clj:58)
    at clojure.lang.AFn.applyToHelper(AFn.java:156)
    at clojure.lang.AFn.applyTo(AFn.java:144)
    at clojure.core$apply.invoke(core.clj:626)
    at clojure.core$partial$fn__4228.doInvoke(core.clj:2468)
    at clojure.lang.RestFn.invoke(RestFn.java:408)
    at clojure.core$map$fn__4245.invoke(core.clj:2557)
    at clojure.lang.LazySeq.sval(LazySeq.java:40)
    at clojure.lang.LazySeq.seq(LazySeq.java:49)
    at clojure.lang.RT.seq(RT.java:484)
    at clojure.lang.LazilyPersistentVector.create(LazilyPersistentVector.java:31)
    at clojure.core$vec.invoke(core.clj:354)
    at clojure.walk$walk.invoke(walk.clj:45)
    at clojure.walk$postwalk.invoke(walk.clj:58)
    at clojure.lang.AFn.applyToHelper(AFn.java:156)
    at clojure.lang.AFn.applyTo(AFn.java:144)
    at clojure.core$apply.invoke(core.clj:626)
    at clojure.core$partial$fn__4228.doInvoke(core.clj:2468)
    at clojure.lang.RestFn.invoke(RestFn.java:408)
    at clojure.core$map$fn__4245.invoke(core.clj:2559)
    at clojure.lang.LazySeq.sval(LazySeq.java:40)
    at clojure.lang.LazySeq.seq(LazySeq.java:49)
    at clojure.lang.RT.seq(RT.java:484)
    at clojure.core$seq.invoke(core.clj:133)
    at clojure.core.protocols$seq_reduce.invoke(protocols.clj:30)
    at clojure.core.protocols$fn__6078.invoke(protocols.clj:54)
    at clojure.core.protocols$fn__6031$G__6026__6044.invoke(protocols.clj:13)
    at clojure.core$reduce.invoke(core.clj:6289)
    at clojure.core$into.invoke(core.clj:6341)
    at clojure.walk$walk.invoke(walk.clj:49)
    at clojure.walk$postwalk.invoke(walk.clj:58)
    at clojure.lang.AFn.applyToHelper(AFn.java:156)
    at clojure.lang.AFn.applyTo(AFn.java:144)
    at clojure.core$apply.invoke(core.clj:626)
    at clojure.core$partial$fn__4228.doInvoke(core.clj:2468)
    at clojure.lang.RestFn.invoke(RestFn.java:408)
    at clojure.core$map$fn__4245.invoke(core.clj:2557)
    at clojure.lang.LazySeq.sval(LazySeq.java:40)
    at clojure.lang.LazySeq.seq(LazySeq.java:49)
    at clojure.lang.RT.seq(RT.java:484)
    at clojure.lang.LazilyPersistentVector.create(LazilyPersistentVector.java:31)
    at clojure.core$vec.invoke(core.clj:354)
    at clojure.walk$walk.invoke(walk.clj:45)
    at clojure.walk$postwalk.invoke(walk.clj:58)
    at clojure.lang.AFn.applyToHelper(AFn.java:156)
    at clojure.lang.AFn.applyTo(AFn.java:144)
    at clojure.core$apply.invoke(core.clj:626)
    at clojure.core$partial$fn__4228.doInvoke(core.clj:2468)
    at clojure.lang.RestFn.invoke(RestFn.java:408)
    at clojure.core$map$fn__4245.invoke(core.clj:2559)
    at clojure.lang.LazySeq.sval(LazySeq.java:40)
    at clojure.lang.LazySeq.seq(LazySeq.java:49)
    at clojure.lang.Cons.next(Cons.java:39)
    at clojure.lang.RT.next(RT.java:598)
    at clojure.core$next.invoke(core.clj:64)
    at clojure.core.protocols$fn__6086.invoke(protocols.clj:146)
    at clojure.core.protocols$fn__6057$G__6052__6066.invoke(protocols.clj:19)
    at clojure.core.protocols$seq_reduce.invoke(protocols.clj:31)
    at clojure.core.protocols$fn__6078.invoke(protocols.clj:54)
    at clojure.core.protocols$fn__6031$G__6026__6044.invoke(protocols.clj:13)
    at clojure.core$reduce.invoke(core.clj:6289)
    at clojure.core$into.invoke(core.clj:6341)
    at clojure.walk$walk.invoke(walk.clj:49)
    at clojure.walk$postwalk.invoke(walk.clj:58)
    at clojure.lang.AFn.applyToHelper(AFn.java:156)
    at clojure.lang.AFn.applyTo(AFn.java:144)
    at clojure.core$apply.invoke(core.clj:626)
    at clojure.core$partial$fn__4228.doInvoke(core.clj:2468)
    at clojure.lang.RestFn.invoke(RestFn.java:408)
    at clojure.core$map$fn__4245.invoke(core.clj:2557)
    at clojure.lang.LazySeq.sval(LazySeq.java:40)
    at clojure.lang.LazySeq.seq(LazySeq.java:49)
    at clojure.lang.RT.seq(RT.java:484)
    at clojure.lang.LazilyPersistentVector.create(LazilyPersistentVector.java:31)
    at clojure.core$vec.invoke(core.clj:354)
    at clojure.walk$walk.invoke(walk.clj:45)
    at clojure.walk$postwalk.invoke(walk.clj:58)
    at clojure.lang.AFn.applyToHelper(AFn.java:156)
    at clojure.lang.AFn.applyTo(AFn.java:144)
    at clojure.core$apply.invoke(core.clj:626)
    at clojure.core$partial$fn__4228.doInvoke(core.clj:2468)
    at clojure.lang.RestFn.invoke(RestFn.java:408)
    at clojure.core$map$fn__4245.invoke(core.clj:2559)
    at clojure.lang.LazySeq.sval(LazySeq.java:40)
    at clojure.lang.LazySeq.seq(LazySeq.java:49)
    at clojure.lang.Cons.next(Cons.java:39)
    at clojure.lang.RT.next(RT.java:598)
    at clojure.core$next.invoke(core.clj:64)
    at clojure.core.protocols$fn__6086.invoke(protocols.clj:146)
    at clojure.core.protocols$fn__6057$G__6052__6066.invoke(protocols.clj:19)
    at clojure.core.protocols$seq_reduce.invoke(protocols.clj:31)
    at clojure.core.protocols$fn__6078.invoke(protocols.clj:54)
    at clojure.core.protocols$fn__6031$G__6026__6044.invoke(protocols.clj:13)
    at clojure.core$reduce.invoke(core.clj:6289)
    at clojure.core$into.invoke(core.clj:6341)
    at clojure.walk$walk.invoke(walk.clj:49)
    at clojure.walk$postwalk.invoke(walk.clj:58)
    at clojure.walk$postwalk_replace.invoke(walk.clj:123)
    at clojure.lang.AFn.applyToHelper(AFn.java:156)
    at clojure.lang.AFn.applyTo(AFn.java:144)
    at clojure.core$apply.invoke(core.clj:626)
    at clojure.core$partial$fn__4228.doInvoke(core.clj:2468)
    at clojure.lang.RestFn.invoke(RestFn.java:408)
    at clojurescript.test.plugin$middleware.invoke(plugin.clj:61)
    at clojure.lang.Var.invoke(Var.java:379)
        <...>

This is against Sente's dev branch, available here. Cljx version 0.4.0 was working fine, as was a fork using @lbradstreet's patch here - so I'm guessing this is maybe the result of one of the other changes, like sjacket?

Should have some free time later tonight; will try see if I can find a specific cause then. Just bringing this to your attention in the meantime and checking if you have any ideas off the top of your head?

Thanks again, cheers! :-)

Slightly odd behavior when using cljx in ns declaration

In terms of generated output files, cljx works perfectly.

However, in terms of the repl, I am getting some errors when putting cljx readers into the (ns ) declaration.

Reproduce by

git clone [email protected]:samedhi/cljx-ns-trouble.git
cd cljx-ns-trouble
lein repl-headless

open emacs
start up nrepl and connect to your repl-headless session
Then visit the file at cljx/trouble.cljx

Within emacs try
Ctrl-c Meta-n => RuntimeException Unmatched delimiter: ) clojure.lang.Util.runtimeException (Util.java:219)

Ctrl-c-k works fine but then if you Ctrl-x-e on expression at line 4 you get => Namespace not found

You can circumvent the errors by evaluating the expressions (including the ns declaration) one at a time, or by removing the cljx code from the ns declaration.

Thought: extension-aware handling

Hi Chas! Just thinking out loud here...

The two major workflow patterns seem to be:

  • Separate /src/clj, src/cljs, src/cljx dirs.
  • A single /src dir with mixed .clj, .cljs, .cljx files as necessary.

In both of these cases there's a tricky choice that needs to be made when a namespace is predominantly but not entirely single-platform. The choice is:

  • Split the cross-platform code into another ns.
  • Make the entire ns a .cljx file with appropriate annotations everywhere.

It occurs to me that an alternative may be worth thinking about:

  • The Cljx transformer picks up all relevant file extensions: .clj, .cljs, .cljx.
  • Its behaviour depends on the file extension being processed.

Within .cljx files, we have the usual #+clj and #+cljs annotations.
Within .clj files, everything is assumed to be #+clj unless otherwise annotated.
Within .cljs files, everything is assumed to be #+cljs unless otherwise annotated.

This'd allow a convenient third choice to the problem above: use a file extension (.clj/.cljs) appropriate for the majority of the ns code and add a minimal number of annotations for the few alternate-platform bits.

(With this capability I'd suggest that the second workflow pattern would make a sensible default recommendation btw, but that's tangential).

There is a snag:
There would be an ambiguity in .clj/.cljs files whether #+cljs/#+clj means "this code only for that platform", or "also" for that platform. Some ideas off the top of my head:

  • Add a #+cljx annotation to mean "both platforms" [1].
  • Add #+clj-also #+cljs-also or equivalent annotations (my preference).
  • Allow #+clj and #+cljs to both coexist on the same form somehow (seems distasteful + possibly tricky?).

[1] At first I thought the #+cljx annotation may be limiting (what if we have additional platforms later?) - but in fact this is the default behaviour anyway with .cljx files currently so may be reasonable.

Curious to get your feedback on this. Anyway, enjoy the rest of your weekend - cheers! :-)

Environment variables

I'd like to make some server environment variables available to CLJS, through something like environ. Does cljx enable this sort of functionality?

Double cljs generation if hooks are enabled for both cljsbuild and cljx

Here is a test repository where I enabled :hooks for both cljsbuild and cljx:

git clone https://github.com/magomimmo/modern-cljs.git
cd modern-cljs
git checkout double
$ lein do clean, compile, test
Deleting files generated by lein-cljsbuild.
Rewriting test/cljx to target/test/clj (clj) with features #{clj} and 0 transformations.
Rewriting test/cljx to target/test/cljs (cljs) with features #{cljs} and 1 transformations.
Compiling ClojureScript.
Compiling "resources/public/js/modern_pre.js" from ["src/brepl" "src/cljs"]...
...
...
Successfully compiled "target/test/js/testable.js" in 7.192822 seconds.
Rewriting test/cljx to target/test/clj (clj) with features #{clj} and 0 transformations.
Rewriting test/cljx to target/test/cljs (cljs) with features #{cljs} and 1 transformations.
Compiling ClojureScript.
Compiling "target/test/js/testable_dbg.js" from ["src/brepl" "src/cljs" "target/test/cljs"]...
...
...
Successfully compiled "target/test/js/testable.js" in 6.853873 seconds.

lein test modern-cljs.shopping.validators-test

Ran 1 tests containing 13 assertions.
0 failures, 0 errors.
Running all ClojureScript tests.
Testing modern-cljs.shopping.validators-test

Ran 1 tests containing 13 assertions.
....
{:test 1, :pass 13, :fail 0, :error 0, :type :summary}
$

I don-t know if this behavior pertains cljx, cljsbuild or even `lein.

Nested expressions not supported

Not sure if this is the intended behaviour, but it seems that attempting to exclude nested forms results in :cljx.core/exclude being left over in the generated code. From line 33 of cljx.core (remove #(= % :cljx.core/exclude)), it seems that this is by design because a remove is performed instead of a walk. Would it be possible to support this?

Example of input code that exhibits this problem:

(ns dali.core
  ^:clj
  (:use [dali.macros :only (defshape)])
  ^:cljs
  (:use-macros [dali.macros :only (defshape)]))

Characters in a cljx file after #+clj

Not sure if this is some oversight on my part, or a bug, so I'll report it here. I'm running Clojure 1.7.0-alpha2, cljx 0.6.0, using CIDER nrepl 0.8.2.

Leiningen 2.4.2 on Java 1.8.0_11 Java HotSpot(TM) 64-Bit Server VM

We've been using cljx for a while with no issues, but just noticed an error with the following code snippet inside a cljx file:

#+clj
(defn foo []
  \x)

Compiling that namespace yields "No reader function for tag +clj". If I remove the #+clj, or if I replace the \x with "x", all works well.

:source-paths is platform specific

On Windows, :source-paths has to be defined as "src\cljx" otherwise it's ignored and the generated files end up in the same directory as the original files. This is because of line 49 of cljx.core which uses a regular expression to do path manipulation: (string/replace cljx-path output-path).

Break when upgrading from Cljx 0.4.0 to 0.6.0

Hi Chas,

Upgrading from Cljx 0.4.0 to 0.6.0 produces the following new error on lein check:

Exception in thread "main" java.lang.Exception: namespace 'cemerick.piggieback' not found, compiling:(cljx/repl_middleware.clj:1:1)
    at clojure.core$throw_if.doInvoke(core.clj:5572)
    at clojure.lang.RestFn.invoke(RestFn.java:442)
    at clojure.core$load_lib.doInvoke(core.clj:5658)
    at clojure.lang.RestFn.applyTo(RestFn.java:142)
    at clojure.core$apply.invoke(core.clj:628)
    at clojure.core$load_libs.doInvoke(core.clj:5691)
    at clojure.lang.RestFn.applyTo(RestFn.java:137)
    at clojure.core$apply.invoke(core.clj:628)
    at clojure.core$require.doInvoke(core.clj:5774)
    at clojure.lang.RestFn.invoke(RestFn.java:512)
    at cljx.repl_middleware$eval48740$loading__5295__auto____48741.invoke(repl_middleware.clj:1)

lein deps :tree shows that the correct deps are being pulled in:

 [com.keminglabs/cljx "0.6.0"]
   [com.cemerick/piggieback "0.1.5"]
   [net.cgrand/sjacket "0.1.1" :exclusions [[org.clojure/clojure]]]
     [net.cgrand/parsley "0.9.2"]
     [net.cgrand/regex "1.1.0"]
   [org.clojure/core.match "0.2.0"]
   [watchtower "0.1.1"]

I suspect that this is the breaking change you're referring to here, but I'm a little unclear from the description there what the problem / correct migration actually are.

My project.clj config:

  1. A top-level :dependencies entry: [com.keminglabs/cljx "0.6.0"] - since I'm using my own nrepl middleware stack which includes cljx.repl-middleware/wrap-cljx and needs to exist in production.
  2. A top-level :plugins entry: [com.keminglabs/cljx "0.6.0" :middleware false].
  3. A top-level :prep-tasks [["cljx" "once"] "javac" "compile"] entry.
  4. A top-level :cljx entry:
:cljx
{:builds
 [{:source-paths ["src" "test"] :rules :clj  :output-path  "target/classes"}
  {:source-paths ["src" "test"] :rules :cljs :output-path  "target/classes"}]}''

0.4.0 works fine with this config, 0.6.0 throws the piggieback exception. Would appreciate your input if you have any ideas?

Thanks a lot!

Cheers :-)

Stop requiring precompilation for REPL-ing

The REPL middleware works well, but it doesn't help when you load a file or evaluate an expression that requires some other namespace that:

  1. Is defined in a .cljx file, and
  2. Has not already been precompiled into Clojure/ClojureScript already.

The REPL middleware needs to intercept load calls so that e.g. (require 'foo) will look for a foo.cljx resource on the classpath, cljx it to Clojure/ClojureScript based on the prevailing rules, and then invoke the regular file-loading mechanism for the type of REPL session in progress. Of course, if a .cljx file isn't available, the normal loading mechanism should apply.

Done pervasively/properly, this should make cljx precompilation entirely unnecessary except when cutting a jar/war/other distributable.

Circular dependency bug when user.clj exists

When lein cljx once or lein cljx auto is executed, any code in the user namespace is automatically loaded. In the development profile, this namespace may be populated. For instance if a project is designed along the lines of Stuart Sierra's reloaded workflow, there may be a file "dev/user.clj" that is included in the development profile.

If this is the case, running lein cljx can result in a circular dependency, if the user namespace depends on files that are generated by cljx.

I'm currently working around this with the following:

:aliases {"cljx" ["with-profile" "cljx" "cljx"]}
:profiles {:cljx {}}

cljx auto generates double output

I'm using cljx 0.5.0 and it works great when I run lein cljx once. However, when I run lein cljx auto it will generate the code twice and I'm not sure wether this is caused by a misconfiguration in the project.clj or a bug of cljx.

The following folders are created:

  1. target/generated-src/{ns}... -> correct clj/cljs files
  2. target/generated-src/file//{path-to-project}/test/cljx/{ns}/... -> contains generated clj/cljs test-files
  3. target/generated-test/{ns}... -> correct clj/cljs test-files
  4. target/generated-src/file//{path-to-project}/src/cljx/{ns}/... -> contains generated clj/cljs files

With lein cljx once only the folders of 1 and 3 are generated.

My project.clj contains the following:

(defproject ...
  :source-paths ["src/clj" "src/cljs" "target/generated-src"]
  :test-paths ["test/clj" "test/cljs" "target/generated-test"]
...
  :auto-clean false
  :cljx {:builds [{:source-paths ["src/cljx"]
                   :output-path "target/generated-src"
                   :rules :clj}
                  {:source-paths ["src/cljx"]
                   :output-path "target/generated-src"
                   :rules :cljs}
                  {:source-paths ["test/cljx"]
                   :output-path "target/generated-test"
                   :rules :clj}
                  {:source-paths ["test/cljx"]
                   :output-path "target/generated-test"
                   :rules :cljs}]}
...
  :dependencies [
    [org.clojure/clojure            "1.6.0"]
    [org.clojure/clojurescript      "0.0-2511" :scope "provided"]
...
  ]
  :profiles {
    :dev {
      :plugins [[com.keminglabs/cljx  "0.5.0"          :exclusions [org.clojure/clojure org.clojure/clojurescript]]]
      :prep-tasks   [["cljx" "once"]]
...
  }}
}})

Current file generation approach is broken with recent leiningen

Starting 2.4.2 leiningen calls the clean task right before the deploy task. This implies for most cljx configuration jars uploaded won't contain any generated file. Starting 2.5.0 the same happens before install so even local jars won't be properly generated.
:auto-clean false can be used for this but it looks like the preferred solution is to rely on :prep-tasks "cljx once".

Documentation should probably be updated as this behavior is pretty unexpected.

See leiningen#1642 and leiningen#1586 for more details.

exclude only annotation

Lets say I have a cljx source with a ns declaration like this:

(ns #+clj ^{:doc "spam" :author "me"}
  my.ns)

The resulting .cljs would be:

(ns
       )

but I would wish this in some way:

(ns
  my.ns)

How do I prevent the ^{...} from being included in the cljs generated source, but not my.ns also?

Miss clean subtask

Hi Keving,
very good work! But I miss a $ lein cljx clean subtask to delete any generated clj/cljs file. Is it something you're working on?
Thanks so much

Homogenize hooks with cljsbuild

Wouldn't be better to have the same way to hook cljx and cljsbuild to tasks?
Now we have to write:

:hooks [leiningen.cljsbuild cljx.hooks]

IMHO it would be better to write

:hooks [leiningen.cljsbuild leiningen.cljx] 

polling rate

cljx is a great way to write portable code and I was wondering if there is a way to speed up compiling. I noticed that the polling rate is set to 1000ms. Worst case, it takes a whole second just to notice that a file was changed.

What do you think of making the polling rate configurable or dropping it to something much lower, like 50ms?

Stacktrace while trying to lein cljs once

I got a stacktrace while trying to cljx the demo file from readme.MD. I wish I could provide more info but I don't know what else should I report. My project.clj is also pretty standard. The :cljx part looks like:

:cljx {:builds [{:source-paths ["src/cljx"]
             :output-path "target/cljx-generated/clj"
             :rules :clj}

            {:source-paths ["src/cljx"]
             :output-path "target/cljx-generated/cljs"
             :rules :cljs}]}

Here is what I get:

▸ lein cljx once
Rewriting src/cljx to target/cljx-generated/clj (clj) with features #{clj} and 0 transformations.
Exception in thread "main" java.lang.IndexOutOfBoundsException
at clojure.lang.RT.subvec(RT.java:1483)
at clojure.core$subvec.invoke(core.clj:3440)
at cljx.rules$apply_features.invoke(rules.clj:18)
at cljx.core$walk.invoke(core.clj:29)
at cljx.core$walk$fn__3486.invoke(core.clj:35)
at clojure.core$iterate$fn__4266.invoke(core.clj:2651)
at clojure.lang.LazySeq.sval(LazySeq.java:42)
at clojure.lang.LazySeq.seq(LazySeq.java:60)
at clojure.lang.Cons.next(Cons.java:39)
at clojure.lang.RT.next(RT.java:598)
at clojure.core$next.invoke(core.clj:64)
at clojure.core$some.invoke(core.clj:2443)
at cljx.core$walk.invoke(core.clj:32)
at cljx.core$walk$fn__3486.invoke(core.clj:35)
at clojure.core$iterate$fn__4266.invoke(core.clj:2651)
at clojure.lang.LazySeq.sval(LazySeq.java:42)
at clojure.lang.LazySeq.seq(LazySeq.java:60)
at clojure.lang.Cons.next(Cons.java:39)
at clojure.lang.RT.next(RT.java:598)
at clojure.core$next.invoke(core.clj:64)
at clojure.core$some.invoke(core.clj:2443)
at cljx.core$walk.invoke(core.clj:32)
at cljx.core$transform.invoke(core.clj:44)
at cljx.core$generate.invoke(core.clj:65)
at cljx.core$cljx_compile.invoke(core.clj:86)
at clojure.lang.Var.invoke(Var.java:415)
at user$eval3531.invoke(NO_SOURCE_FILE:1)
at clojure.lang.Compiler.eval(Compiler.java:6619)
at clojure.lang.Compiler.eval(Compiler.java:6608)
at clojure.lang.Compiler.eval(Compiler.java:6609)
at clojure.lang.Compiler.eval(Compiler.java:6582)
at clojure.core$eval.invoke(core.clj:2852)
at clojure.main$eval_opt.invoke(main.clj:308)
at clojure.main$initialize.invoke(main.clj:327)
at clojure.main$null_opt.invoke(main.clj:362)
at clojure.main$main.doInvoke(main.clj:440)
at clojure.lang.RestFn.invoke(RestFn.java:421)
at clojure.lang.Var.invoke(Var.java:419)
at clojure.lang.AFn.applyToHelper(AFn.java:163)
at clojure.lang.Var.applyTo(Var.java:532)
at clojure.main.main(main.java:37)
Subprocess failed

Source directories from parent directories don't work

Using :source-paths like ["../shared/src/cljx"] doesn't work.

Exception in thread "main" java.io.FileNotFoundException: 
/home/juho/Source/foobar/target/generated/clj/file:/home/juho/Source/foobar/app1/../shared/src/cljx/foobar/common/transit.clj (No such file or directory), compiling:(/tmp/form-init2327862490854915151.clj:1:72)

This would be fixed by #67

Getting cljx to work in LightTable

Hello,

I'm trying to get cljx files be parsed correctly by Light Table. First I try to be able to use load-file from the REPL.

From cljx README, I only need to install cljx as a plugin, but it doesn't work.

So I tried to use cljx.repl-middleware/wrap-cljx nrepl middleware.

To perform my experiment, I tried to load cljx file from Schema configured REPL which is of the following:

:profiles {:dev {:dependencies [[org.clojure/clojure "1.5.1"]
                                  [org.clojure/clojurescript "0.0-2030"]
                                  [com.keminglabs/cljx "0.3.1"]]
                   :plugins [[com.keminglabs/cljx "0.3.1"]
                             [lein-cljsbuild "0.3.2"]
                             [com.cemerick/austin "0.1.3"]
                             [com.cemerick/clojurescript.test "0.2.2"]]
                   :hooks [leiningen.cljsbuild]
                   :repl-options {:nrepl-middleware [cemerick.piggieback/wrap-cljs-repl
                                                     cljx.repl-middleware/wrap-cljx]}}}

When I launch lein repl, cljx generates the cljs/clj files and cljsbuild generate javascript. When done, if I tried to load a cljx file *(load-file "test/cljx/schema/test_test.cljx") I got the following error:

nREPL server started on port 57898 on host 127.0.0.1
REPL-y 0.3.0
Clojure 1.5.1
    Docs: (doc function-name-here)
          (find-doc "part-of-name-here")
  Source: (source function-name-here)
 Javadoc: (javadoc java-object-or-class-here)
    Exit: Control+D or (exit) or (quit)
 Results: Stored in vars *1, *2, *3, an exception in *e

user=> (load-file "test/cljx/schema/test_test.cljx")

CompilerException java.lang.RuntimeException: No reader function for tag +clj, compiling:(/Users/bertrand/Desktop/schema/test/cljx/schema/test_test.cljx:2:28)

Can you explain me how to make it work ?

Sincerely

Bertrand

CLJX overrides Piggieback dependency

Hi Kevin/all,

I think there's an incompatibility between CLJX and browser REPLs caused by CLJX's middleware adding its own dependency (including its version of Piggieback - currently 0.1.0, latest is 0.1.3) to the project in preference to any other version of Piggieback that users specify in their project.clj.

It's been raised on the mailing list at https://groups.google.com/forum/?fromgroups=#!topic/clojurescript/-ZfDekURO6I - although I've had other problems with this in the past - sorry for not reporting it sooner.

I currently work around it with this gist: https://gist.github.com/james-henderson/4c890844903f6054334b - essentially, by replicating what the middleware does in my own project.clj.

I can think of a couple of solutions off the top of my head, (although I suspect with your familiarity with the codebase, you'll probably have more ideas!):

  • Updating the piggieback dependency to 0.1.3 (the easy solution!)
  • Using leinjacker's leinjacker.deps/add-if-missing rather than just conj - this would mean that users could add their own CLJX dependency with exclusions, and the middleware wouldn't override it
  • Adding the CLJX dependency in a way that doesn't take preference over other dependencies (I'm not entirely sure about how lein resolves version conflicts, so not sure if it's possible to do this reliably?)

Thanks for writing and maintaining CLJX btw, it's really helped my Clojure/ClojureScript workflow - a much appreciated library!

James

Drop hooks

It looks like :prep-tasks [["cljx" "once"]] works nicely, so we can eliminate the hooks and change docs. This will fix #22, too.

Invocation of cljsbuild from cljx auto

Out-of-the-box, cljx auto does not provide a means of calling cljsbuild (once?) upon run.

Some workflow or configuration for getting the effect of both "lein cljx auto" and "lein cljsbuild auto" should be documented as supported.

Endless loop when used from :prep-tasks

I currently have this in my project.clj:

                   :prep-tasks [["clean"]
                                ["cljx" "once"]
                                ["cljs-prod"]
                                ["garden" "once"]
                                ["javac"]
                                ["compile" ":all"]]

With both 0.4.0 and 0.5.0, cljx seems trigger this sequence of events to be performed again and again. In 0.4.0, cljx is run before the others, in 0.5.0 it seems that cljx isn't run at all (possibly related to #60 )

I recently fixed this in lein-garden, maybe it's something similar here: https://github.com/Skinney/lein-garden/commit/6dc65a2193fca84838b34334a37c6d2b23b7e799

Clojure REPL not working if CLJX 0.5.0 & CLJS 2665 on classpath

Am not entirely sure if that is related to recent REPL changes in CLJS, but I can't open a Clojure REPL in my CLJX project anymore :( Removing all other deps and trying various recent CLJS releases, the issue only seems to start w/ CLJS 0.0-2665, 2657 still is working fine...

lein repl
.... (a ton of various reflection warnings because I enabled them...)
Reflection warning, cemerick/piggieback.clj:54:3 - call to static method putProperty on org.mozilla.javascript.ScriptableObject can't be resolved (argument types: unknown, java.lang.String, java.lang.Object).
Error loading cljx.repl-middleware: java.lang.IllegalArgumentException: No single method: _setup of interface: cljs.repl.IJavaScriptEnv found for function: -setup of protocol: IJavaScriptEnv, compiling:(cemerick/piggieback.clj:149:5)
Exception in thread "main" java.lang.RuntimeException: Unable to resolve var: cljx.repl-middleware/wrap-cljx in this context, compiling:(/private/var/folders/x8/_j311xvx49151dw3t3gmcbmm0000gn/T/form-init601009934546686385.clj:1:1829)
    at clojure.lang.Compiler.analyzeSeq(Compiler.java:6651)
    at clojure.lang.Compiler.analyze(Compiler.java:6445)
    at clojure.lang.Compiler.analyze(Compiler.java:6406)
    at clojure.lang.Compiler$InvokeExpr.parse(Compiler.java:3719)
    at clojure.lang.Compiler.analyzeSeq(Compiler.java:6646)
    at clojure.lang.Compiler.analyze(Compiler.java:6445)
    at clojure.lang.Compiler.analyze(Compiler.java:6406)
    at clojure.lang.Compiler$InvokeExpr.parse(Compiler.java:3719)
    at clojure.lang.Compiler.analyzeSeq(Compiler.java:6646)
    at clojure.lang.Compiler.analyze(Compiler.java:6445)
    at clojure.lang.Compiler.access$100(Compiler.java:38)
    at clojure.lang.Compiler$LetExpr$Parser.parse(Compiler.java:6050)
    at clojure.lang.Compiler.analyzeSeq(Compiler.java:6644)
    at clojure.lang.Compiler.analyze(Compiler.java:6445)
    at clojure.lang.Compiler.analyze(Compiler.java:6406)
    at clojure.lang.Compiler$BodyExpr$Parser.parse(Compiler.java:5782)
    at clojure.lang.Compiler$FnMethod.parse(Compiler.java:5217)
    at clojure.lang.Compiler$FnExpr.parse(Compiler.java:3846)
    at clojure.lang.Compiler.analyzeSeq(Compiler.java:6642)
    at clojure.lang.Compiler.analyze(Compiler.java:6445)
    at clojure.lang.Compiler.eval(Compiler.java:6700)
    at clojure.lang.Compiler.eval(Compiler.java:6693)
    at clojure.lang.Compiler.eval(Compiler.java:6693)
    at clojure.lang.Compiler.load(Compiler.java:7130)
    at clojure.lang.Compiler.loadFile(Compiler.java:7086)
    at clojure.main$load_script.invoke(main.clj:274)
    at clojure.main$init_opt.invoke(main.clj:279)
    at clojure.main$initialize.invoke(main.clj:307)
    at clojure.main$null_opt.invoke(main.clj:342)
    at clojure.main$main.doInvoke(main.clj:420)
    at clojure.lang.RestFn.invoke(RestFn.java:421)
    at clojure.lang.Var.invoke(Var.java:383)
    at clojure.lang.AFn.applyToHelper(AFn.java:156)
    at clojure.lang.Var.applyTo(Var.java:700)
    at clojure.main.main(main.java:37)
Caused by: java.lang.RuntimeException: Unable to resolve var: cljx.repl-middleware/wrap-cljx in this context
    at clojure.lang.Util.runtimeException(Util.java:221)
    at clojure.lang.Compiler$TheVarExpr$Parser.parse(Compiler.java:659)
    at clojure.lang.Compiler.analyzeSeq(Compiler.java:6644)
    ... 34 more

Is is possible to make this faster?

This isn't so much a problem, but just a open ended question. Adding the cljx hook to my project adds about 4-5 seconds to my "lein test" task.

Don't get me wrong, I appreciate what cljx is doing for me. I was just wondering if there was some way (documented or otherwise) to get cljx to either:

  1. Just run a lot faster
  2. Only run if the source (cljx) file is newer than the derived (clj or cljs) file
  3. Do something else to achieve the same effect.

Upgrade core.logic (track whatever kibit requires)

Attempting to eliminate the 0.7.0 core.logic dependency (thus tracking the rev that kibit requests, currently 0.8.0-rc2) results in a stackoverflow:

Rewriting src/cljx to target/classes (clj) with 2 rules.
Exception in thread "main" java.lang.StackOverflowError
    at clojure.core.logic.Substitutions.walk(logic.clj:546)
    at clojure.core.logic$walk_STAR_.invoke(logic.clj:415)
    at clojure.core.logic$walk_STAR_$fn__1399.invoke(logic.clj:420)
    at clojure.core.logic$eval1582$fn__1583.invoke(logic.clj:1068)
    at clojure.core.logic$eval312$fn__313$G__303__320.invoke(logic.clj:85)
    at clojure.core.logic$walk_STAR_.invoke(logic.clj:416)
......

Using kibit with the older core.logic works now, but that's presumably not going to be true forever…

0.5.0 fails to run cljx in sequence of prep tasks

I run my builds with the following in my uberjar profile:

:prep-tasks ^:replace [["clean"]
                                              ["cljx" "once"]
                                              ["cljsbuild" "clean"]
                                              ["cljsbuild" "once" "prod"]
                                              ["javac"]
                                              ["compile" ":all"]]

With cljx 0.4.0 and Leiningen 2.5.0, this works great. When I upgrade to cljx 0.5.0, the cljsbuild task starts running before cljx, causing a compilation failure and crashing the process. Moving cljx after cljsbuild doesn't help.

If I remove all tasks except for cljx, it works.

Any ideas on what might have changed here?

Is automatic symbol replacement worth it?

The sjacket branch now has symbol replacement (e.g. clojure.lang.IFn => cljs.core.IFn).

After looking into expanding this significantly (with the objective of providing at least a full mapping of Clojure interfaces => ClojureScript protocols), I'm think that it's not such a good idea. While there's a sizable correspondence between the names involved, it's far from uniform: ClojureScript has many, many more protocols than Clojure has interfaces, and the methods defined by them are arranged in a couple of cases slightly differently. We could provide automatic replacement for the ones that are directly analogous, but then users would be left having to know/remember which protocol name changes are taken care of and which aren't.

Beyond that, it seems like the real pain around protocols isn't their names, but their methods. The camelCase vs. -dash-prefix conventions are consistent in many places, but post-ClojureScript Clojure protocols have been following that movement and also using -dash-prefix method names; do we always presume that people are writing Clojure and convert when emitting ClojureScript? What happens with "userland" protocols that use the camelCase convention?

I'm strongly leaning towards abandoning this particular feature (though cljx master only replaces two symbols as it is, IFn and Atom ;-P). Thoughts?

cljx leaking as dependency

The README states:

cljx itself will be added as a project dependency (this will only affect REPL processes, and won't leak out into your project's pom.xml, influencing downstream users of your library, if you're writing one)

However, cljx does leak out. For example, the Medley 0.5.0 has a dependency on cljx 0.4.0.

Error handling in cljx-compile

Having this bug in project.clj:

:cljx {:builds [{ ; boring
                        :rules clj}]}

caused the rather unhelpful error:

$ lein cljx once
java.lang.NullPointerException
    at clojure.lang.Symbol.intern(Symbol.java:60)
    at clojure.core$symbol.invoke(core.clj:539)
    at cljx.core$cljx_compile.doInvoke(core.clj:85)
    at clojure.lang.RestFn.invoke(RestFn.java:410)
    at leiningen.cljx$once.invoke(cljx.clj:11)
    at leiningen.cljx$cljx.invoke(cljx.clj:33) ...

I do appreciate the freedom the fallback to resolving symbols in cljx-compile allows - but it causes a steep price for an average user (in a failure case like this).
A little more context (e.g. "NPE while trying to load namespace x") in the error message seems like a good idea.
Maybe even fuzzy checking to catch "clj" and "cljs" as strings / symbols and emit a "Did you actually mean what you wrote in the config?" message.

Does cljx somehow affect my classpath?

I have the following project.clj

(defproject samedhi.quizry "0.0.1-SNAPSHOT"
  :dependencies [[org.clojure/clojure "1.5.1"]
                 [org.clojure/clojurescript "0.0-1878"]
                 [domina "1.0.1"]
                 [ch.qos.logback/logback-classic "1.0.7"
                  :exclusions [org.slf4j/slf4j-api]]
                 [io.pedestal/pedestal.app "0.2.1"]
                 [io.pedestal/pedestal.app-tools "0.2.1"]
                 [com.cemerick/piggieback "0.1.0"]
                 [org.clojure/test.generative "0.5.1" 
                   :exclusions [org.clojure/tools.namespace]]
                 [org.clojure/core.async "0.1.242.0-44b1e3-alpha"]]
  :repl-options
  {:port 5000
   :init-ns user
   :init (do
           (try
             (use 'io.pedestal.app-tools.dev)
             (catch Throwable t
               (println "ERROR: There was a problem loading io.pedestal.app-tools.dev")
               (clojure.stacktrace/print-stack-trace t)
               (println)))
           (start))
   :welcome (println "Welcome to pedestal-app! Run (tools-help) for help.")}

  :aliases {"test!"  ["do" "clean," "test"]
            "repl-headless"["trampoline""repl" ":headless"]}

  :repositories {"sonatype-oss-public" "https://oss.sonatype.org/content/groups/public/"}
  :min-lein-version "2.0.0"
  :source-paths ["app/src" "app/templates" "app/generated/cljs"]
  :test-paths   ["app/src" "test" "app/generated/clj"]
  :resource-paths ["config"]
  :target-path "out/"
  :clean-targets [:target-path "app/generated"]
  :main ^{:skip-aot true} io.pedestal.app-tools.dev
  :plugins [[com.keminglabs/cljx "0.3.1"]]
  :cljx {:builds [{:source-paths ["app/cljx"]
                   :output-path "app/generated/clj/samedhi/quizry"
                   :rules :clj}

                  {:source-paths ["app/cljx"]
                   :output-path "app/generated/cljs/samedhi/quizry"
                   :rules :cljs}

                  {:source-paths ["app/macro-cljx"]
                   :output-path "app/generated/clj/samedhi/quizry"
                   :rules
                   {:filetype "clj"
                    :features #{"clj"}
                    :transforms []}}

                  {:source-paths ["app/macro-cljx"]
                   :output-path "app/generated/cljs/samedhi/quizry"
                   :rules
                   {:filetype "clj"
                    :features #{"cljs"}
                    :transforms []}}]}
  :hooks [cljx.hooks])

And have 2 odd things to report.

Number 1:

As you can see, I separated my simple clojure and macro containing clojure into two separate areas. I compile them into "app/generated/cljs" and "app/generated/clj". When I am messing around in clojure nrepl, or when I for instance run my "lein test!" alias (both pure clojure code) then everything is fine.

However, if I try to start up the (cljs-repl) and then go to a browser to compile the app for development, I get a funny error. It is clear that the cljs files are being used, however, it appears the that the macros files for the clojure world are being used instead of the macro files for the clojurescript world. Stated differently, when I :require-macro's from within a .cljs file, the macros used are the macros that were meant for the clojure world, not for the clojurescript world. Or, to just put it directly, the .cljs files, which are under "app/generated/cljs" are using the equivalently named and namespaced files under "app/generated/clj" for their macros.

The confusing matter is that I don't seem to have included "app/generated/clj" in my :source-paths, so I don't see how it is the case that the clojurescript compiler can even see "app/generated/clj".

As you might guess, I can easily fix the issue by removing the "app/generated/clj" directory before I attempt to use the clojurescript compiler. Then it finds the macros (which are .clj files) in "app/generated/cljs" and everything works fine.

Number 2:

When I run "lein clean; lein repl-headless" I don't seem to be able to find the expected files when compiling for cljs. However, if I run "lein clean; lein cljx once; lein repl-headless" everything works fine.

This would seem to have something to do with the classpath being checked and found missing before cljx had a chance to generate "app/generated/*" ? Just a guess.

Finally, I want to note that I am using pedestal, it is possible that these issues have nothing to do with cljx at all, I will ask there as well.

Stop using metadata notation

Hey @lynaghk (and whoever else). Following up on the spike of using sjacket (see the corresponding branch), a thought I'd like feedback on:

Since the Clojure reader isn't being used anymore, the e.g. ^:clj tags don't actually denote metadata. It seems that cljx should stop using them, and perhaps adopt feature expression-style (née Common Lisp-style) tags e.g. #+clj. sjacket currently parses these (properly) as reader literals, so matching and eliding/transforming their value portion is no more difficult than the ^:clj-style tags.

Along with an option to define the "features" that are to be turned on on a per-build basis, this would make cljx a fairly general-purpose s-expression preprocessor.

Thoughts?

Incorrect path when source-paths value is repeated

When source-paths value is present several times in the complete file path, all occurences are replaced by the value of output-path.

e.g.
with {:source-paths ["test"] :output-path "generated-test"}
path is generated-test/XX/generated-test/ instead of generated-test/XX/test/

Note this doesn't happen with branch sjacket.

Remove cljx dependencies from deployed code

I'm trying to set up cljx to build a multi-platform project with clj, cljs, jvm and android-device tags. For (admittedly quite an extreme) example

(defn debug-log [s] 
  (#+android-device Log/d #+jvm println #+cljs .log #+cljs js/console s))

and it looks like it should work for my purposes, however it seems that the plugin inserts a dependency in the runtime code on com.keminglabs/cljx which depends on piggieback which depends on clojurescript and rhino and clojure core, all of which cause conflicts with the android dependencies. For example the dexing process can only add one copy of each class, and I'm getting an "already added org/mozilla/classfile/ByteCode" which implies I have two copies of that dependency somewhere. It is also pulling in clojure core 1.5.1, when lein droid requires a special build of clojure.core.

Is there a way to reduce the dependency tree without taking away the ability to evaluate cljx at runtime via the repl, and how do I remove these dependencies completely for the release product?

0.5.0 release

Hi @lynaghk

I've settled master such that it's ready for an 0.5.0 release. All that remains is for you to:

  • lein do clean, deploy clojars
  • tweak the README to refer to 0.5.0

I pushed off the more ambitious stuff that was slated for 0.5.0 to 0.6.0 so that the pending :prep-tasks fix and cljx auto enhancement can get out there.

Thanks!

cljx not running

I think I've followed the instructions in the readme correctly, but when I run lein cljx once, I get the following error:

Exception in thread "main" java.lang.RuntimeException: Unable to resolve symbol: match in this context, compiling:(cljx/rules.clj:18)

Do you have any ideas?

Simplify configuration

Most of my projects using cljx end up with a configuration similar to:

  :source-paths ["src" "target/generated-src"]
  :test-paths ["test" "target/generated-test"]
  :cljsbuild {:builds [{:source-paths ["src" "target/generated-src"]}]}
  :cljx {:builds [{:source-paths ["src"]
                   :output-path "target/generated-src"
                   :rules :clj}
                  {:source-paths ["src"]
                   :output-path "target/generated-src"
                   :rules :cljs}
                  {:source-paths ["test"]
                   :output-path "target/generated-test"
                   :rules :clj}
                  {:source-paths  ["test"]
                   :output-path "target/generated-test"
                   :rules :cljs}]}

Note that the cljx configuration has some implications on source-paths, test-paths and cljsbuild.

Most of it could be deduced and injected at run time (by a leiningen plugin). The configuration could be simplified down to:

:cljx {:builds [{:source-paths ["src" "test"]
                 :output-path "target/generated-%"
                 :rules [:clj :cljs]}]}

This is similar to this proposition for clojurescript.test.

The whole configuration could be omitted with some default:

  • source-paths is the concatenation of source-paths and test-paths
  • output-path has some default
  • rules defaults to [:clj :cljs]

Now this is probably too much (and assumes cljx files are in the same directory structures than clj files, which I usually do).

Wrong test selector used with lein do clean, test

I've recently switched to @cemerick's 0.5.0-SNAPSHOT. version and using :prep-tasks [["cljx once"] "javac" "compile"]. When running the above lein command chain it does correctly generate cljx transforms, but the test command is then invoked for the 'user' ns only, even if I specify the :all test selector... running lein clean and lein TEST separately works fine though.

Exception when running lein install (sjacket branch)

This report concerns sjacket branch.

When running lein install with hooks defined I get the following exception:

Exception in thread "main" java.io.FileNotFoundException: Could not locate cljx/core__init.class or cljx/core.clj on classpath:
    at clojure.lang.RT.load(RT.java:443)
    at clojure.lang.RT.load(RT.java:411)
    at clojure.core$load$fn__5018.invoke(core.clj:5530)
    at clojure.core$load.doInvoke(core.clj:5529)
    at clojure.lang.RestFn.invoke(RestFn.java:408)
    at clojure.core$load_one.invoke(core.clj:5336)
    at clojure.core$load_lib$fn__4967.invoke(core.clj:5375)
    at clojure.core$load_lib.doInvoke(core.clj:5374)
    at clojure.lang.RestFn.applyTo(RestFn.java:142)
    at clojure.core$apply.invoke(core.clj:619)
    at clojure.core$load_libs.doInvoke(core.clj:5413)
    at clojure.lang.RestFn.applyTo(RestFn.java:137)
    at clojure.core$apply.invoke(core.clj:619)
    at clojure.core$require.doInvoke(core.clj:5496)
    at clojure.lang.RestFn.invoke(RestFn.java:408)
    at user$eval3.invoke(NO_SOURCE_FILE:1)
    at clojure.lang.Compiler.eval(Compiler.java:6619)
    at clojure.lang.Compiler.eval(Compiler.java:6608)
    at clojure.lang.Compiler.eval(Compiler.java:6582)
    at clojure.core$eval.invoke(core.clj:2852)
    at clojure.main$eval_opt.invoke(main.clj:308)
    at clojure.main$initialize.invoke(main.clj:327)
    at clojure.main$null_opt.invoke(main.clj:362)
    at clojure.main$main.doInvoke(main.clj:440)
    at clojure.lang.RestFn.invoke(RestFn.java:421)
    at clojure.lang.Var.invoke(Var.java:419)
    at clojure.lang.AFn.applyToHelper(AFn.java:163)
    at clojure.lang.Var.applyTo(Var.java:532)
    at clojure.main.main(main.java:37)

I can reproduce with data.generators after adding :hooks [cljx.hooks].

After removing the hooks definition it works perfectly. Also it works fine with the hook and master branch.

cljx as plugin causes version warning in lein

It looks like what happens is the plugin isn't aware of any exclusions it might so when it adds itself as a dep, no exclusions are copied over. When no exclusions are applied (org.clojure/clojure) to the plugin, you see two duplicate traces like so:

(WARNING!!! version ranges found for:)
([com.keminglabs/cljx "0.4.0"] -> [org.clojars.trptcolin/sjacket "0.1.0.6"] -> [org.clojure/clojure "[1.3.0,)"]
Consider using [com.keminglabs/cljx "0.4.0" :exclusions [org.clojure/clojure]].)
([com.keminglabs/cljx "0.4.0"] -> [org.clojars.trptcolin/sjacket "0.1.0.6"] -> [net.cgrand/regex "1.1.0"] -> [org.clojure/clojure "[1.2.0,)"]
Consider using [com.keminglabs/cljx "0.4.0" :exclusions [org.clojure/clojure]].)
([com.keminglabs/cljx "0.4.0"] -> [org.clojars.trptcolin/sjacket "0.1.0.6"] -> [net.cgrand/parsley "0.9.1"] -> [org.clojure/clojure "[1.2.0,)"]
Consider using [com.keminglabs/cljx "0.4.0" :exclusions [org.clojure/clojure]].)
([lein-gorilla "0.3.1"] -> [gorilla-repl "0.3.1"] -> [grimradical/clj-semver "0.2.0"] -> [org.clojure/clojure "[1.3.0,)"]
Consider using [lein-gorilla "0.3.1" :exclusions [org.clojure/clojure]].)
([com.keminglabs/cljx "0.4.0"] -> [org.clojars.trptcolin/sjacket "0.1.0.6"] -> [net.cgrand/parsley "0.9.1"] -> [net.cgrand/regex "1.1.0"] -> [org.clojure/clojure "[1.2.0,)"]
Consider using [com.keminglabs/cljx "0.4.0" :exclusions [org.clojure/clojure]].)
nil
(WARNING!!! version ranges found for:)
([com.keminglabs/cljx "0.4.0"] -> [org.clojars.trptcolin/sjacket "0.1.0.6"] -> [org.clojure/clojure "[1.3.0,)"]
Consider using [com.keminglabs/cljx "0.4.0" :exclusions [org.clojure/clojure]].)
([com.keminglabs/cljx "0.4.0"] -> [org.clojars.trptcolin/sjacket "0.1.0.6"] -> [net.cgrand/regex "1.1.0"] -> [org.clojure/clojure "[1.2.0,)"]
Consider using [com.keminglabs/cljx "0.4.0" :exclusions [org.clojure/clojure]].)
([com.keminglabs/cljx "0.4.0"] -> [org.clojars.trptcolin/sjacket "0.1.0.6"] -> [net.cgrand/parsley "0.9.1"] -> [org.clojure/clojure "[1.2.0,)"]
Consider using [com.keminglabs/cljx "0.4.0" :exclusions [org.clojure/clojure]].)  
([com.keminglabs/cljx "0.4.0"] -> [org.clojars.trptcolin/sjacket "0.1.0.6"] -> [net.cgrand/parsley "0.9.1"] -> [net.cgrand/regex "1.1.0"] -> [org.clojure/clojure "[1.2.0,)"]
Consider using [com.keminglabs/cljx "0.4.0" :exclusions [org.clojure/clojure]].)
nil

The workaround is to manually add the dep in profiles dev provide exclusion for it and add the piggieback repl option as well. not so bad, but it would be helpful if cljx plugin could take care of this since it affects all projects downstream - in fact it should probably exclude by default.

Edit: arg actually that doesn't solve it since you lose the cljx lein task.

nREPL support breaks with replaced function

When defining a function overriding another one part of clojure.core (e.g. get) an exception is thrown at call time. REPL is then unusable.

You can reproduce with the following snippet

(ns test
  (:refer-clojure :exclude [get]))

(defn ^:clj get [] ())

and then at REPL

(use 'test)
(get)

triggers the following exception:

ERROR: Unhandled REPL handler exception processing message {:code (get), :id ebbd0492-33c1-4842-909c-7d312b3bd754, :op eval, :session 4b9d1082-14b1-4e2b-9529-a1a52bbd13c0}
java.lang.IllegalStateException: get already refers to: #'test/get in namespace: user
    at clojure.lang.Namespace.warnOrFailOnReplace(Namespace.java:88)
    at clojure.lang.Namespace.reference(Namespace.java:110)
    at clojure.lang.Namespace.refer(Namespace.java:168)
    at clojure.core$refer.doInvoke(core.clj:3850)
    at clojure.lang.RestFn.invoke(RestFn.java:439)
    at kibit.check$careful_refer$fn__6011.invoke(check.clj:52)
    at kibit.check$careful_refer.invoke(check.clj:51)
    at kibit.check$read_file.invoke(check.clj:72)
    at kibit.check$fn__6029.invoke(check.clj:161)
    at kibit.check$check_reader.doInvoke(check.clj:219)
    at clojure.lang.RestFn.invoke(RestFn.java:559)
    at cljx.core$munge_forms.invoke(core.clj:64)
    at cljx.repl_middleware$munge_code.invoke(repl_middleware.clj:30)
    at cljx.repl_middleware$wrap_cljx$fn__6165.invoke(repl_middleware.clj:48)
    at clojure.tools.nrepl.middleware$wrap_conj_descriptor$fn__402.invoke(middleware.clj:17)
    at clojure.tools.nrepl.middleware$wrap_conj_descriptor$fn__402.invoke(middleware.clj:17)
    at clojure.tools.nrepl.middleware.session$session$fn__695.invoke(session.clj:192)
    at clojure.tools.nrepl.middleware$wrap_conj_descriptor$fn__402.invoke(middleware.clj:17)
    at clojure.tools.nrepl.server$handle_STAR_.invoke(server.clj:18)
    at clojure.tools.nrepl.server$handle$fn__757.invoke(server.clj:27)
    at clojure.core$binding_conveyor_fn$fn__4107.invoke(core.clj:1836)
    at clojure.lang.AFn.call(AFn.java:18)
    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334)
    at java.util.concurrent.FutureTask.run(FutureTask.java:166)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
    at java.lang.Thread.run(Thread.java:722)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.