Clojure Project – Setting Up Clojure Project and Sub Projects

clojureproject-structure

This is primarily a lein question about setting up a major project and its sub-projects, and is not intended to be a discussion question. Instead, I am interested in either a pointer to documentation or to a Clojure/lein best practices link.

I have a municipal property assessments application that splits two master flies into different subset files, depending on whether a billing transfer is taking place or we want to batch update new accounts, rather than making our assessment department enter new accounts once in their system and then again in the tax collection system.

My application is going to be large enough, that I can see a common library lein project with support functions, like splitting apart the files, and then individual lein projects that use the common library.

Should the lein projects be set up at the same level and support included through the project.clj/core.clj files?

Is there an advantage to creating lein new projects underneath a major project?

Is there a problem with combing all functions in one project?

I can probably make my one core.clj contain all flavors of the program, but coming from a C/C++ and Python background, I would prefer to have a lot of little projects.

Best Answer

If you reasonably believe that parts of your project would be valuable as shared libraries, I would build separate projects for them with lein new.

At the same time, Clojure is all about simplicity, so you can always create the components in separate namespaces, and pull out pieces as libs on an as-needed basis (really, you should be doing this anyhow, in order to keep your components as decoupled as possible).

Once you have your separate pieces, you have a couple of options. If you want to make them public/open-source, you can upload them to Clojars. If they're private, in-house libs, you can set up a maven server internally, or while you're in early development, just use lein-localrepo to have them accessible to your build process when you include them in your project.clj.

This is one of those times for hammock-driven development; think carefully about which modules you think will be reusable before you start, and create those as separate libs. But for many cases, that level of reusability is a YAGNI feature, so my usual approach is to just put common functionality in a common namespace, and extract it out asa library on an ad hoc basis. It's both pragmatic, and avoids the pain of having to maintain too many discrete software entities unnecessarily.

Related Topic