Fork me on GitHub
Shantanu Kumar09:06:22

Hi. I'm looking for a sample project/repo that maintains both project.clj and deps.edn - some way to specify the dependencies in just one place. Would appreciate any pointers.


It's fairly easy to keep a list of deps in an edn file and then generate the project.clj and deps.edn from a template, but this will limit you to non-git-deps


or just keep the deps.edn as the source of truth (since it's already just edn) and then generate the project.clj from that (using a template)


I used to do that, it's brittle. Dependency resolution is different between the two, so you might end up in weird situations if you use stg like pedantic.


Perhaps lein could one day use tools deps alpha as the resolution mechanism?

🙏 3

at least optionally


@U066J7E2U It's definitely an approach that has problems so I would ask why you want to do this? Rick's repo README does a great job of talking about the potential problems (due to the inherent mismatch between how lein and t.d.a handle dependency resolution) and the downsides of the trade off he makes. I created a similar tool for boot (prior to Rick's lein plugin, I believe) because we were using Boot but already had our dependencies external (in deps.edn -- albeit a different format at first). Here's mine -- again, the README talks about limitations and differences and I decided to archive the repo and discourage its use, because it was just too hard to make it work properly beyond the simplest cases! At work, we decided it was simpler to switch completely to the CLI and deps.edn and abandon trying to integrate the two approaches (we'd already switched from lein to boot years earlier for the flexibility Boot provided over Leiningen).


My advice would be to just switch from lein to t.d.a/CLI deps.edn and avoid trying to integrate them. Or stay with lein and ignore deps.edn for now.

Shantanu Kumar18:06:18

Thanks, @U04V70XH6 I was trying to keep the benefits of both and the freedom (for developers) to choose either, but as you and others have mentioned, it's nondeterministic and error prone.


I do have a deps.edn and project.clj for a lot of open source projects, exactly for that reason and I never had any conflicts there, probably because libraries tend to have fewer deps


@U04V15CAJ I'm curious about what benefits you perceive for a library project to have both? (assuming the deps.edn/CLI side can do "everything" that the Leiningen side can)


(there are definite benefits -- for CLI users -- to have even a minimal deps.edn added to a Leiningen project, so that it can participate as a :git/url dep, but I don't see much benefit in having project.clj added to a deps.edn project if your dev/test/build setup is based on the CLI)


As I just explained to @UKFSJSM38 :

👍 3

also I want to be flexible for other maintainers


@U066J7E2U I think there's value in forcing "encouraging" Leiningen users to install the CLI and start learning deps.edn since it's the "official" tooling -- and we have on the horizon as well 🙂


@U04V15CAJ Fair enough. I'm looking forward to clojure -X:build test jar deploy as a CI process. We're not quite there yet, but I think that will beat what Leiningen offers. At work we just replaced our long build shell script with build.clj as a stepping stone toward, and the next version of depstar will offer the option of running pom, aot, and jar/`uberjar` as separate tasks, along with offering a :target-dir option.


what's the syntax again for the -> semantics vs. providing key/vals?


clojure -X:aliases func1 func2 func3 :some '"arg"' :and '[:more :stuff]' = (-> {:some "arg", :and [:more :stuff]} (func1) (func2) (func3)) -- you mean that?


(plus any :exec-args from the :aliases obvs)


what if you want to pass func1 func2 as a key value pair?


the keys have to start with a colon?


You can always pass a hash map at the end: '{func1 func2}' -- just bear in mind those are then passed as symbols.


clojure -X:aliases func1 '{func2 func3, :some "arg", :and [:more :stuff]}' -- like so (assuming you meant passing func2 func3 not func1 func2?)


or clojure -X:aliases func1 :some '"arg"' :and '[:more :stuff]' '{func2 func3}' if you wanted to combine named args and a hash map. Just like Clojure 1.11 calls 🙂


ah right, trailing maps