cloverage / cloverage

Clojure test coverage tool
Eclipse Public License 2.0
503 stars 99 forks source link

lein-cloverage 1.1.2 throws NullPointerException instrumenting a leiningen plugin #261

Open gonewest818 opened 4 years ago

gonewest818 commented 4 years ago

To reproduce:

  1. create a new leiningen plugin project
  2. add [lein-cloverage "1.1.2"] as a plugin
  3. lein cloverage to see the null pointer exception
  4. revert to [lein-cloverage "1.1.1"]
  5. lein cloverage yields normal output, no exception

I looked at the history, and it seems to me the likely culprit is 8adb81c568a36031be9ed156e1da8d32985c4968 which is the main substantive change to lein-cloverage between 1.1.1 and 1.1.2. That commit is trying to pick up reader tags from data_readers.clj before commencing instrumentation. I'm not really following exactly, but seems plausible the code in that commit is running at the wrong time.

Here's a transcript of the repro steps:

$ lein version
Leiningen 2.9.1 on Java 1.8.0_231 Java HotSpot(TM) 64-Bit Server VM
$ lein new plugin foo
$ cd foo
$ rm project.clj
$ cat > project.clj << END
(defproject foo "0.1.0-SNAPSHOT"
  :description "FIXME: write description"
  :url "http://example.com/FIXME"
  :license {:name "EPL-2.0 OR GPL-2.0-or-later WITH Classpath-exception-2.0"
            :url "https://www.eclipse.org/legal/epl-2.0/"}
  :eval-in-leiningen true
  :dependencies [[org.clojure/clojure "1.9.0"]]
  :plugins [[lein-cloverage "1.1.2"]])
END
$ lein cloverage
WARNING: reader-conditional already refers to: #'clojure.core/reader-conditional in namespace: clojure.tools.reader.impl.utils, being replaced by: #'clojure.tools.reader.impl.utils/reader-conditional
WARNING: tagged-literal already refers to: #'clojure.core/tagged-literal in namespace: clojure.tools.reader.impl.utils, being replaced by: #'clojure.tools.reader.impl.utils/tagged-literal
java.lang.NullPointerException: null
 at user$eval3298.invokeStatic (NO_SOURCE_FILE:0)
    user$eval3298.invoke (NO_SOURCE_FILE:-1)
    clojure.lang.Compiler.eval (Compiler.java:7176)
    clojure.lang.Compiler.eval (Compiler.java:7166)
    clojure.lang.Compiler.eval (Compiler.java:7131)
    clojure.core$eval.invokeStatic (core.clj:3214)
    clojure.core$eval.invoke (core.clj:3210)
    leiningen.core.eval$fn__6411.invokeStatic (eval.clj:343)
    leiningen.core.eval/fn (eval.clj:333)
    clojure.lang.MultiFn.invoke (MultiFn.java:234)
    leiningen.core.eval$eval_in_project.invokeStatic (eval.clj:367)
    leiningen.core.eval$eval_in_project.invoke (eval.clj:357)
    leiningen.cloverage$cloverage.invokeStatic (cloverage.clj:32)
    leiningen.cloverage$cloverage.doInvoke (cloverage.clj:14)
    clojure.lang.RestFn.invoke (RestFn.java:410)
    clojure.lang.AFn.applyToHelper (AFn.java:154)
    clojure.lang.RestFn.applyTo (RestFn.java:132)
    clojure.lang.Var.applyTo (Var.java:705)
    clojure.core$apply.invokeStatic (core.clj:667)
    clojure.core$apply.invoke (core.clj:660)
    leiningen.core.main$partial_task$fn__6592.doInvoke (main.clj:284)
    clojure.lang.RestFn.invoke (RestFn.java:410)
    clojure.lang.AFn.applyToHelper (AFn.java:154)
    clojure.lang.RestFn.applyTo (RestFn.java:132)
    clojure.lang.AFunction$1.doInvoke (AFunction.java:31)
    clojure.lang.RestFn.applyTo (RestFn.java:137)
    clojure.core$apply.invokeStatic (core.clj:667)
    clojure.core$apply.invoke (core.clj:660)
    leiningen.core.main$apply_task.invokeStatic (main.clj:334)
    leiningen.core.main$apply_task.invoke (main.clj:320)
    leiningen.core.main$resolve_and_apply.invokeStatic (main.clj:343)
    leiningen.core.main$resolve_and_apply.invoke (main.clj:336)
    leiningen.core.main$_main$fn__6681.invoke (main.clj:452)
    leiningen.core.main$_main.invokeStatic (main.clj:442)
    leiningen.core.main$_main.doInvoke (main.clj:439)
    clojure.lang.RestFn.applyTo (RestFn.java:137)
    clojure.lang.Var.applyTo (Var.java:705)
    clojure.core$apply.invokeStatic (core.clj:665)
    clojure.main$main_opt.invokeStatic (main.clj:491)
    clojure.main$main_opt.invoke (main.clj:487)
    clojure.main$main.invokeStatic (main.clj:598)
    clojure.main$main.doInvoke (main.clj:561)
    clojure.lang.RestFn.applyTo (RestFn.java:137)
    clojure.lang.Var.applyTo (Var.java:705)
    clojure.main.main (main.java:37)
$ 
lvh commented 4 years ago

Looks like the biggest difference is :eval-in-leiningen true. Does the error go away if you turn that off?

gonewest818 commented 4 years ago

Yes. In the repro I posted above, the error goes away if you turn off :eval-in-leiningen true.