Fork me on GitHub

I have problems reading Clojure source files that contains reader conditionals. I have no problems with all other “standard” Clojure files. The problem is explained in my comment at the end of issue.


read has a :read-cond option.


Okay, thanks, will check that out!


Note that clojure's read doesn't let you control the features. For this it's probably better to use tools.reader or edamame:


Oh, wait read does let you control the features, but there was something edge-casey with this: in Clojure's read you can't disable the :clj feature or so


user=> (read-string {:read-cond :allow :features #{:cljs}} "#?(:clj 1 :cljs 2)")


Perfect! Thanks.


No, that wasn't perfect. Check the difference.

$ clj -Sdeps '{:deps {borkdude/edamame {:mvn/version "RELEASE"}}}'
user=> (require '[edamame.core :as e])
user=> (e/parse-string "#?(:clj 1 :cljs 2)" {:read-cond :allow :features #{:cljs}})


Okay, will try it out!


If you just want to read all the forms and you don't care about alias resolving, you can do this:

user=> (e/parse-string-all "[1 2 3] #?(:clj 1 :cljs 2)" {:read-cond :allow :features #{:cljs}})
[[1 2 3] 2]


but not 100% sure how you are using the reader for polylith


Will fiddle with it, but thanks.


Your read-file will currently only partially read this file:

(ns foo (:require [clojure.set :as set]))
It will only read the first ns form since it will crash on the second form, but maybe that's your intention.


No, that’s not my intention. But users haven’t reported this as a problem. If the file only contain def/defn/defmacro + comments, then it works. But I guess it would be good if it doesn’t crash in the example you give.


Here is an example how you can parse ns forms more accurately and then resolve to the right keywords, etc If you don't care about the "right" keywords, but keep reading, you can just do this:

user=> (e/parse-string "[::foo ::str/foo]" {:auto-resolve name})
[:current/foo :str/foo]


How would the code look like if I want to read from a file? (I can probably figure that out, but sometimes it’s tricky)


I mean, should I read the whole content of the file and convert it to a string and then do e/parse-string, or should I read the file as a stream or something (haven’t looked in the doc yet).


you can do two things: first create a reader with e/reader and then call e/parse-next on it repeatedly, or slurp the file and then call e/parse-string-all


It worked perfectly! Thanks again for the help (I used e/parse-string-all).

partyparrot 4

I configured parse-string-all way and I’m now able to read the whole Polylith workspace with it. You may take a quick look @U04V15CAJ to see if I got it right! It’s important that I can read all variants of valid .clj source code, so maybe there are more options I need to add (or maybe some I should remove).


I’ll take a look later today

👍 2

@U1G0HH87L This looks ok. With the newest edamame you can also use :auto-resolve-ns for better keyword reading like ::alias/foo . What are you doing with the results? For closer clj defaults, also check here:


I’m extracting the :require statements from the ns for .clj files + reading .edn files (which reading everything from). I added :auto-resolve-ns to the list of attributes and it worked!


@U1G0HH87L Ah then you are in luck, since edamame now also has a edamame/parse-ns-form function which returns the :requires

👍 2

user=> (e/parse-ns-form '(ns foo (:require [foo :as bar])))
{:current foo, :meta nil, :requires ({:as bar, :require true, :lib foo}), :aliases {bar foo}}


It also supports gnarly edge cases like nested libspecs:

user=> (e/parse-ns-form '(ns foo (:require [foo [bar :as bar]])))
{:current foo, :meta nil, :requires ({:as bar, :require true, :lib}), :aliases {bar}}


Sounds great.


Is there Fulcro-like RAD tool to be used in luminus stack? Something like code generation based on data model for things like CRUD


We started building something like this, but are nowhere near it being useful for our one usecase. The problem I see with it for the Luminus stack is, that it roughly can pull in everything. Different SQL drivers, XTDB, Datomic, spec, malli, reitit, hiccup, selmer, re-frame…

👍 2

Is there a way to disable mutlthreaded artifact resolution when getting dependencies of a deps.edn based project? I am getting lock errors:

(base) chrisn@chrisn-lp2:~/dev/tech.all/tech.opencv$ clj
Downloading: org/bytedeco/opencv/4.6.0-1.5.8/opencv-4.6.0-1.5.8-ios-arm64.jar from central
Downloading: org/bytedeco/openblas/0.3.21-1.5.8/openblas-0.3.21-1.5.8-windows-x86_64.jar from central
Error building classpath. Could not acquire write lock for 'artifact:org.bytedeco:opencv:4.6.0-1.5.8'
java.lang.IllegalStateException: Could not acquire write lock for 'artifact:org.bytedeco:opencv:4.6.0-1.5.8'
        at org.eclipse.aether.internal.impl.synccontext.named.NamedLockFactoryAdapter$AdaptedLockSyncContext.acquire(
        at org.eclipse.aether.internal.impl.DefaultArtifactResolver.resolveArtifacts(
        at org.eclipse.aether.internal.impl.DefaultArtifactResolver.resolveArtifact(
        at org.eclipse.aether.internal.impl.DefaultRepositorySystem.resolveArtifact(
        at clojure.lang.MultiFn.invoke(
        at java.util.concurrent.ThreadPoolExecutor.runWorker(
        at java.util.concurrent.ThreadPoolExecutor$


try -Sthreads 1

👍 2

Thanks for such a quick reply! That is worst issue. Other issues is that it downloads all jars not just the jars for my current platform.


for that second issue, what is a maven coordinate that demonstrates that?


org.bytedeco/opencv-platform {:mvn/version "4.6.0-1.5.8"}


Last issue opencv only has a c++ interface making dynamic binding via jna and friends impossible leading to issues like this 🙂

Carsten Behring16:03:58

I just opened an AskClojure issue with it. It was logged in Jira. Interestingly it happened only on "slow network"

Jakub Šťastný23:03:25

How do I install latest Clojure CLI on Linux without adding external dependencies (Linuxbrew)? Everything I can found is post-fixed with the version, such as, but I cannot find the current version anywhere predictable. For instance has the version, but it's the master branch, so the version is 1.12.0-master-SNAPSHOT. I need either: • A URL that never changes, as in an (official) install script that doesn't include the version if there's one. • A way to get the version from somewhere, so I can correctly construct (str "linux-install-" version ".sh").


I use arch, clojure cli should be up to date and can be installed via pacman

Jakub Šťastný23:03:54

@U0LAJQLQ1 I like Arch, I've been using it for a good time back in the day when I was using Linux as my main OS.

Jakub Šťastný23:03:02

These days I use Ubuntu for my images though.


if you are using docker, you probably do want to specify the version number for clojure cli in your build process

Jakub Šťastný23:03:26

This is Ubuntu that will be released in April and has Clojure 1.10.


Ubuntu is hell

Jakub Šťastný23:03:42

I'm using Docker actually.


I use Ubuntu on my servers, and I'm pretty sure it's one of the main reasons why docker is popular

Jakub Šťastný23:03:38

I wanted not having to specify (I keep forgetting). The idea is get me latest Clojure, don't care which it is as long as it's the latest one.


if you are using docker, then hard coding a version of a dep is ideal


Before macports supported tools build, I used to run the install script used by the homebrew tap manually,


I think to get the latest version of something on Ubuntu, maybe you can use snap, or a ppa and use apt, but you can never be sure that those will give you up to date versions

Jakub Šťastný23:03:50

@U0LAJQLQ1 what do you mean by hard-coding? Setting it as ENV at the beginning of the script? I have it hard-coded, but somewhere in the middle 🙈

Jakub Šťastný23:03:12

Jesus now there are so many bloody package managers.

Jakub Šťastný23:03:57

@U7RJTCH6J cheers man! The version's right there, that'll work!


there is flat pack too, and yes there are way too many package managers on Ubuntu, and they are all bad


for hardcode, I just mean in your docker, if you build it a year from now that you would still build with the same version of clojure

Jakub Šťastný23:03:11

On Linux in general. It's always the main + Linuxbrew/Nix, then all the new Ubuntu ones or what...I don't really follow, it just is a new thing every time and it's too much!


Use the script name without the version.


nix is the now hotness, but it's actually pretty old


FWIW, contains the version (and SHA) for the latest 1.11.1.x version in case that's usefl.

clojure-spin 2

I'm adding a Getting Started with Clojure CLI to clojure-doc that mentions these scripts (it's a work in progress right now)

💙 4
💯 2
Jakub Šťastný23:03:33

@U04V70XH6 thanks, that's very useful. Going to check it later 🙂


We have a script at work that starts off:

if test "$1" = ""
  echo "Usage: <version> [preview]"
  echo "-- preview is required if version is not current stable release"
  exit 1

curl -O 
read stable_version stable_sha <

if test "${version}" = "stable"
We use this to update the vendored version we keep in our repo (so every developer/environment can rely on the same CLI version easily).
sh build/bin/ stable
Updates us to the latest stable version, whatever it happens to be. We can also specify an explicit version and even move to a non-stable version by adding preview as the second argument. has the current preview version (which, right now, is the same as the stable version).

Alex Miller (Clojure team)00:03:03 is maybe an easier url to get latest stable version info but the versionless urls above are supported

Alex Miller (Clojure team)00:03:54

(the github 1.11.1 will break when we re-version, which is its own issue to fix some day)


(yeah, our script at work uses that "easier url" for the stable version -- I should have specified that in my comments, rather than the links, thanks!)