Skip to content

Add option to symlink Clojure dependencies during build#165

Draft
kenranunderscore wants to merge 1 commit intojlesquembre:mainfrom
kenranunderscore:symlink-clojure-deps
Draft

Add option to symlink Clojure dependencies during build#165
kenranunderscore wants to merge 1 commit intojlesquembre:mainfrom
kenranunderscore:symlink-clojure-deps

Conversation

@kenranunderscore
Copy link
Contributor

@kenranunderscore kenranunderscore commented Jun 15, 2025

I'm often finding myself building projects that use Clojure + ClojureScript (with shadow-cljs), with an artifact uberjar that contains the Clojure backend and some compiled JavaScript code for the frontend. In order for the build commands to be identical for both local development and Nix builds, I'm usually building the frontend stuff in my build.clj. This involves using npm at some point during the buildPhase.

npm expects $HOME to point to a mutable location, but clj-nix sets $HOME to the immutable location of the Clojure dependencies. This PR introduces an option to symlink the Clojure dependencies to the pwd (and setting HOME to that) during the buildPhase instead, making it possible to use mkCljBin to build such projects instead of having to reverse enginner it :)

Note that I didn't touch the leiningen-specific part of the build, as I don't have anything to test that with. I don't think it should interfere in any way, though, especially since the default did not change.

@kenranunderscore
Copy link
Contributor Author

For a before/after you can check out what I changed in this example project:
kenranunderscore/clojure-clojurescript-with-nix@06f682b

@kenranunderscore
Copy link
Contributor Author

Is that CI failure due to flakiness? I saw the same error in some other commits' runs.

@kenranunderscore
Copy link
Contributor Author

We could create a makeSetupHook like importNpmLock.linkNodeModulesHook, and:

  • export that in the flake to use in a devShell
  • use that to implement mkCljBin by just including it in the buildInputs

Would that be something you'd consider? I might add an example implementation in my fork to use in my showcase project and check how it feels.

@jlesquembre
Copy link
Owner

Would that be something you'd consider?

Absolutely. I currently have very little time for clj-nix, which is why I haven't commented before. Thank you for your PR; this one is more involved than the others, so I want to think a bit about it before merging it

@jlesquembre
Copy link
Owner

Oh, and yes, there's some flakiness on CI

@kenranunderscore
Copy link
Contributor Author

@jlesquembre Thanks for the answer! I'll convert this one into a draft as I have a working local copy that creates cljHooks.linkCljDepsHook that does the following (and would obsolete or supersede this PR):

  • linkCljDepsHook is a makeSetupHook that takes care of symlinking the locked dependencies.
  • This hook can be used in a devShell to automatically symlink the Clojure deps into the working directory (similar to pkgs.importNpmLock.linkNodeModulesHook for people who want to use identical, "pure" dependencies during development and nix build.
  • It can also be used as the environment "implementation" of mkCljBin, mkCljLib etc. -> it no longer needs to use export HOME=... at all, making the buildCommand more compatible with some commands that need a mutable $HOME.
  • All tests are still passing! I'll send another PR your way (or update this one) in the coming days. I've even tested it locally with a Leiningen project. So it could be argued that we don't need this PR at all and could use the above as a default (or simply use a flag like in this PR to use the hook).

Before making this PR so we can talk about it I'd have another question: To be absolutely sure I don't destroy anything I'd love to upstream some integration tests for Leiningen projects, as lein needs to be handled and configured differently wrt "local dependencies". But I'm not sure where those tests should go, as I don't want to add Leiningen to the template (and it'd need a different lockfile anyway). Would you be fine with me adding a third bats test suite, together with a small Leiningen "hello world" project like in the template? Then we could test whether locking with and without Leiningen profiles also works, and use the gained certainty before talking about bigger changes like above.

Sorry for the wall of text 😅 And no need to hurry!

@kenranunderscore kenranunderscore marked this pull request as draft June 18, 2025 16:28
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

Successfully merging this pull request may close these issues.

2 participants