When writing lein plugins you have to think about if they should do work in
lein's vm or the project's vm. In this case, since you want to load
namespaces from the project, the work will need to be done in the project's
vm.  This is where `leiningen.core.eval/eval-in-project` is used, to spin
up the project's vm and run forms in it.

The arguments to `l.c.e/eval-in-project` will be the project map, a clojure
form representing what to run, and a clojure form designed to allow
avoidance of the gilardi scenario. The big question here becomes how to
create the first form representing what to run.

Option 1: short syntax quote form + injecting dependency into project
Example: cljx
https://github.com/lynaghk/cljx/blob/master/src/leiningen/cljx.clj#L32 and
https://github.com/lynaghk/cljx/blob/master/src/leiningen/cljx.clj#L20
Disadvantages:

1. Requires injecting a dependency into the project (could also be ok if
the working code already exists in a seperate dep, marg vs lein-marg,
ring-server vs lein-ring, etc).
2. Needs a require for the dependency's helper namespace as part of gilardi
avoidance form.

Option 2: long syntax quote form
Example: leiningen.test
https://github.com/technomancy/leiningen/blob/master/src/leiningen/test.clj#L67
Disadvantages:

1. Have to think in syntax quote vs normal evaluation.
2. Needs a require for each namespace the form uses as part of the gilardi
avoidance form (could be ok if only 1 or 2 ns used).


I generally recommend option 1 as easier to think about, and I believe it
to be more common.

As for why `l.c.e/eval-in-project` was not found, I would hazard a guess
based on limited info that it was not `require`d first.

I'll plug
https://github.com/technomancy/leiningen/blob/master/doc/PLUGINS.md#code-evaluation
and https://www.youtube.com/watch?v=uXebQ7RkhKs as containing similar
information said in different ways, in case it comes across better there.

-
Nelson Morris


On Sun, Aug 31, 2014 at 4:02 PM, Timothy Washington <twash...@gmail.com>
wrote:

> Ok,
>
> So I'm trying to write a leiningen plugin that takes some namespace
> arguments. Let's call it *<myplugin>*. This is a brand new plugin, so
> everything else is empty, and this value is present: *{:eval-in-leiningen
> true}*. My problem happens when, in the context of the project
> *<myplugin>* is acting on, the plugin code fails. I pass in some
> project-local namespace that I want to eval (which is definitely present).
> And I get this situation:
>
> *Error*
>
> java.lang.Exception: No namespace: <mynamespace> found
>
>
> *Offending Code*
>
> (defn check-foreach-namespace [namespaces]
>
>
>   (let [fnss (filter #(= Fubar (type (var-get %)))
>
>                      (vals *(ns-publics (symbol (first namespaces)))*))]
>
>
>     (println "filtered-namespace [" fnss "]")))
>
>
> (defn myplugin [project & args]
>
>   (check-foreach-namespace args))
>
>
>
> So then, if I try to require the namespace being passed in, that too fails
> like so:
>
> *Error: *
>
> java.io.FileNotFoundException: Could not locate <mynamespace_file.clj> on
> classpath:
>
>
> *Offending Code:*
>
> (ns leiningen.chesk
>
>   (:require [clojure.test.check :as tc]
>
>             [clojure.test.check.generators :as gen]
>
>             [clojure.test.check.properties :as prop]))
>
>
> (defn check-foreach-namespace [namespaces]
>
>
>
>   (let [nss (map *#(require (symbol %))* namespaces)
>
>          fnss (filter #(= clojure.test.check.generators.Generator (type
> (var-get %)))
>
>                      (vals (ns-publics (symbol (first nss)))))]
>
>
>     (println "filtered-namespace [" fnss "]")))
>
>
> (defn myplugin [project & args]
>
>   (check-foreach-namespace args))
>
>
> Looking around, I thought I had found some relevant instruction on how to
> handle this gilardi scenario
> <https://github.com/technomancy/leiningen/blob/master/doc/PLUGINS.md#evaluating-in-project-context>.
> So I tried to use *eval-in-project* with and without namespace prefix,
> and with several permutations of quoting. This is the error that occurs.
>
> *Error: *
>
> clojure.lang.Compiler$CompilerException: java.lang.ClassNotFoundException:
> leiningen.core.eval
>
>
> *Offending Code: *
>
> (ns leiningen.chesk
>   (:require [clojure.test.check :as tc]
>             [clojure.test.check.generators :as gen]
>             [clojure.test.check.properties :as prop]))
>
> (defn check-foreach-namespace [namespaces]
>
>   (let [fnss (filter #(= clojure.test.check.generators.Generator (type
> (var-get %)))
>                      (vals (ns-publics (symbol (first namespaces)))))]
>
>     (println "filtered-namespace [" fnss "]")))
>
> (defn myplugin [project & args]
>   (*leiningen.core.eval/eval-in-project* project
>                                        (check-foreach-namespace args)
>                                        (map #(require (symbol %)) args)))
>
>
>
>
> So something that looks like it should be straightforward, is not working
> out as planned. I also can't quite see how other plugins are doing this.
> lein-midje seems a bit cryptic (see here
> <https://github.com/marick/lein-midje/blob/master/src/leiningen/midje.clj#L14-L23>
> and here
> <https://github.com/marick/Midje/blob/master/src/midje/repl.clj#L192-L235>).
> Are there any clearer examples?
>
>
> Tim Washington
> Interruptsoftware.com <http://interruptsoftware.com>
>
>  --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with
> your first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en
> ---
> You received this message because you are subscribed to the Google Groups
> "Clojure" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to clojure+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to