Fork me on GitHub
#clj-kondo
<
2021-08-03
>
borkdude10:08:36

@ajarosinski Sorry, I didn't see your question

borkdude10:08:17

@ajarosinski I think this will work when you output EDN or text, but not all editors may supports this, so "it depends"

👍 3
Derek15:08:14

If I’ve written a kondo ‘hook’ function for a macro in a third-party library, what’s the best way to distribute it? Make a PR against that library? Or does it need to go in https://github.com/clj-kondo/config ?

borkdude15:08:05

@dpassen1 Cool. Which lib?

Derek15:08:20

Gary Fredericks’ test.chuck

borkdude15:08:21

I think the preferred way is to PR it against the lib but if the maintainer of the lib isn't comfortable with this, you can PR it against clj-kondo/config or maintain it yourself somewhere

borkdude15:08:55

If you maintain it yourself, you can recommend to users of test.check to also include your lib (with only config) and then it will be automatically copied

borkdude15:08:39

I think clj-kondo/config is nice since it's a central place where people might look for a config

Derek15:08:04

Thanks. I’ll clean it up and try to get in contact with the author of the lib

👍 3
hugod20:08:50

We have a macro that imports a namespace (creates forwarding defs). Does clj-kondo have an api that enables a hook to access the cached symbols from a namespace? which would allow transforming the import into a sequence of defn/def forms.

borkdude20:08:42

@hugod currently not. but you could generate this macro using runtime info and then dump it into the config folder

hugod20:08:03

what do you mean by “runtime info”?

borkdude20:08:08

in the REPL

borkdude20:08:16

or some function you run periodically

hugod20:08:31

oh, completely outside clj-kondo

borkdude20:08:52

yes. e.g. when you eval the namespace you could trigger a side effects which writes the macro

hugod20:08:06

that’s a possibility, I guess, though would require changing our codebase to something very specific for each current call site of the import macro. Seems like it would be simpler to just read the transit files generated by clj-kondo, and use it to rewrite the import calls.

borkdude20:08:44

@hugod The transit files are subject to change, not really a public API. The public API for this is https://github.com/clj-kondo/clj-kondo/blob/master/analysis/README.md

hugod20:08:04

right - just looking to see how easy it would be to extend that api. Would that be something you would be open to accepting a patch for?

borkdude20:08:44

do you mean, the API of the hooks right?

borkdude20:08:51

or the analysis data?

hugod20:08:03

sorry, misread. Yes extending the hooks api to include a function to get the cached data for a namespace.

borkdude20:08:34

I think that could be useful. But there is one problem here: the cache may not already been populated.

hugod20:08:50

or it may not be recent. But that seems no different to the behave when linting with a require :all.

borkdude20:08:51

also the namespace may be coming from clj, cljs or cljc (depending on the caller namespace, this is a bit of trickiness that this API should then account for)

borkdude20:08:13

what about leveraging the analysis data, which has everything of your project, and use that to generate the macro?

borkdude20:08:29

there is now also a :custom-lint-fn which is called after analysis with the findings + analysis where you could do this

borkdude20:08:50

that might also not be ideal since you would have to run this function every time you change an imported namespace

borkdude21:08:18

there are some people who went completely away from these kinds of macros towards a code generation approach

borkdude21:08:48

clj-kondo has built-in support for this well known macro, I forgot the name

hugod21:08:58

The import macro is used multiple times on different namespaces, so each instance would have to become unique, iiuc.

borkdude21:08:08

potemkin was the name

hugod21:08:24

right, unfortunately we’re not using that

hugod21:08:44

what’s the code generation approach?

hugod21:08:46

oh - could we use :lint-as and point to the potemkin versions?

borkdude21:08:31

if @lee is around he could tell you what he did to replace potemkin with code generation. the gist of it is instead of letting the macro generate code at runtime, you generate the code and save that to a file

borkdude21:08:46

yes, you can use :lint-as iff the syntax is the same

borkdude21:08:18

but I assume your macro doesn't literally get to see the var symbols?

hugod21:08:56

Right, it’s literal just passed the namespace name. potemkin doesn’t have an equivalent.

hugod21:08:38

I’ll have a think about how generating a macro implementation could work in the build.

borkdude21:08:56

perhaps it could be part of the macro itself

borkdude21:08:04

since all those vars go through there anyway

hugod21:08:30

could be - would require some logic to make it dev time only

borkdude21:08:34

e.g.

(defmacro import-all-vars [ns]
  (let [vars (ns-publics ns)]
         defs (map (fn [v] (list 'def v (symbol (str ns) (str v))) (keys vars)
         _ (spit ".clj-kondo/macros.clj" `(defmacro ~'import-all-vars .... (case ... ns (do ~@defs ....
This is very sketchy pseudocode. I think the clj-kondo config macro would have to be extensible using a multimethod or so, so each time the macro is called with a different ns, this different ns registers another defmethod to which the macro can dispatch and appends that to the file.

borkdude21:08:54

you could also just disable the unresolved var linter for an imported namespace

borkdude21:08:00

if that doesn't work out, we can see if we can provide the hook API with some cache info

borkdude21:08:48

I think I've done a similar thing to make :refer :all work better

hugod21:08:49

I’ll take a look at the implementation of refer :all.

borkdude21:08:51

I could simplify that case to not take into account cljs, etc. since :refer :all is only supported in clojure (JVM)

borkdude21:08:32

it's the only spot in clj-kondo where I read from the cache during analysis

borkdude21:08:05

so to think about an API: (hooks-api/var-names ns-sym) and this would return all the names. if everything was just clojure, then this would be it.

borkdude21:08:23

but cljs/cljc makes it a little bit more difficult.

borkdude21:08:28

so perhaps it should take an options map where you can specify more options or so

borkdude21:08:40

I'll let you think about it a little bit, at least you know where to look now. And I'm going to sleep on it as well :)

hugod21:08:39

Thanks for the detailed, useful response, as usual! Have a good evening!

borkdude21:08:54

is the semantics of your macro that ns1 is basically the same as ns2 ?

hugod21:08:10

No, the importing namespace adds stuff

littleli21:08:11

@borkdude I spotted the latest clj-kondo don't have a windows release artifact

borkdude21:08:40

failing test

borkdude21:08:45

thanks for noticing, I'll make a fix

borkdude21:08:00

I'll probably do a new release tomorrow

borkdude21:08:06

Windows path stuff

littleli21:08:33

no problem, if you do new artifact is going to be picked up.

borkdude21:08:12

@UKFSJSM38 ^ I'll probably have to do a new release tomorrow for Windows

👍 3