This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2022-11-24
Channels
- # adventofcode (4)
- # announcements (1)
- # aws (6)
- # babashka (18)
- # babashka-sci-dev (18)
- # beginners (12)
- # calva (43)
- # circleci (3)
- # clj-kondo (96)
- # cljdoc (2)
- # clojure (89)
- # clojure-australia (2)
- # clojure-europe (26)
- # clojure-nl (3)
- # clojure-norway (11)
- # clojure-spec (8)
- # clojure-uk (1)
- # clojurescript (28)
- # cursive (25)
- # datahike (6)
- # datalevin (56)
- # datomic (12)
- # docker (15)
- # emacs (9)
- # events (2)
- # figwheel (3)
- # fulcro (15)
- # gratitude (10)
- # introduce-yourself (8)
- # lsp (16)
- # malli (6)
- # nbb (2)
- # off-topic (23)
- # other-languages (2)
- # pathom (4)
- # portal (25)
- # practicalli (1)
- # re-frame (9)
- # releases (1)
- # shadow-cljs (8)
- # sql (6)
- # timbre (3)
So I created this hook:
(ns hooks.ws.clojure.extensions.condp->
(:require [clj-kondo.hooks-api :as api]))
(defn condp-> [{:keys [node]}]
(let [[expr pred & tail] (rest (:children node))
rewritten
(api/list-node
(list*
(api/token-node 'cond->)
expr
(api/list-node (list pred expr))
tail))]
{:node rewritten}))
and it's in hooks/ws/clojure/extensions/condp__GT_.clj
and it works -- clj-kondo correctly processes condp->
invocations everywhere -- but clj-kondo complains that the ns in that file does not match the file name (namespace-name-mismatch) which seems like a bug?Clojure can handle that natively? That’s pretty cool!
clj-kondo uses namespace-munge
to detects if the filename corresponds to the namespace name:
user=> (namespace-munge "foo->")
"foo_>"
that it works, might be accidental, since the reverse operation is probably just the general demunge
user=> (doc namespace-munge)
-------------------------
clojure.core/namespace-munge
([ns])
Convert a Clojure namespace name to a legal Java package name.
having >
in filenames can be awkward in bash and I don't even want to know what happens in Windows :)
Oh, weird. namespace-munge
and munge
do not match?
no, there are some subtle differences, I can find the related clj-kondo issue for you
but if your hook worked, this is actually a bug in the clj-kondo SCI env, since it should also use namespace-munge
for looking up that file :)
I guess I got the impression from earlier discussions and examples that a hook for x.y.z/abc
needed to be in hooks.x.y.z.abc/abc
but I gather that's not true? What are the constraints on the namespace/function name for hooks?
you can make up any namespace name in the local .clj-kondo
directory, as long as the namespace name corresponds to the filename.
clj-kondo has a kind of classspath. the local .clj-kondo
directory is added to that classpath, as are all two-level deep directories: acme/lib
OK, so I don't need a separate file for each hook function? If a ns in my code has multiple macros that need hook definitions, I could have hooks.whatever/something.clj
and that could contain all the hook fns for those macros?
Cool. I can do quite a simplification of our hook setup then 🙂
@U04V70XH6 would you consider adopting the .clj_kondo
extension for hooks? I've come across a https://github.com/clj-kondo/clj-kondo/issues/1685 related to having hook code in .clj
files.
@U08BJGV6E I'm talking about hooks within our monorepo at work, to handle macros in our own code, or 3rd party libraries we use that don't have clj-kondo support.
oh, I misunderstood then. I was under the impression some of these were for your OSS projects
I'm puzzled by your issue: I don't have the .clj-kondo
folder on my classpath so I can't see how an IDE would ever confuse the hook code with actual Clojure code?
And even if .clj-kondo
is on your classpath, the ns would be different and would not be something any of your code nses would ever require -- so, again, how on earth can be IDE get confused about that?
It isn't normal for .clj-kondo
to be on the classpath and my issue isn't about that.
The problem comes out when a library distributes its own clj-kondo hooks (among its resources), and that library is used by a consumer via a git dep.
a quick repro case is
clj -Srepro -Sdeps \
'{:deps {org.clojure/tools.namespace {:mvn/version "1.2.0"} seancorfield/next.jdbc {:git/url " " :git/sha "24bf1dbaa441d62461f980e9f880df5013f295dd"}}}' \
-M -e "((requiring-resolve 'clojure.tools.namespace.repl/refresh-all))"
Oh, you mean like this: https://github.com/seancorfield/next-jdbc/tree/develop/resources/clj-kondo.exports/com.github.seancorfield/next.jdbc/hooks/com/github/seancorfield
Heh, yeah, well a) don't use c.t.n.r and b) don't use Cursive 🙂
Well, that's what I thought @U04V15CAJ so I'm surprised it's a problem...
well maybe there is, if c.t.n.r tries to load every .clj file there is on the classpath, but why would it do that, if nothing else refers to it?
that's just how c.t.n.r works, I asked about it https://ask.clojure.org/index.php/11434/could-namespace-refresh-sophisticated-directory-filtering but core aren't interested in changing that
c.t.n.r is just broken (in many ways). I wish it didn't exist 😕
According to Alex: But why are those in :paths? The whole meaning of :paths is "paths containing source to be put on the classpath". Seems like these source files should not be there if they are not source.
@U04V15CAJ To be clear, clj-kondo will find an import foo.clj_kondo
as a hook in that resources
tree (as well as bar.clj
)? So I could change them and it would all still work? (that extension is news to me)
@U04V70XH6 Yes, this was implemented to solve this c.t.n.r problem
here's a https://github.com/clj-kondo/clj-kondo/blob/master/doc/hooks.md#compatibility-with-toolsbuild-compilation in you're interested
@U08BJGV6E Feel free to create issues on any of my OSS projects you use that have hooks in resources
and I'll make the change next time I'm working on them...
next.jdbc
may be the only one?
I just renamed it, and it is the only hook in any of my projects as far as I can see.
Currently, the only other unreleased change in next.jdbc
is a small doc example so it may be a while before I release an update for that.
Thanks a bunch. Since the problem only comes out when referring a lib via git coordinates, it's already fixed
> Since the problem only comes out when referring a lib via git coordinates Why is that?
Yeah, that surprises me since the JAR files contains that same file/path:
655 Fri Nov 04 22:22:36 PDT 2022 clj-kondo.exports/com.github.seancorfield/next.jdbc/hooks/com/github/seancorfield/next_jdbc.clj
Because clojure tools differentiate between namespaces coming from a directory path vs a jar path
I've had problems with this in both lein and tools.build with duplicate compiled namespaces + graalvm native-image and since then I always use an explicit list
deps-new
has a bunch of .clj
files in resources
because they are templates for generating new projects -- but they are mostly illegal Clojure code and the ns
in particular is not a valid symbol... but almost no one would have deps-new
on their classpath while working on other stuff 🙂
(`clj-new`, boot-new
, and lein new
code all do the same -- and those .clj
files are in the codebase, not even just restricted to resources
)
I'm with you, I tried to phrase something like this at https://ask.clojure.org/index.php/11434/could-namespace-refresh-sophisticated-directory-filtering?show=11880#c11880
I'm reminded of https://corfield.org/blog/2018/04/18/all-the-paths/ wherein I examine how different tools deal with different "types" of paths -- and Leiningen in particular had :source-paths
and :resource-paths
(Boot also had these two keys but they meant different things of course).
https://github.com/seancorfield/deps-new/issues/39 -- for "completeness" on this topic 🙂
Nice article, Sean. In the end it all comes down to what is on the classpath at runtime.
Do you think it might be worthwhile for the clj-kondo --lint src
command to output just the filenames (if it finds warnings/errors) for loading up into an editor? For example, something like vim $(clj-kondo --lint src --raw)
, then when it's loaded into an editor (in my case, vim with clojure-lsp), those errors would flag up when the analysis has been done?
@dharrigan the format that is currently spit out is already made in a standard way that editors recognize
Using :cfile, you can just load a file with kondo’s normal output
what I mean is that when you open this format in an editor, it usually knows what to do with it. https://github.com/borkdude/carve#report-mode
@dharrigan clj-kondo --lint src --config '{:output {:pattern "{{filename}}"}}'
but since we have a config option and it might break existing tools somehow, maybe not necessary
@dharrigan sorry I sounded a little agitated
@dharrigan I guess what I meant earlier is that when you command click in your terminal, and you have the right default editor set, the file will open at the right location with the current output. This works at least for me + VSCode (for some reason that editor is set for my terminal right now), but of course your terminal has to support this too