Fork me on GitHub
#tools-build
<
2023-01-26
>
practicalli-johnny16:01:58

Do I have to create a build.clj file for every project I want to use tools.build with to create a jar or uberjar package? Is there a common default I can use to or a package that provides such a thing? Or is tools.build only for creating a custom build each time? Given the tools.build project describes itself as a programmatic approach and I would prefer a declarative approach, I am not sure if tools.build is something relevant. Ideally I just want to run something like clojure -T:project/uberjar or clojure -T: project/build uberjar and I get a defacto .jar file I dont have any requirements to tailor the build and would prefer something consistent across all projects (until I find an exceptional case where I need to do something different)

seancorfield16:01:15

That was the original concept behind my build-clj wrapper but in reality, every project seems to be just slightly different enough that I added knobs & dials to it to try to accommodate that -- instead of pushing back and using tools.build in the first place. That said, when I've updated deps-new's templates to use raw tools.build and dropped the build-clj wrapper from those, the generated projects will be as close to "stock" uses of tools.build as possible as a starting point.

seancorfield16:01:01

An example, for uberjars, is whether you have transitive dependencies on log4j2 and whether those deps include formatting plugin caches -- if so, you need a log4j2 conflict handler for the uber tasks.

Alex Miller (Clojure team)16:01:24

the examples in https://clojure.org/guides/tools_build are meant to be "typical" starting points. in reality, most projects start the same (but rarely end the same). a "declarative" approach (like maven/lein) leads to 1000 knobs to cover all the deviations

seancorfield16:01:02

Yup, this ☝️:skin-tone-2: build-clj was meant to be "so simple it could be used from the CLI" but the reality is that just doesn't work for "most" projects.

borkdude16:01:11

@U05254DQM You can run neil add build in your project to get a reasonable default. See https://blog.michielborkent.nl/new-clojure-project-quickstart.html It adds a build.clj and add tools.build to the :build alias. This can be done in any existing deps.edn project. I just figured that I can update the build.clj file to add an uber function too.

seancorfield16:01:17

build.clj for a library JAR and for an application JAR are pretty different and you generally only want one or the other.

borkdude16:01:42

(oh never mind, neil add build already gets you to clojure -T:build uber by default)

Alex Miller (Clojure team)17:01:33

yeah, I think neil is a good approach to bridge here

practicalli-johnny17:01:03

Ah, I did find notes about seancorfield/build-clj and that would be useful, but sounds like its being decommissioned like depstar. So I have something to think about. Sounds like my preferred approach isnt going to be realistic, so will have some hammoc time about it some more and how (if at all) this can be added to the practicalli config. For now I'll remove the old packaging aliases from practicalli/clojure-deps-edn and leave it up to people to figure this stuff out in a project deps.edn or another tool approach.

seancorfield17:01:41

Both depstar and build-clj evolved beyond their initial "simple wrapper" starting points to include far too many knobs & dials -- because no two projects are alike, as soon as they move from their initial starting point.

seancorfield17:01:13

It would be nice if some basic "create new project" and "add build file" features were included in the CLI -- but even then you have library projects and application projects being quite different from the get-go and they quickly diverge from there... so I'm not sure what the best answer is...

borkdude17:01:45

I've also noticed this project: https://github.com/liquidz/build.edn but I've never used it. The idea, I think, is to make build.clj declarative again, but it might suffer from the same "wrapper" limitation

seancorfield17:01:53

Even hearing that neil add build adds a build.clj that caters for both library jar and application uber seems unnecessary complexity for someone just trying to get started.

seancorfield17:01:16

It's a really hard problem to solve correctly...

borkdude17:01:19

@U04V70XH6 Well, you don't have to use the uberjar function, you can just let it sit there or remove it :)

seancorfield17:01:03

Sure, but someone new to all this will tend to look at the build file and want to understand all of it -- and wonder why "half" of it isn't relevant to their project 🙂

seancorfield17:01:18

Historically, I've found that running tests in "real" projects tends to get beyond just clojure -X:test pretty quickly so I've ended up always adding testing to build.clj -- multi-version testing, doc example testing, Clojure & ClojureScript cross-platform testing, etc.

practicalli-johnny17:01:00

I'll write up some options about tools.build in Practicalli Clojure book instead of trying to shoe-horn in some user aliases that have external requirements I was looking at liquidz/build-edn and think its a nice alternative for project configuration (not so easy for a user alias though as it still needs a build.edn flle) I guess I have just relied on depstar for way too long... 🙂

seancorfield17:01:38

(some people have "opinions" on running tests from build.clj but I prefer not to have a mix of shell scripts and Clojure scripts if possible)

borkdude17:01:47

@U04V70XH6 What you are describing sounds like a task runner to me and the tools.build can be used as such, but there are other solutions for this too (like bb tasks, Makefile, Justfile)

seancorfield17:01:11

But then your dev/CI/CD platform needs additional tooling installed.

borkdude17:01:01

For some people that is worth the trade-off ;)

seancorfield17:01:40

I haven't used Makefiles for decades -- and I'm very happy about that 🙂

borkdude17:01:26

I also don't like Makefiles, which is why bb tasks exists ;)

seancorfield17:01:36

I did cave in and add bb to next.jdbc for running tests that require more setup... but it was a marginal tradeoff TBH...

seancorfield17:01:32

At work, we vendor in the Clojure CLI so our entire toolchain only needs git and java and nothing else. That's why I don't want to add extra tooling requirements there.

practicalli-johnny17:01:41

Most commercial work I've done recently had to be done within Docker, so there were already tooling requirements. Once place even enforced a Makefile had to be used (I had forgotten how much I like them, so use them a lot now). I (now) have a pretty standard Dockerfile / docker-compose.yaml / Makefile combination for CI that I am happy with (and some .k8s/ configs too... when necessary) Sometimes it feels there is more config than application code laughcry I I think creating my own project template / template repository will be the smoothest approach to creating a basis for new Practicalli projects

seancorfield17:01:37

@U05254DQM LMK if you need help creating a deps-new template -- they are mostly declarative (EDN) 🙂

👍 2
borkdude17:01:20

@U04V70XH6 If you need to add more tools, check out asdf, it's a pretty nice way to control which CLIs and versions you get per directory/project. They are using it heavily at Pitch.

practicalli-johnny17:01:27

Yes, @U04V70XH6 I think the plan is to create a git repo of what I want the project to look like and then create a deps-new template to generate it, replacing project names in namespaces/filenames and any other useful substitutions. Thanks

2
seancorfield17:01:39

@U04V15CAJ So then we'd need to install another tool -- asdf -- in order to install more tools? That seems like it is compounding the problem :rolling_on_the_floor_laughing: By vendoring the CLI into our repo, we can automate a lot of setup/deployment that doesn't require additional downloads and installs across containers and servers.