Fork me on GitHub

In a mono-repo is it possible to use a common deps.edn file with aliases that can be used from all sub repos?


(without hacking $CLJ_CONFIG)


Not that I've discovered.


I don't believe it's possible.


I’m experimenting with porting to deps.edn, so in the future, we could migrate our boot stuff to deps.edn


The idea is that you can define a bunch (bundle) of deps in a common file and then refer to a common name for that bundle in your deps.edn files’ :deps and/or :extra-deps.


@borkdude not sure if that covers your need, but @matthias.margush has created this tool:


We have a monorepo with dozens of subprojects -- and we use a small shell script to wrap clojure and use CLJ_CONFIG to point to the monorepo's deps.edn file (and then each subproject has its own deps.edn file). Works great. Any reason you don't want to do that @borkdude?


Basically the shell script does cd path/to/subproject.clj; CLJ_CONFIG=../versions/deps.edn clojure ...args...


datapoint -> we have a monorepo and looking for a clean solution as well


or hints at how to contribute a solution


@seancorfield the reason I thought I wanted to avoid that is that it messes with people’s own configs in their .clojure dir?

Alex Miller (Clojure team)18:02:22

some possible answers, curious if these would help: 1) a clj flag to pass one or more config files that go “in the chain”

Alex Miller (Clojure team)18:02:44

2) an env property to list or more additional config file locations

Alex Miller (Clojure team)18:02:35

3) some kind of config file in .clojure/ (I’m guessing probably not ideal as this is for a group of projects but may not extend to everything you’re doing)


1 makes this manual opt in everywhere, so users have to inform their tooling of this flag. 2 would require something like direnv, and would also require extensive editor integration.


another way: :include "../parent.deps.edn"


1 seems more tenable than 2 for something like cursive which has the most extensive analysis of deps.end files.


That, together with a way of including the deps of aliases into another alias would be helpful to me


Hey all. I'm having trouble getting a very simple deps.edn going. I keep on getting a message that opencv can't be found in mvn central, but I've added my custom repo where the jar can be found.


1 with less magic: clj --deps-file foo/deps.edn would only take foo/deps.edn into account. The current situation could be seen as clj --deps-file ~/.clojure/deps.edn --deps-file deps.edn ....


@borkdude when you're working on a monorepo project, I'd argue you want a more reproducible set of processes so I'd say you want .clojure to be omitted from deps.edn.


@seancorfield I don't think that's any more true than a normal repo is it?


@seancorfield people tend to put their cider-nrepl config into .clojure/deps.edn. I don’t want to disturb that

👍 5

Since deps.edn is “just data”™️ I’m inclined to rewrite a template to the deps.edn that will be used


I also put Rebel, library overrides for environment specific bugs, benchmarking and more. All depending on the context I'm in.


@dominicm It's a matter of opinion 🙂 We've generally added stuff to our versions/deps.edn file that individual devs find useful. And we have a couple of "dev" namespaces that include REPL startup stuff. So there's really nothing in our .clojure/deps.edn files that would be useful in addition (we already have nrepl/socket REPL/REBL stuff in our project deps.edn files).


@borkdude be aware that updating a deps.edn like that will erase comments. I wrote ednup to be a crappy solution to that, but it's not prime ready yet.


@dominicm I’m exploring rewrite-clj using zippers, that will leave everything intact. does this too.


That said, I wouldn't object to an enhancement to tools.deps/`clj` that allows additional deps.edn files to be specified 🙂


@borkdude that's what ednup does




@seancorfield I work on a few monorepos (they're mono to their context), and updating my dev config in each of them would be a pain. I'd feel inclined not to commit my dev hacking and clutter git history, especially in projects where we have stringent reviews on code.


@borkdude yup. You can see usage in my rewrite of resolve tags.


I’ve started experimenting with supporting deps.edn for boot-bundle here, also using rewrite-clj: but since it’s hard to settle down on an approach, I’m first looking if deps.edn itself could support this better


It's not a great library, but I plan to iterate on it intensely at some point, and it's great for simple things.


Oh, if you want examples, pack has an injector which uses rewrite directly.


I meant: figuring out the format/API is hard, not the actual programming 🙂


I want to support existing users of boot-bundle (including myself) and support a migration path from boot to deps.edn


anyways, being able to specify multiple extra deps.edns from the cmd-line is a good thing in my opinion


you can always use -Srepro to exclude .clojure so that functionality is already there

Alex Miller (Clojure team)19:02:46

it is still a pending todo to finalize what -Srepro means, esp in context of -Sdeps and other features. some of that is pending config file rework


another option, instead of having a super deps.edn for the monorepo, or generating dep.edns for subprojects might be something like a dependency linter, you give it some rules (deps on project x most version y) and run it over a directory and it checks all the deps.edn files it finds


a linter could even be run against projects not in your monorepo to see how some other library might integrate


@hiredman meh, then you would still have to update all those occurrences, or do you mean the linter would actually update the files?


no, you would have to update the files


the reason I wrote boot-bundle was to prevent having to do that, it became annoying


I would want one source of the truth and the include that in another project


some call it “managed dependencies” but I didn’t realize that when I wrote the lib


how much dependency churn do you have?


so what I’m searching for is managed deps for deps.edn. Another way to accomplish this maybe is to have “empty” projects that declare their deps and then make a dependency on those with local/root.


but that gets out of hand too, I want it to be declarative and easy to modify


@hiredman we have a couple of local libraries which all depend on subsets of the same dependencies. in some of those we use AOT. it’s nasty if you get the versions wrong, so we want them to be the same

Alex Miller (Clojure team)19:02:18

we always intended to support something like managed deps and I think that is a valuable use case

Alex Miller (Clojure team)19:02:06

we have not put as much thought into how that should look as with other stuff yet


Our versions/deps.edn file is mostly :override-deps to "pin" dependencies for the whole monorepo. Each subproject declares its own dependencies as group/artifact {}. And we have dev/test/build aliases in versions/deps.edn.


@alexmiller with being able to specify extra deps.edn configs from the cmd line + the ability to merge multiple aliases into one (:foo has :bar and :baz like with -R:bar:baz) I think we would be 99% there


maybe even 100%


Having four deps.edn in the chain instead of three would solve all our issues 🙂 (system, user .clojure, project root, subproject root).


project/subproject seems arbitrary to me (different projects use different directory structures), being able to specify this yourself and number of times you can do this should be flexible


aot adds whole other wrinkle on top of things for monorepos, because you are depending on build output of a local project, not the local project (with clj doesn't directly support so much)


do you aot as low down the deps tree as possible, or as high up as possible?


@hiredman We wrote a lib that has some Java code which we compile up front. We don’t want to have the situation that we’re going to use different deps than what that was compiled against.


ah interesting, built java not aot'ed clojure?


@borkdude Perhaps I'll rephrase that as "monorepo" and "project" level then instead of "project" and "subproject"? 🙂


We also ran into trouble once with a service that was running clojure 1.8 which did different edn serialization than 1.9, that was also a problem. we just don’t want to think about this stuff too much and exclude any such possibility.


@seancorfield boot-bundle supports loading bundles (managed deps) even from Clojars, it doesn’t matter how you organize this.


@borkdude and each "bundle" would map to a separate deps.edn file? So you could have a folder for each "bundle" and then access them via multiple :local/root deps?


@seancorfield how this is done currently in boot bundle is one keyword maps to one or more deps (or recursively, to another bundle). this is just EDN which is expanded dynamically in the scope of a build.boot file.


For us, the problem isn't really the deps themselves, but the aliases we want across the whole monorepo -- sort of like requiring every dev to have consistent .clojure/deps.edn files but just for the projects in the monorepo.


where this bundle.edn file comes from is up to you, could be from clojars, a directory, etc.


I haven't looked at anything in Boot for quite a while now. I hadn't heard of boot-bundle. Sounds useful in a deps.edn world.


in boot this is easy to implement because you can actually program in the build file. in deps.edn I currently see no other way than to rewrite a deps.edn.template and expand it into a deps.edn. but with the options we mentioned in this conversation, I think it’s very close at hand


relying on add-lib could also work, but I’m not too familiar with that and I think that’s alpha-alpha?


I recently added some aliases to my .clojure/deps.edn file that pull in that branch and the comments in my EDN file show how to write a load-master function that can resolve master from git repos and then add that library 🙂


read the whole conversation, our team is looking for the same answers @borkdude, maybe we can join forces 😄 Share the pain err your thoughts with me ok?