Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cider should inject its own dependencies/plugins automatically at cider-jack-in #1531

Closed
phillord opened this issue Jan 29, 2016 · 33 comments
Closed
Milestone

Comments

@phillord
Copy link
Contributor

Currently, cider complains when the dependencies are wrong in profile.clj. I understand the reasons for this, but it would be nice if Cider offered the ability to update your profile for you.

Another possibility would be for cider to check whether pomegranate is present and if not, inject the correct dependencies. Don't know if that is possible with plugins, but worth thinking about.

This would be great for me when I am switching Emacs' -- sometimes using melpa-stable, sometimes melpa normal. Then I have to continually re-edit my profile.clj. Painful.

@benedekfazekas
Copy link
Member

I've been thinking along the same lines (for clj-refactor as well) lately so +1

also we should be able to figure out if given setup uses lein or boot

@stardiviner
Copy link
Contributor

+1 for this, don't want to continuously monitor version change update.

@Malabarba
Copy link
Member

I mentioned this on slack. I'll be glad to provide this if lein (or boot) has a way to specify deps on the command line. Otherwise it would involve manually parsing the project.clj file in elisp, which is not something I'm super excited to do. =)

One thing that would be easier to do is to offer a "new project" command, which would create the project with the right deps. However, this wouldn't solve any of the complaints here.

@phillord
Copy link
Contributor Author

I've been thinking about it -- a "cider shim" plugin which pulls the middleware into the JVM with pomegranate really seems possible to me. It should be possible to write it once and rarely update it. I guess it needs to inject both into the repl and the leiningen JVM?

I've been watching a new colleague of mine trying to install cider, and this step really isn't nice.

@benedekfazekas
Copy link
Member

We do something like this in refactor-nrepl eg. add dependency to a running REPL. My worry is tho that these artifacts are not simple deps but nrepl middlewares there could be some extra steps to register them. No idea if this works dynamically.

@phillord
Copy link
Contributor Author

I think it works. Can someone give this a go: https://github.com/phillord/plugin-inject

You launch with lein plugin-inject repl :headless and it pushes the nrepl middleware plugin in first, then passes execution to repl task. End result, cider works despite there not being any cider middleware plugin around.

Might not work for anyone else, but seems a reasonable start. It's only a few lines of code.

@Malabarba
Copy link
Member

@phillord do you think it would be possible to specify the version of the cider middleware?

@phillord
Copy link
Contributor Author

Hmmm, think I've made a mistake. I had an old "cider-nrepl" dependency left in my .lein. So, it's not working. Try again.

I think more generally this is a leiningen issue -- if cider could specify it's own profile.clj which was merged with the users, this would solve the problem. A shim is a bit of a cheap plastic solution (bad pun).

@expez
Copy link
Member

expez commented Jan 30, 2016

It might be easier to just check if profiles.clj contains a matching version and if not offer to update the text specifying the version, before starting the repl at all. This would be far simpler than the proposed solutions so far.

I don't think we need more indirection (a shim) or any magic happening in the background (injecting the right stuff into a running repl).

@phillord
Copy link
Contributor Author

I don't think would help with the new install. I agree, the shim is rather complex. Having support in lein would be the easiest.

@benedekfazekas
Copy link
Member

this seems to be working for me:

lein update-in :plugins conj "[cider/cider-nrepl \"0.11.0-SNAPSHOT\"]" -- repl

@benedekfazekas
Copy link
Member

it seems to me that boot has even better support for this via their boot.repl/*default-dependencies* and boot.repl/*default-middleware* atoms, see details and 1a765793

@benedekfazekas
Copy link
Member

more on leiningen:

in fact it is doable even now with setting cider-lein-parameters:
(setq cider-lein-parameters "update-in :plugins conj \"[cider/cider-nrepl \\\"0.11.0-SNAPSHOT\\\"]\" -- repl")

so I guess we could introduce a variable listing all nrepl middleware plugins (so clj-refactor can add its own) and then update those in as plugins by default with perhaps an opt out config in case somebody wants to start up cider without this.

@Malabarba
Copy link
Member

lein update-in :plugins conj "[cider/cider-nrepl "0.11.0-SNAPSHOT"]" -- repl

Nice! If it's as simple as that, I'd like to start using this as soon as the next release.
I've set a milestone so that we at least give it a try and see if it's feasible.

@Malabarba Malabarba added this to the v0.11 milestone Jan 30, 2016
@phillord
Copy link
Contributor Author

It looks like so. I just removed my profile.clj, ran a clean emacs, installed cider, added this:

(setq cider-lein-parameters "update-in :plugins conj \"[cider/cider-nrepl \\\"0.10.2\\\"]\" -- update-in :dependencies conj \"[org.clojure/tools.nrepl \\\"0.2.12\\\"]\" -- repl :headless")

And started cider on a test clojure project. Bingo, all works.

The command line is a bit of a gobsmacker, and probably doesn't need to get displayed to the user, but that's just a matter of adding a new variable.

@benedekfazekas Thanks! I hadn't seen the update-in task.

@benedekfazekas
Copy link
Member

no worries. will try to have a look on boot as well. not sure we need to handle gradle

@phillord
Copy link
Contributor Author

Boot can be handled with a custom task -- like the "cider repl" task in the doc, but passing in version numbers as keys.

This has been a PITA ever since the middleware came in, so removing the hassle for new users is going to be a major contribution to useability. And it should cleanly update from version to version.

@benedekfazekas
Copy link
Member

after having a chat with @micha on slack it seems there is CLI way for boot too, something like:
boot -d asdf/qwer:1.2.3 repl -m asdf.qwer/middleware

@benedekfazekas benedekfazekas changed the title Cider should update dependencies/plugins automatically in profile.clj Cider should inject its own dependencies/plugins automatically at cider-jack-in Jan 30, 2016
@phillord
Copy link
Contributor Author

With boot, I put this into my boot.profile

(deftask cider "CIDER profile"
  [c cider-nrepl VAL str "The cider-nrepl version"
   t tools-nrepl VAL str "The tools-nrepl version"
   ]
  (require 'boot.repl)
  (swap! @(resolve 'boot.repl/*default-dependencies*)
         concat `[[org.clojure/tools.nrepl ~(:tools-nrepl *opts*)]
                  [cider/cider-nrepl ~(:cider-nrepl *opts*)]])
  (swap! @(resolve 'boot.repl/*default-middleware*)
         concat '[cider.nrepl/cider-middleware])
  identity)

Added this into a clean emacs, with cider installed.

 (setq cider-boot-parameters "cider -c \"0.10.2\" -t \"0.2.1\" repl -s wait" )

Loaded a new project, and it works.

It could be made more generic still, I guess --- have a task which loads a file inside CIDER which defines the task -- which would secure against any changes in boot or if more middlewares are needed.

I'm very happy! I rather not regret putting this up as an issue a while back now, as the problem to have been solved more straight-forwardly than I would have guessed.

@benedekfazekas
Copy link
Member

yup this is nice but we still need the user to define this task or hide it somewhere in the elisp code of cider or something. would be even nicer to:
(setq cider-boot-parameters "-d cider/cider-nrepl:0.10.2 -m cider.nrepl/cider-middleware repl -s wait" )
which should be possible (have not tested it yet)

@Malabarba
Copy link
Member

INdeed, if we have to tell users to define that task, then we haven't gained much on the boot front. It'd be nicer to do it all directly.

@benedekfazekas
Copy link
Member

the boot guys discussing the scenario when you connect to a running repl process which apparently is how quite a few ppl prefer to work even with emacs (instead of jack-in). for that case finding a way to add the middleware at run time would still have good value. but I suppose solving this at start up for the jack-in use case is much higher priority

@phillord
Copy link
Contributor Author

@Malabarba with that task you would at least have gained version independence, so it would be worth documenting anyway. So long as cider's dependency requirements are accessible from lisp, then it can be made to work anyway of course.

Still, agree it's suboptimal. Surprised to find boot doesn't have an "eval" or "load-file" task, a la emacs --batch. Would solve the problem

@Malabarba
Copy link
Member

the scenario when you connect to an running repl process which apparently is how quite a few ppl prefer to work

I think that's a slightly more advanced task, so people who understand how that works should have no problems following the readme.
Of course, it would be nice to make that fully automated, but I'm less concerned with it because of the above (and because I think it would be moderately harder to do).

with that task you would at least have gained version independence, so it would be worth documenting anyway.

True. If there's no better alternative, we should document it. 👍

@phillord
Copy link
Contributor Author

@benedekfazekas if you are already talking to the boot guys, want to ask whether they will add a eval or load-file task? It's generic, totally future proof and, sometimes, only lambda is enough:-)

@benedekfazekas
Copy link
Member

@phillord why would that be beneficial? It seems that we can do the same (or very similar) with boot on the CLI as with lein at start up time -- see my comment above. So the ux would be the same for both lein and boot when jacking in without any extra config done by the user.

Btw thanks a lot for raising this!

@phillord
Copy link
Contributor Author

@benedekfazekas Oh, I couldn't get that to work; sorry, should have said. Is there a -m option command line option?

@benedekfazekas
Copy link
Member

There is, yes, for the repl task. So you will only see it if you run help for the repl task. Will have a play with it when I have a little time.

@phillord
Copy link
Contributor Author

@benedekfazekas Right you are.

(setq cider-boot-parameters
  "-d cider/cider-nrepl:0.10.2 -d org.clojure/tools.nrepl:0.2.12 repl -m cider.nrepl/cider-middleware -s wait")

This seems to do the trick on a clean emacs.

@benedekfazekas
Copy link
Member

Awesome 👍 thx for figuring it out

@benedekfazekas
Copy link
Member

i might try to put together a PR for this tmrw if nobody else is already working on it in anger. let me know

@phillord
Copy link
Contributor Author

phillord commented Feb 1, 2016

I am not at the moment, and will not get to it for tomorrow or the next few days, so please go ahead.

@Malabarba
Copy link
Member

I'm also not working on it. Feel free to go ahead.

benedekfazekas added a commit to benedekfazekas/cider that referenced this issue Feb 2, 2016
[wip] so users don't have to fiddle with profiles.clj and the like, see
details in clojure-emacs#1531

supports leiningen and boot
benedekfazekas added a commit to benedekfazekas/cider that referenced this issue Feb 9, 2016
[wip] so users don't have to fiddle with profiles.clj and the like, see
details in clojure-emacs#1531

supports leiningen and boot
benedekfazekas added a commit to benedekfazekas/cider that referenced this issue Feb 9, 2016
So users don't have to fiddle with profiles.clj and the like, see
details in clojure-emacs#1531 Supports both leiningen and boot. Additionally there is
a defcustom `cider-skip-repl-dependencies-at-jack-in` to switch this
functionality off (defaults to nil); and an extension point
defun (`cider-add-repl-dependencies`) so other tools like clj-refactor
can inject to their own dependencies, middlewares

Fix clojure-emacs#1531 and clojure-emacs#1534
benedekfazekas added a commit to benedekfazekas/cider that referenced this issue Feb 9, 2016
So users don't have to fiddle with profiles.clj and the like, see
details in clojure-emacs#1531 Supports both leiningen and boot. Additionally there is
a defcustom `cider-inject-dependencies-at-jack-in` to control this
functionality (defaults to t); and an extension point
(`cider-add-repl-dependencies`) so other tools like clj-refactor
can inject to their own dependencies, middlewares.

Fix clojure-emacs#1531 and clojure-emacs#1534
benedekfazekas added a commit to benedekfazekas/cider that referenced this issue Feb 11, 2016
So users don't have to fiddle with profiles.clj and the like, see
details in clojure-emacs#1531 Supports both leiningen and boot. Additionally there is
a defcustom `cider-inject-dependencies-at-jack-in` to control this
functionality (defaults to t); other tools (like clj-refactor) can
modify `cider-jack-in-dependencies`, `cider-jack-in-lein-plugins` and
`cider-jack-in-nrepl-middlewares` to inject their own dependencies.

Fix clojure-emacs#1531, clojure-emacs#1534
benedekfazekas added a commit to benedekfazekas/cider that referenced this issue Feb 12, 2016
So users don't have to fiddle with profiles.clj and the like, see
details in clojure-emacs#1531 Supports both leiningen and boot. Additionally there is
a defcustom `cider-inject-dependencies-at-jack-in` to control this
functionality (defaults to t); other tools (like clj-refactor) can
modify `cider-jack-in-dependencies`, `cider-jack-in-lein-plugins` and
`cider-jack-in-nrepl-middlewares` to inject their own dependencies.

Fix clojure-emacs#1531, clojure-emacs#1534
benedekfazekas added a commit to benedekfazekas/cider that referenced this issue Feb 13, 2016
So users don't have to fiddle with profiles.clj and the like, see
details in clojure-emacs#1531 Supports both leiningen and boot. Additionally there is
a defcustom `cider-inject-dependencies-at-jack-in` to control this
functionality (defaults to t); other tools (like clj-refactor) can
modify `cider-jack-in-dependencies`, `cider-jack-in-lein-plugins` and
`cider-jack-in-nrepl-middlewares` to inject their own dependencies.

Fix clojure-emacs#1531, clojure-emacs#1534
benedekfazekas added a commit to benedekfazekas/cider that referenced this issue Feb 13, 2016
So users don't have to fiddle with profiles.clj and the like, see
details in clojure-emacs#1531 Supports both leiningen and boot. Additionally there is
a defcustom `cider-inject-dependencies-at-jack-in` to control this
functionality (defaults to t); other tools (like clj-refactor) can
modify `cider-jack-in-dependencies`, `cider-jack-in-lein-plugins` and
`cider-jack-in-nrepl-middlewares` to inject their own dependencies.

Fix clojure-emacs#1531, clojure-emacs#1534
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants