This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2022-08-07
Channels
- # babashka (20)
- # beginners (72)
- # biff (7)
- # calva (15)
- # clj-kondo (36)
- # clj-on-windows (5)
- # cljs-dev (30)
- # clojure (27)
- # clojure-europe (2)
- # clojure-nl (1)
- # clojure-norway (6)
- # clojure-uk (2)
- # clojurescript (26)
- # conjure (14)
- # cursive (17)
- # events (1)
- # honeysql (5)
- # hyperfiddle (1)
- # leiningen (1)
- # off-topic (3)
- # reitit (5)
- # shadow-cljs (1)
- # xtdb (13)
Might be a FAQ so I figured I'd ask here. How come the :consistent-alias linter needs a pre-configured corpus?
Have you considered that in a given project, if I use a :as b
and a :as c
that is clearly inconsistent and would not need a config?
FWIW I have a custom linter for this sort of thing, but where I can I try to get people to use clj-kondo first :)
My understanding is that it boils down to point 4? https://github.com/clj-kondo/clj-kondo/blob/a550a8279e1bf2134921d5a31b98aa68c60f5a00/doc/dev.md#design-principles
I took the link from https://github.com/clj-kondo/clj-kondo/issues/561
ok yes, this is the main consideration: https://github.com/clj-kondo/clj-kondo/issues/561#issuecomment-547539721
there is a little tool here to populate your config: https://github.com/oxalorg/clj-konmari/
> ok yes, this is the main consideration: If that is the main consideration (and not a higher-level design consideration), I disagree. If you have a linter failure for two aliases, you can, instead of adding config at all, solve the conflict by changing one of the aliases. i.e. the 'endgame' is to have consistent aliases, not to have a config. There's a very objective, desirable advantage to this approach: you get consistency enforced for all aliases - not for a cherry-picked subset. i.e. 100% coverage. Had you considered the matter in this way?
Right, so, yes with :inconsistent-alias
you can specify the namespaces you care about, namespaces not mentioned there aren't considered. This can be considered a feature or a shortcoming. Some people might consider the linter to be too strict if you would consider namespaces not mentioned there, although this could be configured perhaps. To implement the strict mode, clj-kondo would have to keep data in the cache of every namespace + alias encountered, which is not impossible but also not trivial.
Thanks for the reponse. Maybe I dont agree with "too strict", it's very annoying to have projects with inconsistent aliases. I'd go as far as saying that it's detrimental for the ability to properly code-review things over github, etc. > To implement the strict mode, clj-kondo would have to keep data in the cache of every namespace + alias encountered, which is not impossible but also not trivial. Maybe this is the sort of thing that clojure-lsp is already good at?
There could be a mode in which you lint multiple namespaces at once in which clj-kondo reports this, so not the editor mode let's say, but a CI mode, then it would be much easier to implement.
It's also not so hard to do this yourself in a :custom-lint-fn
over the analysis data
(...Again, I have a linter that addresses this https://github.com/nedap/formatting-stack/blob/main/src/formatting_stack/linters/ns_aliases.clj but I'm mostly interested in something that can reach as many people as possible without convincing them of extra tooling etc)
One other thing to consider is: what should the error message look like: Inconsistent alias found for foo: yes, alright, but what to do now? Scan the project for occurrences of foo: or configure clj-kondo's consistent-alias linter? Well, then we're back at where we are now. All trade-offs considered, I think having a small tool like konmari printing a config for you and regularly updating it, isn't too bad
I think the expectation of this linter would be clearer if it were named :preferred-alias
, that's really what it is
Example message:
The alias foo is inconsistently used in the project.
An extended description in the .md could be as verbose as desired. Probably for non-novice Clojure programmers the preferred course of action would be self-evident anyway
> I think having a small tool like konmari printing a config for you and regularly updating it, isn't too bad
It seems very ugly to have a huge list regularly being spit from a foreign tool. It's just more moving pieces e.g. now I have extra stuff in CI? More security weak spots also
> I think the expectation of this linter would be clearer if it were named :preferred-alias
I agree with that, but this seems a pretty big opportunity for clj-kondo for making codebases fundamentally better. Which benefits everyone in the community, workplaces etc
If you can, leave in the "thumbs up" message so we can poll how much the community wants this, so it can be prioritized accordingly.
Is it possible to extend others hooks? For example, I am writing a DSL. I implemented it with protocols, so anyone can get a library and extend it locally. But is there a way for him/her to extend my hook as well?
@arturdumchev I think so yes
So If I get a library with hook based on protocol, I can add a hook locally with protocol extension, and lib's hook will see it? Great!
Note: only namespaces that are referenced in hooks are loaded and also namespaces required in hook namespaces. So if a user extends your protocol, that extension will only be loaded if the namespace is referenced somewhere
How to I reference node?
(extend-protocol IExpression
clj_kondo.impl.rewrite_clj.node.token.TokenNode ...
Could not resolve symbol: clj_kondo.impl.rewrite
_clj.node.token.TokenNode
I tried require node, but didn't work
(ns hooks.defs
(:require [clj-kondo.hooks-api
:refer [token-node list-node vector-node reg-finding!
token-node? list-node? vector-node? sexpr]]
[clj-kondo.impl.rewrite-clj.node :as node]
[clojure.string :as str]))
getting:
error while trying to read hook for dumch.concatenative/defstackfn: Could not find namespace: clj-kondo.impl.rewrite-clj.node.
Sorry, one more question: what am I doing wrong?
I tried to get tags on parent node children:
(println head :class (class head) :tag (:tag head))
And I see nils on symbol (TokenNode) tags:
<token: !a> :class clj_kondo.impl.rewrite_clj.node.token.TokenNode :tag nil
<token: !b> :class clj_kondo.impl.rewrite_clj.node.token.TokenNode :tag nil
<list: (invoke> + 2)> :class clj_kondo.impl.rewrite_clj.node.seq.SeqNode :tag :list