I'm getting a Unresolved namespace user. Are you missing a require?
for referencing symbols in my user.clj. Why is this happening when there is a user namespace defined and it doesn't need a require because it's fully qualified?
The user.clj is in a separate dev/ source directory. I have a .lsp/config.edn, which includes dev/ in the source paths. The error still is present.
Adding a .clj-kondo/config.edn with {:output {:include-files ["^src" "^dev" "^test"]}}
resolved the issue. But I'm confused why this is necessary when the .lsp/config.edn is present. This is happening in vscode with Calva.
Actually it didn't. It made the linting not work at all.
Repro please.
Define a var in the user ns. Try to reference it with user/foo
User ns being in dev/
So my .lsp/config.edn is
{:source-paths #{"src" "dev"}
:project-specs [{:project-path "deps.edn"
:classpath-cmd ["clj" "-A:dev" "-Spath"]}]
:semantic-tokens? true}
The user ns does get cached in .clj-kondo
Does the same thing in my Doom Emacs setup so it's not Calva specific
Can you please make a standalone repro without LSP.
Something that I can run locally
with clj-kondo on the command line only
You don't use lsp?
Running clj-kondo --lint <file>
results in the same output
I do use LSP but when posting an issue with clj-kondo, I don't want to use any downstream tools
If it's an issue with LSP, post in #lsp
Ok. Well as I said, running it alone results in the same error
ok, but that's still not a repro that I can run locally. You'll have to provide me with an actual file or repo that I can run
...?
I gave you the steps
Create a dev/user.clj, put any def in it. Then reference it from src/<something> as user/<def>
You will have to just put a (require 'user)
in there for now. Clj-kondo expects this for any namespace you are using
But that doesn't make sense given it's a fully qualified ns
I don't understand.
And adding in a ns require [user :as user]
doesn't work either
Code can reference a FQDN without a require
fqdn?
fully qualified domain name
That's not true though. You can't just (foo.bar.baz/x)
without requiring foo.bar.baz
in general
Not sure what you mean. Open a fresh repl and eval (clojure.string/starts-with? "foo" "f")
And as I said, if I require [user :as user]
it still doesn't work
dev/user.clj:
(ns user)
(def foo :foo)
src/kondo.clj:
(ns kondo)
(prn user/foo)
deps.edn:
{:paths ["src" "dev"]}
This works
But results in linting error
And you can start a repl and (in-ns 'kondo)
and then user/foo
And it returns the expected :foo
As I said you should add a (require 'user)
in your (ns kondo)
file
Not necessary as I said and it still results in the linting error
ok, can you file an issue?
For now you can solve the problem with {:linters {:unresolved-var {:exclude [user]}}}
after adding the require
it is unusual what you are doing here btw, normally you will not refer to the user
namespace from the code in src
it's usually the other way around, you will require other namespaces from user
and then use them from user
I have dev-time vars defined there and I'm not referring to them in src/ outside of a comment block. I'm referring to them in test/ mostly.
Released a new clj-kondo version 2021.03.03 with some fixes for false positives introduced by the :redundant-expression
linter.
you can also put a #_:clj-kondo/ignore
before the comment
block or before the form with the warning to disable the warning
But it's still good to post an issue about this so we can improve this
But I'm seeing the issue. The user ns is special in this case as the repl is loading it at startup. So it's aware of user/foo. But using another ns it isn't working.
I wonder if it's this: just because something works, doesn't mean it should lint without errors. For example you can :refer :all and the referred symbols will give errors. I know you can use clojure.string/includes? without requiring clojure.string but for other namespaces it is imo better for the linter to suggest that you require that namespace, as it is then clearer for the next reader.
Oh wait, you're saying including (:require [user])
in your ns form doesn't work?
What is happening (I think) is that clj-kondo overwrites the vars for the user
namespace the next time it starts linting a file. Any file basically starts in the user
namespace. So after adding the require, he would still get an unresolved-var
Not sure what the correct thing to do is, but it really seems like a questionable edge case
I'm not sure why it's such an edge case. There's a valid use for creating vars in the user namespace so that when you start up the repl you have those already set up. Such as defining a conn
var for a db connection. Instead of calling it each time I start a repl I just already have user/conn
.
And fwiw Cursive analyzes this case just fine
clj-kondo is not working with fully qualified namespaces, which is allowed in Clojure
@mike.j.cusack Out of curiosity: does Cursive also catch if you write user/foobar
if foobar
doesn't exist?
https://www.clojure.org/guides/learn/namespaces#_require "While vars can always be referred to by their fully-qualified name, we rarely want to type fully-qualified names in our code."
It does catch that
It's not ignoring the user ns. It's analyzing the local file
@mike.j.cusack This is not generally true. You can only use this after you load the namespace. And generally you should not rely on other namespaces loading those namespaces for you.
The user
namespace might be an exception
It's absolutely true. I already gave you an example. You can use clojure.string
without requiring it
The place where it's inconsistent is in user code, which requires loading the file as you said.
@mike.j.cusack This is not true for e.g. (clojure.pprint/pprint {:a 1})
Which seems like an issue in Clojure itself
You should not rely on the fact that clojure.string
was already loaded by some other library
I'm not. Literally start a fresh repl in a new dir and use it. It works
So does your pprint example
And read the link above
$ clj -M -e "(clojure.pprint/pprint {:a 1})"
Execution error (ClassNotFoundException) at java.net.URLClassLoader/findClass (URLClassLoader.java:471).
clojure.pprint
I suggest you read this issue: https://github.com/clj-kondo/clj-kondo/issues/339
It's just like Java. You can always refer to vars by fully qualifying them
$ clj
Clojure 1.10.2
(clojure.pprint/pprint {:a 1})
{:a 1}
nil
$ clj
Clojure 1.10.1
user=> (clojure.set/union #{1 2 3} #{2 3 4})
Execution error (ClassNotFoundException) at java.net.URLClassLoader/findClass (URLClassLoader.java:471).
clojure.set
user=>
Ok. Well this is quite confusing given the official docs stating you can refer to things by fully qualifying them always
Not if the namespace hasn't been loaded yet.
That's not what always means
The fact that your clojure.pprint
example works just means that it has already been loaded by some other tool
I suggest you verify this in the #clojure channel and people will tell you exactly what I told you
I'm off to other business now
I'm not loading any libs so it's clj repl itself
But in any case the repl for sure loads the user namespace and it is suggested to add dev helpers in a user.clj to be loaded by the repl automatically.
Cursive treats this correctly and reads your user.clj. clj-kondo does not
Yes, I've already suggested you make an issue on Github about this, I am repeating myself.
I'm not sure why spending all of this time explaining the issue to you is not enough.
Is it too much to ask to post your issue on Github so I don't forget about it?
Since you're talking about yourself forgetting being the issue can you not make the issue yourself with the info I've already provided? I've already taken a chunk of my time to help you when I don't even use the tool. I use Cursive. I'm just trying to be helpful.
OK, I will write it down somewhere if I have time. I'm kinda busy right now. Thanks for the help.
@borkdude I see the latest tag at https://hub.docker.com/r/borkdude/clj-kondo/tags?page=1&ordering=last_updated is a few months old. Did you stop publishing these?
@imre Docker images have moved to cljkondo/clj-kondo on Dockerhub
Ah, thank you. The link in https://github.com/clj-kondo/clj-kondo/blob/master/doc/docker.md contains an extra - then 😉
sent a quick pr https://github.com/clj-kondo/clj-kondo/pull/1191
Thanks!