This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2021-08-19
Channels
- # announcements (15)
- # babashka (4)
- # beginners (55)
- # calva (92)
- # cider (70)
- # circleci (1)
- # clj-kondo (136)
- # cljdoc (2)
- # clojars (11)
- # clojure (48)
- # clojure-australia (1)
- # clojure-europe (30)
- # clojure-nl (3)
- # clojure-sweden (2)
- # clojure-uk (7)
- # clojurescript (40)
- # conjure (5)
- # core-async (11)
- # cursive (55)
- # data-science (1)
- # datomic (10)
- # degree9 (2)
- # development-containers (15)
- # events (1)
- # fulcro (14)
- # gratitude (13)
- # helix (5)
- # lsp (35)
- # malli (10)
- # meander (18)
- # off-topic (24)
- # pathom (13)
- # polylith (12)
- # practicalli (6)
- # re-frame (13)
- # reagent (33)
- # reitit (4)
- # remote-jobs (1)
- # shadow-cljs (13)
- # spacemacs (31)
- # specter (1)
- # stepwise (2)
- # tools-deps (19)
- # vim (1)
- # xtdb (7)
I'm helping out a colleague with Calva's clojure-lsp integration. They use Windows, and it's not working. Here's the error we see in clojure-lsp.out
:
https://github.com/BetterThanTomorrow/calva/issues/1050#issuecomment-824719118
The stack trace points to this bit in clj-kondo:
https://github.com/clj-kondo/clj-kondo/blob/b6f76ea8371d2497ed14314cf99a679e41f5db4f/src/clj_kondo/impl/core.clj#L358-L360
Sadly, the error message doesn't show the path of the file it's trying to access, so we don't know what the problem is.
In any case, I figured we could work around the problem by setting {:output {:canonical-paths false}}
in the clj-kondo config, but that doesn't seem to make any difference. It's as though the config isn't getting picked up at all. At least I don't see how .getCanonicalPath
is called if :canonical-paths
is false.
Would it be possible for clj-kondo to log the file it's trying to access so that it ends up in clojure-lsp.out
? Any other ideas on how to troubleshoot the issue? The only thing I can think of is to create a custom clj-kondo version that logs the file path, then create a custom clojure-lsp version that includes the custom clj-kondo version, then try to set up Calva to use that. I guess we'll try that if nothing else pans out.
Could be, but inspecting the output of (System/getProperty "java.class.path")
doesn't reveal anything.
Anyway, I guess that's sort of the problem. There's a weird path-related issue, but I can't figure out what it is. It doesn't seem to be Could clj-kondo maybe log those file paths using a debug/trace log level?
Normally you should get this as a lint warning but not if there is something wrong while producing the lint warning
You could try linting using clj-kondo on the command line or JVM and see if you can reproduce this
Hmm, is it possible to tell Calva to use a different clojure-lsp…? Need to look into it.
@UKFSJSM38 perhaps you have a hint?
Clojure-lsp just pass the return of lein classpath to clj-kondo, you can try running that with the -NoProfile like said in the issue and get the output
2021-08-19T12:41:42.131Z SOLPF2AKCBN INFO [clojure-lsp.crawler:20] - Finding classpath via `powershell.exe -NoProfile npx shadow-cljs classpath`
2021-08-19T12:41:51.213Z SOLPF2AKCBN INFO [clojure-lsp.crawler:118] - Analyzing classpath for project root C:\Users\foo.bar-baz\Coxa\piso
2021-08-19T12:41:51.214Z SOLPF2AKCBN INFO [clojure-lsp.kondo:125] - Analyzing 265 paths with clj-kondo with batch size of 6 ...
2021-08-19T12:41:51.214Z SOLPF2AKCBN INFO [clojure-lsp.kondo:131] - Analyzing 1/6 batch paths with clj-kondo...
2021-08-19T12:42:02.513Z SOLPF2AKCBN INFO [clojure-lsp.kondo:131] - Analyzing 2/6 batch paths with clj-kondo...
So maybe it's the classpath that npx shadow-cljs classpath
returns that's the problem?
yes, probably, if your project is both a lein and npx one, clojure-lso will scan the lein classpath first and then the npx one and merge it
so try to run powershell.exe -NoProfile npx shadow-cljs classpath
and check the output
Ha! Found the issue, finally! Thanks for the hints, they led us down the right track. 🙂
PS C:\Users\foo.bar-baz\Coxa\piso> powershell.exe npx shadow-cljs classpath
------------------------------------------------------------------------------
WARNING: shadow-cljs not installed in project.
See
------------------------------------------------------------------------------
shadow-cljs - config: C:\Users\foo.bar-baz\Coxa\piso\shadow-cljs.edn
dev/src;dev/resources;target/shadow-cljs;
npx shadow-cljs classpath
prints a warning if shadow-cljs isn't installed locally (into the project node_modules
.
hummm, good to know, we can change the default on clojure-lsp adding that flag if that makes sense
(Our projects use the shadow-cljs Clojure API, so we don't typically install shadow-cljs via NPM.)
feel free to open an PR changing it https://github.com/clojure-lsp/clojure-lsp/blob/master/src/clojure_lsp/crawler.clj#L61
hum, so I think we can improve the way clojure-lsp handles that, probably shadow-cljs prints to output that, but it's not the return of the command
could you create a simple repro project where you confirm that happens so I can try debug it later?
testing on a lein project, lein also prints a lot of thinks specifally if the :pedantic flag is :warn, but that work with clojure-lsp becaause probably lein prints only the classpath to stdout
yeah, I think the best option is to change clojure-lsp to only get the last line of the output as the classpath
λ npx shadow-cljs classpath 2>/dev/null
------------------------------------------------------------------------------
WARNING: shadow-cljs not installed in project.
See
------------------------------------------------------------------------------
dev/src: <SNIP>
Yeah, that might be the quickest fix, although could maybe also ask Thomas to fix that in shadow-cljs.
Heh, and just to emphasize that this only occurs on Windows, because at least macOS doesn't have a problem with a path that looks like ------------------------------------------------------------------------------\n\n WARNING…
.
λ clj -M -e '(.getCanonicalPath ( (first (clojure.string/split (slurp "/tmp/foo.txt") #":"))))'
"/private/tmp/lsp-shadow-cljs/------------------------------------------------------------------------------\n\n WARNING"
probably @U04V15CAJ!
@U4ZDX466T ok, can you raise an issue before I forget?
ok, I pushed this one: https://github.com/clj-kondo/clj-kondo/commit/472d1417b504e2f4e91c7e8ec092436926327ac3
@UKFSJSM38 Awesome, many thanks! I also created an issue for shadow-cljs, so it'll probably get fixed there, too. Maybe it's enough to fix it in three places. 😛
I have an improvement suggestion that I'd like to know if that makes sense to be done on clj-kondo 🧵
related to midje
, there is a macro midje.sweet/provided
that is used to mock function calls, and it's possible to pass a & anything to suppress any extra args, for example:
(fact "foo"
(my-func) => true
(provided
(other-func & anything) => 2))
this should mock other-func
call and it doesn't care about the args.
clj-kondo reports the other-func
as wrong arity, it's possible to make clj-kondo ignore that linter if the args is a & anything
?ATM we are always exlcluding this with {:linters {:invalid-arity {:exclude [(midje.sweet/provided [*])]}}}
but that looks not ideal and needs extra configuration
yeah, but imagine there is a valid call that I want to clj-kondo lint as invalid arity:
(provided
(foo & anything) => 1 ; don't care about the invalid-arity
(bar 1 2 3) => 2) ; I do want a invalid-arity here
it does make sense, you can support this by writing an analysis hook or macroexpand hook
you mean, we could add a config on midje lib of:
{:linters {:invalid-arity {:exclude [(midje.sweet/provided)]}}}
but with a custom analysis hook to do lint the invalid-arity if not & anything
?I would remove the invalid-arity config and just handle this from your hook. expand into a call to the function if it doesn't contain an ampersand, and expand into a non-call like [foo anything] in the case of an ampersand, so clj-kondo will still see that the function is being used, and the arguments, but it won't be treated as a call
ok, well, this:
(provided
(foo & anything) => 1 ; don't care about the invalid-arity
(bar 1 2 3) => 2)
would expand into:
(do
[foo anything] 1 ; don't care about the invalid-arity
(bar 1 2 3) 2))
for exampleUsing the clj-kondo api, how can I specify a hook to be used? It's already in a directory. I tried setting :config-paths
, but had no luck.
clj-kondo check your projec config and check for :config-paths first, if a config path of foo/bar
is found, then it tries to find in your project a .clj-kondo/foo/bar/config.edn
file
if that folder doesn't exists it's because clj-kondo didn't import the folder, you can make that work with something like:
then clj-kondo will analyze the classpath, copy the folders from other libs classpaths and then you just need to have your :config-paths
configured correctly
A concrete example of rewrite-clj config paths on clojure-lsp: https://github.com/clojure-lsp/clojure-lsp/blob/master/.clj-kondo/config.edn#L1
note that is recommended to commit that folder inside the .clj-kondo dir after clj-kondo copy the configs
I'm using the API, I want to analyze another project that I am not in the cwd of from the JVM.
you can still use those flags via API, similar to how clojure-lsp uses https://github.com/clojure-lsp/clojure-lsp/blob/master/src/clojure_lsp/kondo.clj#L82-L89
but you will need to pass the classpath manually like clojure-lsp gets manually the classpath
Let's take a step back. I don't think dominic is asking how you import a config. he already has the hook config
The way to enable that is in the :hooks
config, as documented here:
https://github.com/clj-kondo/clj-kondo/blob/master/doc/hooks.md
Or is the config imported from another library? Then adding it to the config-paths should work
> Or is the config imported from another library? Then adding it to the config-paths should work Unless there is no cache, so clj-kondo would not find the hook I think
I have a .clj-kondo dir containing a "config.edn" and a "hooks". It belongs to projectA.
I'm in projectB (totally unrelated, but performing analysis on projectA). I'd like to utilize those hooks.
Yes, closed source. But not a mono-repo situation. ProjectB may be open sourced. I'm perfoming visualizations on namespaces using d3.
They're already in a directory named .clj-kondo. I tried using :config-paths and didn't get the hooks factored in.
(kondo/run!
{:lint ["/full/path/to/file/src/foo/bar/baz.cljs"]
:config {:output {:analysis true
:config-paths ["/full/path/to/file/.clj-kondo"]}
:config-paths ["/full/path/to/file/.clj-kondo"]}
:config-paths ["/full/path/to/file/.clj-kondo"]})
I really tried to use it 😄Maybe the more obvious solution, should I just slurp
the config.edn in .clj-kondo/ ?
Ideally this would work without needing cwds, so I could build something like https://next.github.com/projects/repo-visualization without cloning full repos.
https://github.com/clj-kondo/clj-kondo/blob/master/test/clj_kondo/hooks_test.clj#L57
ehm, that's not really intended to be exposed to users, it's only done for testing ;)
cool. so if you need additional help, I think it would be good to make a small minimal dummy repro so we have something concrete to talk about and debug instead of guessing
I think you've answered my question, which is, it's not possible to pull hooks in from another directory at the moment.
If I continue to be excited about this project, I'd like to explore changing that in kondo somehow.
Ideally I can load this data from github via http, and allow users to just type in "juxt/clip" or whatever, and get an analysis of namespaces. Similar to how https://next.github.com/projects/repo-visualization works
> it's not possible to pull hooks in from another directory at the moment I haven't said this isn't possible.
but your use case would be better off with a repro, so we can talk about code instead of guessing. it is possible to get hooks from other places
this may also work for your use case: https://github.com/clj-kondo/clj-kondo/blob/master/doc/config.md#exporting-and-importing-configuration but since your code is closed source, I can't really offer any help beyond guesswork which isn't very productive