tools-deps

ag 2023-08-24T19:36:07.014589Z

I want the following structure of my project:

src
└── some_proj
    ├── backend
    │   └── system.clj
    ├── dev
    │   ├── config.edn
    │   └── user.clj
    └── frontend
        └── app.cljs
And I want to separate frontend, backend, dev dependencies. Like so:
{:paths ["resources"]
 :deps {org.clojure/clojure {:mvn/version "1.12.0-alpha4"}}

 :aliases
 {:backend
  {:extra-paths ["src/some_proj/backend"]
   :extra-deps {,,,}}

  :frontend
  {:extra-paths ["src/some_proj/frontend"]
   :extra-deps {,,,}}

  :dev
  {:extra-paths ["src/some_proj/dev"]
   :extra-deps {,,,}}}}
And now, if I do clj -A:backend, in the repl I should be able to (require '[some-proj.backend.system]). But it doesn't see it in the classpath. I think I miss something in my understanding of extra-paths.

2023-08-24T19:41:21.605239Z

Paths are classpath roots

dpsutton 2023-08-24T19:41:42.987249Z

if the classpath root is src/some_proj/backend, if you are looking for some-proj.backend.system it will look at <classpath-root>/some_project/backend/system.clj

2023-08-24T19:41:45.889769Z

The way namespaces are mapped to files is relative to roots

dpsutton 2023-08-24T19:42:01.557919Z

which would be src/some_project/backend/some_proj/backend/system.clj

ag 2023-08-24T19:43:59.036729Z

Can you guys please tell me what am I doing wrong?

favila 2023-08-24T19:49:26.578319Z

You cannot do this with paths: where the path “ends” becomes the root for class lookup, which in your config will never match the namespace. You need multiple roots if you want to do this with paths

ag 2023-08-24T19:51:44.186869Z

So what's the idiomatic way of splitting dependencies with deps.edn?

favila 2023-08-24T19:51:58.671049Z

more deps.edn

favila 2023-08-24T19:52:06.397869Z

and :local/root

favila 2023-08-24T19:53:45.525009Z

if you want to keep them all in the same dir, you can do this, but you may have trouble consuming artifacts made by this (maybe that doesn’t matter if it’s an application)

favila 2023-08-24T19:53:53.432799Z

src-backend
└── some_proj
    └── backend
        └── system.clj
src-dev
└── some_proj
    └── dev
        ├── config.edn
        └── user.clj
src-frontend
└── some_proj
    └── frontend
        └── app.cljs


{:aliases
 {:backend
  {:extra-paths ["src-backend"]}

  :frontend
  {:extra-paths ["src-frontend"]}

  :dev
  {:extra-paths ["src-dev"]}}

favila 2023-08-24T19:54:02.531379Z

but at this point, why separate classpaths at all?

seancorfield 2023-08-24T19:55:11.195539Z

I guess the question is really: what are you trying to achieve (and why)?

ag 2023-08-24T19:55:55.005539Z

So I can deploy front-end completely separately from the backend

seancorfield 2023-08-24T19:56:55.675769Z

Well, that's about what goes into your deployable artifacts -- so it's all about how you build things, not how the source code is structured.

dpsutton 2023-08-24T19:58:35.510539Z

and if you want stuff in separate folders, just use a structure that has backend, frontend , and dev folders and make each of those an item in :extra-paths ["backend"]

👍 1
dpsutton 2023-08-24T20:00:52.779269Z

and then make sure the namespaces are in the correct structure underneath backend/ frontend/ or dev/

ag 2023-08-24T20:01:56.527459Z

@seancorfield so like for example, if I want to have a "test build" that can separately build front-end and test it without bundling dependencies required for the server. And vice-versa, I don't want to include the test scripts into the main (prod) front-end build artifact.

dpsutton 2023-08-24T20:02:05.812629Z

note this is exactly @favila’s suggestion above. except he used src-backend

favila 2023-08-24T20:02:47.944939Z

@ag You’re skipping a step: how will you make those builds? deps.edn doesn’t do this automatically

1
dpsutton 2023-08-24T20:03:28.565819Z

you can pass aliases into it right? basis takes aliases and everything should work fine from there on out?

dpsutton 2023-08-24T20:03:39.564649Z

or will copy source still have some issues

favila 2023-08-24T20:03:49.358929Z

that’s definitely a way to go, and works for application artifacts

favila 2023-08-24T20:04:17.321909Z

it doesn’t work if it’s supposed to be a git-consumed or local-root consumed things because aliases aren’t transitive

dpsutton 2023-08-24T20:04:46.104359Z

yeah. can’t specify aliases for dependencies. i think there’s an http://ask.clojure.org ticket for it though

favila 2023-08-24T20:04:47.126099Z

but the point is many folder and deps.edn structures can support many different artifact variants and vice-versa

ag 2023-08-24T20:06:24.189989Z

> deps.edn doesn’t do this automatically so like if I use clojure.tools.build.api and all my code (front, back, dev, tests) are all in the same place, wouldn't it make it difficult to build multiple artifacts? i.e., I wouldn't want to include compiled and minified .js files in my server-side uberjar

dpsutton 2023-08-24T20:07:15.164689Z

you are pretty easily in control of what exactly goes in your jar. you build it, clean the directory, copy sources, etc into your jar.

ag 2023-08-24T20:10:07.016229Z

yeah, good point. Maybe why bother then by separating the files at the root level?

ag 2023-08-24T20:10:39.312569Z

Thank you, everyone. You are all very helpful. As always.

genekim 2023-08-24T21:09:30.773269Z

After years of being dazzled by people using add-libs (looking at you, @seancorfield), I decided to give it a try. I first tried using Clojure 1.12.0-alpha2, but got this error:

(deps/add-libs '{babashka/fs {:mvn/version "0.4.19"}})
Namespace clojure.tools.deps loaded but function not found: resolve-added-libs
I then tried using Clojure 1.12.0-alpha4, and got a different error:
(deps/add-libs '{babashka/fs {:mvn/version "0.4.19"}})
Execution error (ExceptionInfo) at clojure.tools.deps.interop/invoke-tool (interop.clj:49).
null
Has anyone else had this error, or have any recommendations on how to make this work? Thank you!

2023-08-24T21:10:23.066529Z

you need a newer version of the cli

☝️ 2
genekim 2023-08-24T21:11:14.061039Z

Whoa. I’m using this inside of Cursive/IntelliJ. That never occurred to me — trying that now!

2023-08-24T21:11:45.994169Z

add-libs shells out to the cli

genekim 2023-08-24T21:12:52.509569Z

(While I’m watching homebrew upgrade/update install…. @hiredman that this depends on shelling out to CLI would have NEVER occured to me!)

seancorfield 2023-08-24T21:13:01.330759Z

It requires CLI 1.11.1.1347 (or later)...

seancorfield 2023-08-24T21:16:18.130629Z

https://clojurians.slack.com/archives/C06MAR553/p1681479874896649?thread_ts=1681479653.194879&amp;cid=C06MAR553 -- looks like 1.11.1.1273 or later from that announcement but I think on Windows it needs 1.11.1.1347 for the "arguments passed via stdin" feature.

seancorfield 2023-08-24T21:17:54.292879Z

Here's the invoke-tool function it uses under the hood (mentioned in one of your errors): https://clojure.github.io/clojure/branch-master/clojure.tools.deps.interop-api.html

genekim 2023-08-24T21:24:10.818239Z

OMG. It works!! Thank you, all!!!!

genekim 2023-08-24T21:24:40.220299Z

(need to step out for a sec, but will respond more fully later today. 🙏 )