Following on from a thread in #calva I'd be interested in having more nREPL ops processed via the Portal middleware -- more than just eval -- and I've messed with the portal.nrepl code (re-eval'ing changes into a running setup) but don't seem to be picking up a number of ops that I believe Calva is sending... this is really my first foray into nREPL middleware exploration so I'm not sure what to do to debug this... I updated wrap-portal* to tap> every (:op msg) and I'm seeing eval and clojuredocs-lookup but not others...
@seancorfield Okay, I think the solution I'm preferring currently is https://github.com/djblue/portal/pull/197 and https://github.com/djblue/cider-nrepl/commit/fcf5cce08123aab382a05aa17018ae14c6958edf. It's a minimal change on both ends and provides exactly the same info as the current test reporting.
It's still a POC as there are more ops to intercept and test I think, but the main pieces are there 👌
(requiring-resolve `cider.nrepl.middleware.test/report)
will throw an exception if the CIDER middleware is not on the classpath.Yeah, definitely need to change some bits
I've never seen :dynamic true on a defmulti -- and I don't see binding in your code... what am I missing?
Yeah, me neither but that's how https://github.com/clojure/clojure/blob/master/src/clj/clojure/test.clj#L324-L333 does it. The "binding" is the https://github.com/djblue/portal/pull/197/files#diff-f1a2573c99264defd9491ef2d622ab48536e2bf6f9ccbc17a88838f174e25d6cR118. Nrepl middleware always feels a little awkward/ different from normal clojure code
Weird. Hopefully vemv will be more amenable to that tiny change 🙂
(I assume it doesn't work without that dynamic tweak)
Yeah, I tried using with-redefs, but no dice. Not sure what the control flow is for the middleware 🤔
https://github.com/djblue/portal/commit/522b6c6b62f32379831248d25dfb23715614d70a is my with-redefs attempt.
index 503149e..fc1381f 100644
--- a/src/portal/nrepl.clj
+++ b/src/portal/nrepl.clj
@@ -60,6 +60,7 @@
(transport/recv transport timeout))
(send [_this msg]
(transport/send transport msg)
+ (tap> [(:op handler-msg) msg])
(when (and (seq (p/sessions)) (:file handler-msg))
(when-let [out (:out msg)]
(swap! (:stdio handler-msg) conj {:tag :out :val out}))
@@ -97,7 +98,7 @@
(test-report value))]
(handler
(cond-> msg
- (= (:op msg) "eval")
+ (#{"test-var-query" "eval"} (:op msg))
(-> (update :transport
->PortalTransport
(assoc msg
This worked for me locallyI think capturing the test output might involve looking through https://github.com/clojure-emacs/cider-nrepl/blob/master/src/cider/nrepl/middleware/test.clj and figuring out how it's capturing the test output
["test-var-query"
{"elapsed-time" {"ms" 3, "humanized" "Completed in 3 ms"},
"gen-input" nil,
"results"
{"portal.runtime.npm-test"
{"invalid-modules"
({"type" "pass",
"message" "",
"ns" "portal.runtime.npm-test",
"var" "invalid-modules",
"index" 0,
"context" nil,
"elapsed-time" {"ms" 1, "humanized" "Completed in 1 ms"}}),
"valid-modules"
({"type" "pass",
"message" "",
"ns" "portal.runtime.npm-test",
"var" "valid-modules",
"index" 0,
"context" nil}
{"type" "pass",
"message" "",
"ns" "portal.runtime.npm-test",
"var" "valid-modules",
"index" 1,
"context" nil}
{"type" "pass",
"message" "",
"ns" "portal.runtime.npm-test",
"var" "valid-modules",
"index" 2,
"context" nil})}},
"summary" {"ns" 1, "var" 2, "test" 4, "pass" 4, "fail" 0, "error" 0},
"ns-elapsed-time"
{"portal.runtime.npm-test"
{"ms" 3, "humanized" "Completed in 3 ms"}},
:id "794",
"var-elapsed-time"
{"portal.runtime.npm-test"
{"invalid-modules"
{"elapsed-time" {"ms" 1, "humanized" "Completed in 1 ms"}},
"valid-modules"
{"elapsed-time" {"ms" 1, "humanized" "Completed in 1 ms"}}}},
"testing-ns" "portal.runtime.npm-test",
:session "74cf2aee-9375-4b48-a084-59184e2b76c2"}]
The test output from the nrepl op looks something like ☝️Which isn't quite what portal is expecting, so we can't use it directly. Portal expects raw clojure.test/report data.
Ideally, the cider.nrepl.middleware.test middleware would re-proxy the test report messages so the portal.nrepl middleware could capture it directly without even knowing about it 🤔
Weirdly, I'm not even seeing the test-var-query op flowing through...
That's odd 🤔 Might be an ordering issues as well
I tested the proxy stuff and it works, gonna put up a PR in a bit
I tried to prep Portal and got this failure:
=> npm ci
npm ERR! Cannot read property '@fortawesome/fontawesome-svg-core' of undefined
npm ERR! A complete log of this run can be found in:
npm ERR! /home/sean/.npm/_logs/2023-10-02T20_06_39_635Z-debug.log
-> 0.290 seconds (exit: 1)
Execution error (ExceptionInfo) at tasks.tools/sh* (tools.clj:58).
Non-zero exit code: npm ciAh, looks like I needed to run npm install in the Portal project first -- you need to make that part of the prep-lib step I think?
Okay, my dynamic attempts at eval'ing nrepl.clj into a running setup didn't work, but having a properly-prepped local dep does work...
LMK if/how I can help/test this stuff...
For the workflow I have with my custom snippets, having the Portal m/w use "summary" as the "result" would be "sufficient" but I leave it up to you want would be "ideal" from your p.o.v. for test integration.
https://github.com/clojure-emacs/cider-nrepl/pull/822 is the change we need on the nrepl side
Will get the portal.nrepl side done later 👌
I suspect you might get pushback on that...?
(but it does seem reasonable -- a lot of test reporters seem to assume they're the only one in the game which makes them non-composable)
I think vemv is open to it
His response to the PR suggests otherwise but I've added an explanatory note to it 🙂
I think I took reasonable as meaning open to it 😂
It'll take a while for it to filter through into a usable version for Calva... I'll see what could be done on the Portal side to improve integration in the short term, if that's okay with you?
Since cider-nrepl is part of your repl classpath, I think you could pull it in via git deps 🤔
Calva adds the CIDER dep as part of jack-in.
Ohh, and jack-in is part of your workflow 👌 Does calva allow customizing middleware?
Actually, now I think about it... maybe I already have this customized locally...
...hmm I use an alias to bring in additional stuff but Calva supplies cider/nrepl...
Time to hit them with :override-deps 🔥
cider-nrepl relies on a bunch of Leiningen plugin weirdness for adding/inlining a whole bunch of deps so that just doesn't work: https://github.com/clojure-emacs/cider-nrepl/blob/master/project.clj#L10-L26
(it uses mranderson to rename all those deps inline so you don't have conflicts -- and that's a lot of deps)
I added this to PortalTransport send:
(when-let [summary (when (= "test-var-query" (:op handler-msg))
(get msg "summary"))]
(when-let [ns (first (keys (get msg "results")))]
(tap> (assoc summary "ns" ns))))
which at least displays the test summary via tap> which is sufficient for my workflow for now... but it's ugly and doesn't match how the regular nREPL results get handled. But the benefit of Calva's integration with the test explorer are enough to make this subpar experience useful for now.