Awesome, thanks for the feedback. That all makes sense. And yes, the work will be done in the project's VM.
I guess what I'm missing is something more basic. If you look at lein-midje <https://github.com/marick/lein-midje/blob/master/src/leiningen/midje.clj#L168> or lein-spec <https://github.com/slagyr/speclj/blob/master/src/clj/leiningen/spec.clj#L41>, they're doing straightforward requires of *eval-in-project*. Yet, I'll get an error, even for a stripped down version. So take the below example. I'm locally installing the lein plugin, and running it from a separate project with "*lein chesk fubar*". Still an error loading eval-in-project. I looked through some other leiningen projects. None of them are bundling some leiningen core library. I'm sure it'll be a simple switch that'll make sense, once I figure it out. *error* $ lein chesk bkell.domain.user-check clojure.lang.Compiler$CompilerException: java.lang.RuntimeException: *Unable to resolve symbol: eval-in-project in this context, compiling:(leiningen/chesk.clj:16:3)* at clojure.lang.Compiler.analyze (Compiler.java:6464) clojure.lang.Compiler.analyze (Compiler.java:6406) clojure.lang.Compiler$InvokeExpr.parse (Compiler.java:3665) ... *project.clj * (defproject chesk "0.1.0-SNAPSHOT" :description "FIXME: write description" :url "http://example.com/FIXME" :license {:name "Eclipse Public License" :url "http://www.eclipse.org/legal/epl-v10.html"} :eval-in-leiningen true) *chesk.clj * (ns leiningen.chesk (:require [leiningen.core.eval :refer [eval-in-project]])) (defn check-foreach-namespace [] (println "sanity check")) (defn chesk [project & args] (eval-in-project project `(check-foreach-namespace) '())) Hmm Tim Washington Interruptsoftware.com <http://interruptsoftware.com> On Mon, Sep 1, 2014 at 10:27 AM, Nelson Morris <nmor...@nelsonmorris.net> wrote: > 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. > -- 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.