Fork me on GitHub
#clj-kondo
<
2022-08-07
>
vemv04:08:44

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?

vemv04:08:19

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 :)

❤️ 1
borkdude06:08:59

This has come up before. You can find the reasoning in the original issue on GitHub

borkdude07:08:48

I'm trying to find the original issue but this is extremely hard...

borkdude07:08:57

It was in a discussion with Dave Yarwood I remember

borkdude07:08:51

there is a little tool here to populate your config: https://github.com/oxalorg/clj-konmari/

vemv07:08:19

> 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?

borkdude07:08:55

I'm afk for a bit, will reply later

borkdude09:08:01

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.

vemv09:08:08

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?

borkdude09:08:19

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.

borkdude09:08:20

It's also not so hard to do this yourself in a :custom-lint-fn over the analysis data

vemv09:08:46

(...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)

borkdude09:08:16

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

borkdude09:08:04

I think the expectation of this linter would be clearer if it were named :preferred-alias , that's really what it is

vemv09:08:26

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

borkdude09:08:05

Alright, issue welcome.

👍 1
borkdude09:08:18

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.

borkdude09:08:30

I'm also open to PRs

Dumch15:08:47

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?

Dumch15:08:07

But how do you extend hooks? What would be the approach? May be there is an example?

borkdude15:08:37

Through protocols or multimethods?

Dumch15:08:37

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!

borkdude15:08:48

yes, if you require your protocol

👍 1
borkdude15:08:43

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

Dumch15:08:31

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.

borkdude15:08:14

This isn't exposed

borkdude15:08:48

I think you're better off using the :tag of the node and use multimethods

🙌 1
Dumch15:08:05

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

Dumch15:08:31

one way to go with multimethod is to have dispatch function as (-> % class str), but seems not elegant

borkdude15:08:51

Hmm, not sure why the tag is missing. Can you post a issue + repro?

👌 1