calva

mikejcusack 2025-10-13T04:00:39.751009Z

Hey folks. I am tinkering around with using git deps in deps.edn instead of maven. I noticed that if there is a git dep inside of an alias the jack-in will fail saying that the lib needs to be prepared first. Looking into this I found that doing clj -X:deps prepare :aliases '[:dev]' in a terminal before running the jack-in does work. How would I go about doing this from within Calva so that this doesn't need to be a manual step?

mikejcusack 2025-10-13T07:27:51.709829Z

Also wouldn't it make sense for Calva to do this automatically given that it's required to use git deps? Various resources are encouraging the use of git deps over maven yet this extra step causes some friction in using them.

mikejcusack 2025-10-13T07:29:58.983109Z

Needing to manually run the prep command on the CLI or needing to figure out how to do it in a custom connect sequence seems like unnecessary friction. It seems like it could include any aliases provided by cljAliases and if nothing needs to be prepared at the time it's a no-op.

pez 2025-10-13T07:53:43.213209Z

We should consider supporting this. However, I wonder how big the use case it… I was completely unaware about it and have never had to prepare anything when using git deps. Until we have support (if we go that way) A custom Jack-in command line is probably the best option: > Custom command lines are there to bridge the gap to those situations where standard Jack-in command lines don’t reach But I am not sure, since I don’t know anything about what prepping even means. Where do I read about it?

mikejcusack 2025-10-13T07:59:08.101949Z

Unfortunately the official resource is pretty brief about it: https://clojure.org/guides/deps_and_cli#prep_libs

mikejcusack 2025-10-13T07:59:16.948619Z

The dep in question is djblue/portal

mikejcusack 2025-10-13T08:00:26.965719Z

I've never done a custom jack-in command so not sure what it would look like. The examples on your page don't seem to be relevant to this use case and I don't see what the default command would be

mikejcusack 2025-10-13T08:01:35.190379Z

https://github.com/djblue/portal/blob/e376ac4469bded3fb2797b723fb06e9548ccf005/deps.edn#L8 defines what the prep command should target

pez 2025-10-13T08:10:19.314819Z

I’m not sure if it is relevant to the use-case, but a way you can use custom command lines is to first use the Calva: Copy Jack-in command-line to the clipboard and then add the prep stuff to it and use the result as your custom Jack-in command line.

mikejcusack 2025-10-13T08:10:52.829789Z

Thanks, I'll check that out

pez 2025-10-13T08:13:41.313429Z

Thanks for the config examples. Clears things up slightly, but there must be somewhere this is elaborated on a tad, 😃

👍 1
mikejcusack 2025-10-13T08:13:48.360899Z

Hmm, so the default command has some hardcoded deps in it. That would mean needing to know if those versions should be updated later on or not. Seems like running the command in the CLI would be more simple.

mikejcusack 2025-10-13T08:14:21.980429Z

Luckily it only needs to be run when dependencies are first used or updated and not something needed every time it's run

mikejcusack 2025-10-13T08:15:25.990809Z

> Clears things up slightly, but there must be somewhere this is elaborated on a tad, Ah, the classic Clojure issue of being more difficult to find info on specific things 😉

mikejcusack 2025-10-13T08:16:50.115919Z

I can definitely still use the maven dep in the meantime since that works out of the box. I was just exploring this since I've seen multiple places encourage using git deps to remove the unnecessary middleman of Maven/Clojars

mikejcusack 2025-10-13T08:18:24.470099Z

It's neat to be able to just point to a sha and clone instead of needing to worry about a jar being published for it, especially if you wanted to use a specific commit for a particular reason or if there was a need to fork the original dep and apply something specific without needing to wait on the original source to accept a PR.

pez 2025-10-13T08:20:43.494349Z

> the default command has some hardcoded deps in it There command line can use placeholders for those and get whatever Calva uses injected. FYI, But it would run on every jack-in, so if that is expensive in some ways, it is not the right way to solve the prep.

pez 2025-10-13T08:21:15.905599Z

Totally agree about the neatness of git deps. I use them all the time!

mikejcusack 2025-10-13T08:21:20.595469Z

If nothing needs to be prepped or is already prepped it doesn't do anything

mikejcusack 2025-10-13T08:23:08.211559Z

djblue/portal was the first dep I was testing out so not sure how many (if any) of my other deps need preparing.

pez 2025-10-13T08:23:32.295749Z

Portal is a whole tool, so may be a special case.

mikejcusack 2025-10-13T08:23:41.470599Z

That would make sense

mikejcusack 2025-10-13T08:24:37.513809Z

Actually seems like it would be better if it was a Clojure tool so it could be handled differently

pez 2025-10-13T08:25:16.868379Z

Anyway, it looks like we could introduce a setting for gitDepsAlises and if that is set we augment the jack-in command line with that.

pez 2025-10-13T08:26:18.813069Z

Or add a command for it. Issue welcome. We can discuss how to actually solve it there.

mikejcusack 2025-10-13T08:26:57.788419Z

Sure

mikejcusack 2025-10-13T08:37:01.301859Z

https://github.com/BetterThanTomorrow/calva/issues/2950

mikejcusack 2025-10-13T08:39:55.500079Z

Btw not sure if https://github.com/BetterThanTomorrow/calva/issues/2911 slipped through the cracks from a couple months ago.

pez 2025-10-13T08:47:04.433879Z

Yeah, I remember seeing that on my phone, and then forgot to follow up. I am notoriously bad at keeping track of these things. May need to whip up some Joyride script to help me. 😃

mikejcusack 2025-10-13T08:47:46.569479Z

Haha, no worries

seancorfield 2025-10-13T13:31:39.130069Z

> djblue/portal was the first dep I was testing out so not sure how many (if any) of my other deps need preparing. @mike.j.cusack It's pretty rare. I think I've only run across a couple of git deps that need that step -- and it only needs it once for a given version -- you don't need it every time you jack-in -- so this isn't really a Calva issue: you should just do it manually, once (unless you change the Portal dep version).

mikejcusack 2025-10-13T13:56:44.728159Z

@seancorfield I already stated that above. It's not a Calva issue, but the mission of Calva, per pez, is to make it simple and easy for people to write Clojure (and flavors of) programs so this is something that Calva could support to that goal. I actually keep my deps updated consistently so depending on how often the particular dep is updated it could be happening often. Also already stated is that the command will be a no-op if there is nothing needed for the current dep versions so it wouldn't cause any extra work when jacking in for that case.

mikejcusack 2025-10-13T14:03:25.341349Z

For someone that has worked in Clojure for a long time, such as yourself, it wouldn't be a big deal to do it manually every time the dep(s) is(are) updated, but for many other people it would be helpful to at least have a command in Calva to help with it, as pez mentioned. My interest is for any user of Calva and not just myself.

pez 2025-10-13T15:19:55.464619Z

It’s not clear that support in Calva would make this simpler. Maybe easier, but that’s just a a maybe. You would still need to know that this needs to be done and to configure the prep, now in two places. And we risk misleading people into thinking it is a repl start business (if we implement as a jack-in config, so maybe that tells us that we shouldn’t?). Could be that a way to help with this is to have something in the Calva docs that summarize what we know about it so far. Know that we know that the issue exists.

seancorfield 2025-10-13T15:30:05.197749Z

It is certainly complicated by the use of aliases. The official docs only show the basic prep command -- the use of :aliases isn't shown anywhere in the docs -- hence my blog post going into more details. The prep-lib error message only lists the library (group/artifact), not the alias it came in under. If you're working with Polylith, it will most likely need :aliases '[:dev]' as the OP showed but sometimes it's a test-only deps and then you need the :test alias listed -- so the user has to decide which aliases, if any, are needed for prep. Even if Calva handled this, configuration of those aliases, if any, would be required in Calva per-project, and then Calva would need to run two commands to jack-in and fail if the prep command fails for any reason (and make all that output easily available for debugging). And that would have to work cross-platform (oh boy, Windows).

seancorfield 2025-10-13T15:39:05.777379Z

(and, as I noted, the use of :deps/prep-lib is fairly rare so this is quite the edge case -- esp. since the usual use of Portal is via Maven coords, on Clojars, rather than git deps) For a while, LazyTest required prep when used as a git dep -- I had to add this to next.jdbc's CI (GitHub Actions) since that could start with a fresh git dep and there was a Java class that needed compiling -- but if you use LazyTest via :mvn/version you don't need this. I would say that "most" Calva users will use the Maven coords for libraries that are deployed to Clojars (so prep is not needed), making this even more of an edge case?

2025-10-13T20:33:04.760439Z

need to "prep" cannot be that rare. Every "mixed" Clojure / Java project with "git coordinates" needs this. (as the Java code needed to be compiled)

seancorfield 2025-10-13T20:43:19.778859Z

Mixed Clojure / Java projects that declare :deps/prep-lib are fairly rare. Folks are still compiling the Java as part of their build and deploying JARs to Clojars containing .class files. Certain sectors/verticals might use Java classes more than other and maybe certain subsectors rely more on git deps, but I'll still assert that's pretty rare overall.

seancorfield 2025-10-13T20:46:08.399869Z

Whether prep will become more common over time, I don't know. One of the issues with git deps is they are "infectious" -- a library that uses them cannot publish to Clojars, it can only "publish" as git deps itself -- and there's still pressure to play nice with lein or some other non-`deps.edn` projects which leads to Maven versions on Clojars (see tools.build, for example, which started producing Maven versions because folks wanted to use it with lein etc).

seancorfield 2025-10-13T20:59:10.434649Z

https://github.com/search?q=deps%2Fprep-lib+language%3Aedn&type=code&l=edn shows 179 EDN files containing :deps/prep-lib -- there are close to 20k deps.edn files on GitHub apparently.

mikejcusack 2025-10-14T05:12:41.852459Z

I think it's pretty clear why there wouldn't be many with a prep step given that git deps are still relatively "new" and the tendency of veteran Clojure developers to continue using very old things, because "it still works", especially given that Clojure makes a point to maintain backwards compatibility. I think that's an overall good thing and should not change by all means, but it seems to lend itself to issues like this.

mikejcusack 2025-10-14T05:14:05.105379Z

There's been a lot of work towards improving the Clojure tooling, but it seems it still remains a major pain point for many people. To me it's awkward to introduce such new features, but then have some not-so-obvious gotchas that are poorly explained in the official docs, as Sean mentioned.

mikejcusack 2025-10-14T05:15:57.188079Z

Personally I don't see the issue with adding it to the jack-in, given particular configuration, because the jack-in will absolutely fail if using git deps that require preparing and haven't been prepared yet.

mikejcusack 2025-10-14T05:17:45.647879Z

Another potential solution here would be to add a pre-jack-in command configuration that one could then at least add the appropriate prepare command if using those deps. Calva currently has support for post-jack-in, but I don't see anything for pre.

mikejcusack 2025-10-14T05:22:34.556249Z

I've been programming for almost 20 years and it took me quite a while digging to figure out what the appropriate command for it being in an alias would be so I can only imagine what a beginner would experience after seeing some resource encourage the use of git deps and then not be able to start a repl.

pez 2025-10-14T06:45:57.703719Z

To me it looks a bit too complicated for Calva to nail it with some config and/or commands. As about 95% of the considerable work with Jack-in has been about Windows quirks, I’m not keen on piling up more of that kind of work. Seems best to try help with understanding the problem, and to quickly find the most probable remedy (`clojure -X:deps prep :aliases '[:dev :test]'`). So a mention in Calva docs, seems like it would help. We can link to the prep section of @seancorfield’s https://corfield.org/blog/2025/08/08/deps/#prep was a great read for me, but was a bit hard to find, from the error message. We could also consider recognizing the error message at jack-in and link to the blog post.

mikejcusack 2025-10-14T06:53:35.381949Z

What would be the issue with providing a Calva command that takes an optional list of aliases to run said command?

mikejcusack 2025-10-14T06:53:55.340259Z

Or the pre-jack-in command I suggested?

pez 2025-10-13T06:01:07.065479Z

A custom command line could do it, I think. https://calva.io/connect-sequences/#custom-command-line

mikejcusack 2025-10-13T06:51:06.400809Z

This is what I have currently. What would need to be added/changed?

"calva.replConnectSequences": [
        {
            "autoSelectForJackIn": true,
            "name": "Auto-connect",
            "menuSelections": {
                "cljAliases": [
                    "dev"
                ]
            },
            "projectRootPath": [
                "."
            ],
            "projectType": "deps.edn"
        }
    ]

mikejcusack 2025-10-13T06:51:44.898489Z

dev is the alias that would contain the git dep

pez 2025-10-14T07:02:13.577809Z

There is a lot of work with maintaining features. They need to carry their weight for me to be prepared to shoulder the burden they add.

mikejcusack 2025-10-14T07:04:07.542949Z

So there are no other use cases of wanting to run a command before jacking in?

pez 2025-10-14T07:10:04.750659Z

Oh, yes, there are lots of use cases. It’s a different question than helping with prep, though.

mikejcusack 2025-10-14T07:10:34.425339Z

Ok so what would be the issue with supporting that so one could add the appropriate prep command in that config?

pez 2025-10-14T07:12:42.695459Z

As, I said, it adds maintenance surface. I’m just one person.

mikejcusack 2025-10-14T07:14:24.990489Z

I'm not familiar with the inner workings of Calva, but wouldn't this be as simple as prepending the jack-in command with what the user provides, similar to appending for post?

mikejcusack 2025-10-14T07:17:31.671529Z

It would be quite helpful, especially in a team environment, to simply have a project config including something like "preJackInCommand": "clojure -X:deps prep :aliases '[:dev :test]'" than requiring everyone on the team to run said command every time a relevant dep is updated.

pez 2025-10-14T07:27:06.444519Z

I’m not arguing it would not be useful. It’s a matter of leverage. So, that particular use case can be covered with a shell script or Babashka task in the project, and requiring people in the team to run that script when a dep is updated. So then to maintain the config and mechanics for it, and burden the users with more config to understand. It may not be worth it.

mikejcusack 2025-10-14T07:30:19.981439Z

Sure, you could create a shell script or simply a shell alias with that and ask everyone to run that when a dep is updated, but it's out of process. I can guarantee there would be many times were someone will not think to run it and then try to start a repl and it fail. Then have to run it and try running the repl again. It's disruptive and could be easily solved with what we've discussed, but I understand where you're coming from.

mikejcusack 2025-10-14T07:31:38.926449Z

I'm not sure why the Clojure CLI couldn't just detect the situation and run the prep when that happens so it wouldn't fail.

pez 2025-10-14T07:33:30.720119Z

Could be something to suggest at ask.clojure. There’s already this one: https://ask.clojure.org/index.php/14581/improve-clojure-error-following-prepared-include-clojure

mikejcusack 2025-10-14T07:34:45.434789Z

Sure, and maybe in a year or two we could see such support 😉

pez 2025-10-14T07:36:20.975029Z

I think there are probably reasons not to auto-prep, but at least we may get to know those reasons, and people wondering about it in the future will be able to find the reasons.

pez 2025-10-14T07:40:50.735659Z

A thing I have been considering is if Calva could integrate with VS Code Tasks. That’s how I often start my repls, and with better integration it could get even more useful. Tasks are a bit like a super general purpose jack-in.

mikejcusack 2025-10-14T07:43:23.501189Z

That would be nice if possible

pez 2025-10-14T08:02:56.455489Z

Most of my projects need prep (in a general sense, not git deps prep), and I use Tasks to chain the steps. Like with Calva, the “jack-in” is something like: 1. clean the project 2. npm i 3. compile the ClojureScript parts of Calva 4. start watchers for formatting, TypeScript, ClojureScript, ESLint, tests 5. connect the repl With VS Code Tasks this is a two step process, 1, Run the build task, 2, Connect Calva. And I get the watchers I want to monitor running in the integrated terminal, in split view: • https://github.com/BetterThanTomorrow/calva/wiki/Run-Calva-in-Development-Mode#the-dev-process There are two inconveniences, one bigger then the other: 1. The Calva dependencies need to be maintained in my start Clojure script (an npm script in this case) 2. It is a two-step process instead of just 1, or even fully automatic when opening the project I don’t know if it is possible, but if Tasks would support some integration with Calva, both problems could be addressed. And git prep would be similarly covered by configuring a build task.

mikejcusack 2025-10-14T08:33:39.966909Z

Interesting

seancorfield 2025-10-14T13:15:21.660639Z

As a long-time OSS project maintainer (30+ years), I'll +100 what Pez said here: a feature may look simple to a user, but it may be a lot more work for the maintainer than it looks -- not just code, but cross-platform testing, and documentation, and then supporting it "forever" -- and it may only affect a small number of users, even when it is a "big pain point" for them. In addition, there may be other, more general approaches that solve more than that specifically requested feature -- or perhaps a partially-automated, partially-manual solution that is a lot less work to build and maintain but also addresses a broader problem space. Part of my argument here is also that if you're dealing with libraries via git deps that need prep, Calva's jack-in is not the only place it impacts. You need to deal with it in CI, you need to deal with it locally when interacting with the project outside of Calva, e.g., running tests, building an application JAR, starting a REPL yourself. And perhaps not all your team mates are using VS Code / Calva (I think my team at one point had four different editor/REPL setups). As you said @mike.j.cusack perhaps the hardest part of this, as a user, is figuring out that prep is needed in the first place (after your jack-in fails) and then figuring out exactly what that prep command needs to look like. The user has to be able to figure all that out before they can even add the pre-jack-in command, if such a feature existed. I think @pez is right to suggest that this be addressed initially via "just" documentation. When jack-in fails, there's a documented approach to debugging that by taking the jack-in command that Calva would use and running it manually in the terminal yourself (at least, I'm pretty sure that is documented?). So now we're outside Calva/jack-in and just using the CLI/terminal, and still need to go from the (not entirely helpful) "library needs prep" error message to knowing prep is needed to knowing whether to provide aliases -- and only at that point could you configure Calva to automate it just for jack-in for the future.

mikejcusack 2025-10-15T12:31:45.866869Z

I think what you said in general is fair, but is adding support for a pre-jack-in command a big ask? There's already support for running a command after. @pez himself said that there are many use cases for such a feature so it wouldn't be just for preparing a git dep and could be used for many things.

mikejcusack 2025-10-15T12:32:32.598099Z

I think the discussion is focusing too much on what prompted the discussion rather than a solution that would address much more than it

seancorfield 2025-10-15T15:09:17.644329Z

I'll leave the work/value decision to @pez about adding a preJackInCommand option (the afterCLJJackInCode only runs Clojure code -- is there a general shell command option for post-jack-in work?) I can see why customJackInCommandLine per https://calva.io/connect-sequences/#custom-command-line is a bit of a painful workaround for this (your point about keeping versions updated) but some folks already use https://calva.io/customizing-jack-in-and-connect/#jack-in-dependency-versions to pick up more recent versions of nREPL/CIDER/etc than Calva ships with. In addition, there's also https://calva.io/connect-sequences/#custom-command-line-substitutionsplaceholdersenvironment-variables which I think would allow you to substitute Calva's versions into your custom jack-in command? @pez am I understanding that correctly? ${JACK-IN-NREPL-VERSION} is that the correct syntax?

mikejcusack 2025-10-15T16:52:54.438649Z

Ok so going by that I was able to get it working by setting customJackInCommandLine to "clojure -X:deps prep :aliases '[:dev]';clojure -Sdeps '{:deps {nrepl/nrepl {:mvn/version \"JACK-IN-NREPL-VERSION\"},cider/cider-nrepl {:mvn/version \"JACK-IN-CIDER-NREPL-VERSION\"}}}' -M:dev -m nrepl.cmdline --middleware '[cider.nrepl/cider-middleware]'" , but that's obnoxiously long for a config file and still don't see why having a separate config entry for something to prepend to the existing (or custom) jack in command would be a big ask.

mikejcusack 2025-10-15T16:55:16.507229Z

Literally PRE-JACK-IN-COMMAND;JACK-IN-COMMAND

mikejcusack 2025-10-15T16:56:56.355559Z

It doesn't really make sense to have such a long JSON config value when the actual jack-in part is not changing from the default

👍 1
mikejcusack 2025-10-15T16:57:42.691759Z

Especially considering that the jack in dep versions can be customized in a separate config

seancorfield 2025-10-15T17:01:43.253719Z

Good to know that it does at least work. Thank you for verifying that.

👍 1
mikejcusack 2025-10-15T17:05:25.853609Z

This monstrosity sprawls out to column 296 instead of neatly fitting within the normal column size of everything else in the config file

mikejcusack 2025-10-15T17:05:41.760719Z

While, again, not changing a single thing about the actual jack in

mikejcusack 2025-10-15T17:06:19.843339Z

And would be even longer if you need more aliases

seancorfield 2025-10-15T17:06:29.608039Z

Yeah, we get your frustration, dude. You're kind of beating a dead horse at this point. @pez can make a decision about whether to add a pre-jack-in command.

mikejcusack 2025-10-15T17:06:58.574389Z

Ah, I see. You can belabor your points, but not anyone else

seancorfield 2025-10-15T17:12:58.944189Z

No need to be snarky.

mikejcusack 2025-10-15T17:13:33.529039Z

Consider your comment

pez 2025-10-15T22:12:07.490829Z

The substitution variables are also provided as environment variables, so I would move the commands to a script and then set the custom command line to the path of that script.

mikejcusack 2025-10-16T06:47:15.502759Z

Which doesn't address what I said about not actually changing the jack-in part at all and would again rely on something outside of Calva for something very easily implemented in it. Your position on these matters has been made very clear though so I think it's time to look somewhere else.

pez 2025-10-16T07:04:43.860129Z

I didn’t intend to argue anything. I wanted to highlight that Calva provides both substitution and environment variables to facilitate jack-in from a script.