This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2023-11-09
Channels
- # announcements (14)
- # architecture (42)
- # babashka (23)
- # beginners (37)
- # biff (8)
- # calva (2)
- # cider (3)
- # clara (42)
- # clerk (14)
- # clojure (55)
- # clojure-brasil (3)
- # clojure-dev (5)
- # clojure-europe (18)
- # clojure-hungary (88)
- # clojure-losangeles (3)
- # clojure-nl (1)
- # clojure-norway (66)
- # clojure-uk (9)
- # clojurescript (16)
- # core-logic (16)
- # datomic (6)
- # fulcro (32)
- # hyperfiddle (25)
- # instaparse (12)
- # joyride (2)
- # lsp (13)
- # malli (15)
- # off-topic (50)
- # polylith (11)
- # portal (3)
- # re-frame (2)
- # reitit (2)
- # sci (8)
- # shadow-cljs (16)
- # tools-deps (13)
- # xtdb (5)
for those with clj+cljs applications and using docker, how do you write your dockerfile/docker-compose.yml to have both clojure and node installed? i spent a painful evening last night wrestling with various methods and didn't find anything satisfactory
The primary issue being that RUN curl -sL
no longer works to install node in a FROM clojure
dockerfile
Are you building your artifacts in the docker build, or are you just running build artifacts in docker?
Docker compose is for running docker images. It sounds like you're trying to build them.
I use Node inside Docker but outside of the Clojure image (inside Docker - for safety reasons because screw Node and its mistakes) and then simply ptu the built JS bundle into the Clojure container. Couldn't be happier with the setup.
Multi stage dockerfile is extremly helpful with this problem:
FROM node:latest AS builder
# Install clojure related tools
RUN ...
# Build artifacts
RUN ...
FROM clojure:latest
COPY --from=builder /path/to/compiled/artifacts /path/to/resources
@UEENNMX0T I use the clojure:temurin-20-alpine
base image and then install npm with apk. It installs node as an npm dependency. That may or may not work depending on if you need Nodejs 18 specifically.
the docker container currently runs mongo, lein repl
, and then two calls to npm to watch changes to the cljs (shadow-cljs), and to watch for changes to the css. that's why i can't just using COPY --from=builder ...
in the past, i'd run these in a separate tab of my console, but i'm using a new machine and don't feel like setting up all of the extra stuff to get it to work. other devs on our team (open source project) rely on it too
you still can run extra commands from separate tab:
docker compose exec container -ti npm ...
i'm looking to be able to run docker compose up -d
and then have everything running behind the scenes so all i have to do is jack into the repl
this is going against docker principles but you can start container with a chain of commands:
npm ... & \
npm ... & \
lein repl
lol clever
I'm using clojure:temurin-17-tools-deps-bullseye-slim
and then I followed the instructions here for Debian: https://github.com/nodesource/distributions
there are examples of uber images different tech stacks in the same container (for development) - e.g. https://github.com/penpot/penpot/tree/develop/docker/devenv
If you just want a straight hacked up dockerfile here is mine lol: https://github.com/chase-lambert/clojure-app-template/blob/main/Dockerfile
oh that's very nice, i'll try that out
(resharing here because #CHV7NHGAG has like 34 people in it)
Can you share what doesn’t work with data.xml?
I’m seeing this error building my application:
#17 22.79 Syntax error (IOException) compiling fn* at (io/atlantico_software/spanish_publishers/warehouse_location_updates.clj:195:3).
#17 22.79 Filename too long
The line it’s unhappy about is the beginning of a core.match
expression. I’ve shortened the filename a few times (down to warehouse.clj
) but still seeing the error — is there anything else I should try? Or just keep shortening the name until it accedes?it is because the name of the class file for the generated code is too long, so the file cannot be written to disk because it exceeds the file name length limit of whatever filesystem you are using
for the classes the compiler generates the namespace name is usually part of, but not the whole class file name, and usually the namespace name ends up being part of the directory tree the class gets written to, but the name itself is something generated by the compiler
the names generated by the compiler typically reflect the structure of the code, for example a "$fn" will get tacked on for every level of anonymous functions
additionally sometimes for certain expressions the compiler will insert immediately invoked functions, for example E
becomes ((fn [] E))
, which can add nesting where none may be immediately apparent
I see… is there a way to write match
expressions to not nest as much? My expression is (to my eyes) pretty simple:
(def almuzara "ALMUZARA")
(defn record->publisher [{:keys [Proveedor Imprint Tema] :as record}]
(match [Proveedor Imprint Tema]
["editorial almuzara" _ _] almuzara
;; 27 more lines like the previous
:else (throw (Exception. (str "Found an unexpected proveedor/imprint/tema combo:" (select-keys record [:Proveedor :Imprint :Tema]))))))
it is kind of occupational hazard of core.match's implementation, and likely why its use isn't as wide spread as you might expect
I have a little pattern matching library that never really got a release https://github.com/hiredman/match2/tree/master which is much more naive about how it compiles patterns, and so results in less nesting hairy stuff
I will check that out, thank you for the link and for the explanation!
Wow. This just scared me away from core.match.
There's no way to "consume" an alias loading all the libs defined in :extra-deps without restarting the REPL?
:alpha {:extra-deps {org.clojure/clojure {:mvn/version "1.12.0-alpha5"}}}
in ~/.clojure/deps.edn
is a lovely treat for the new featuresWhoa, I just tried (sync-deps :aliases [:bench])
and it worked beautifully. I was so excited about add-lib thing that I completely missed awesomeness of sync-deps. Thank you Alex!
I have a hot key bound in Calva that prompts for aliases and then does sync-deps
🙃 1.12 is awesome-sauce!
Wow, @U04V70XH6, is VS Code your daily driver? If so, I rely on the same text editor as Sean Corfield and that's pretty cool. (Good to be in good company :)
> I have a hot key bound in Calva Oh, that'd be nice to have in Emacs. What's the best way of figuring out all available aliases? Including ~/.clojure/deps.edn, etc.? Also, is it possible to (relatively easily to) determine which aliases were loaded? Ideally, it should only prompt with aliases that either not yet loaded, or modified.
clj -X:deps aliases
provides alias info, happy to consider changes if needed
@U02U1T66REZ All my config is here: https://github.com/seancorfield/vscode-calva-setup (key bindings, settings, Calva REPL snippets, Joyride scripts) plus I use https://github.com/seancorfield/dot-clojure for aliases and for starting my REPL. Here's the alias I use at work for starting a REPL:
:vscode-calva-jack-in
{:extra-deps {com.datomic/dev.datafy {:git/sha "4a9dffb"
:git/tag "v0.1"
:git/url ""}
djblue/portal {:mvn/version "0.49.1"
#_#_:local/root "/home/sean/oss/portal"}
io.github.seancorfield/dot-clojure
{:git/tag "v1.0.2"
:git/sha "6a3f903"}
io.github.stuarthalloway/reflector
{:git/sha "93a0c19b4526c1180959e940202928d35e5c3cef"}
jedi-time/jedi-time {:mvn/version "RELEASE"}
party.donut/dbxray {:mvn/version "RELEASE"}}
and my .vscode/settings.json
file at work:
{
"calva.replConnectSequences": [
{
"name": "World Singles Backend (Jack-In)",
"projectType": "deps.edn",
"cljsType": "none",
"autoSelectForJackIn": true,
"projectRootPath": ["."],
"menuSelections": {
"cljAliases": ["build", "dev", "+default", "test", "vscode-calva-jack-in"]
}
},
{
"name": "World Singles Backend (Connect)",
"projectType": "deps.edn",
"cljsType": "none",
"autoSelectForConnect": true,
"projectRootPath": ["."]
}
],
"calva.jackInEnv": {
"LOG4J_CONFIGURATION_FILE": "log4j2-test.properties"
},
"calva.autoConnectRepl": true,
"workbench.colorTheme": "Default Dark Modern",
"workbench.preferredDarkColorTheme": "Default Dark Modern",
"workbench.iconTheme": "vs-seti",
}
I used to. I used Emacs way back in the 17.x days through the early 19.x days. I used Together/J for my Java years (late '90s onward for a while). I picked Emacs back up when I came to Clojure (2010) but never really settled back into it, and after trying tons of configs, I switched to "modern" editors and used a bunch, settling on Atom until I switched to VS Code -- and with cljs customization via Joyride, it's programmable like Emacs, while having great integrations with everything else I use (like Jira/BitBucket at work!). And Calva is awesome, with LSP/clj-kondo for static analysis too.
Then we junior devs are lucky beneficiaries! ... I started in Atom and adopted VS Code + Calva after struggling with Proto REPL. Very happy to be here! 🔵:large_green_circle:
What does clj -X:deps aliases
do under the hood? What's the equivalent for this in the REPL? I'm thinking, if I already have a connected repl, wouldn't be faster/straightforward to send something to the REPL instead?
@U0G75ARHC Source: https://github.com/clojure/tools.deps.cli/blob/main/src/main/clojure/clojure/tools/deps/cli/api.clj#L139
create-edn-maps
is here https://github.com/clojure/tools.deps/blob/master/src/main/clojure/clojure/tools/deps.clj#L774
@U02U1T66REZ I really liked Atom + ProtoREPL but it stopped being maintained and updates to Atom broke things. That's when I switched to Chlorine (and a Socket REPL). And then when it looked like Atom would also stop being maintained, I switched to VS Code + Clover (a port of Chlorine), and then Clover sort of stopped being maintained(!) so I switched to Calva... and it happened to coincide with the VS Code version of Portal appearing (which I'd switched to from Reveal, which I'd switched to from REBL 🙂 ).
Okay, so I think the lesson for me here is that change is the only constant, there is no perfect tool and to stay nimble & tinker often! I like it!
I need to add a version that works even if org.clojure/tools.deps.cli is not in the classpath
Even the new-in-1.12 stuff that provides access to the CLI tooling stuff does it by shelling out to the actual CLI.