Fork me on GitHub
#clj-kondo
<
2023-05-17
>
grzm13:05:49

‘lo all. I generally want a way to lint just the classpaths of my code (and not the code of the dependencies). If I do something like clj-kondo --lint $(clojure -Spath -M:test:dev) , the clojure -Spath understandably returns the full classpath, including the dependencies, and clj-kondo --lint happily lints those too 🙂 . However, I really only want it to lint the :paths and :extra-paths , not the :deps and :extra-deps. I’ve got a workaround filtering the classpath for only relative paths. It works, but it feels hacky and that I’m probably missing something obvious, or there’s a piece of tribal knowledge I’m missing out on. What are others’ approaches to this? Am I thinking about it wrong (which is always a distinct possibility)?

grzm13:05:07

FWIW, here’s my little bb filter:

% clojure -Spath -M:test:dev | bb -i '(->> (str/split (first *input*) #":") (remove (fn [p] (.isAbsolute (io/file p)))) (str/join ":") print)' 
test/clojure:src/clojure

borkdude13:05:03

There isn't any built-in solution in clj-kondo

borkdude13:05:15

It has no knowledge of deps.edn whatsoever

grzm14:05:19

Makes sense. Right now I’ve got it as a shell script. I’m thinking of porting it to a bb.edn task. Would it make sense to leverage deps.clj instead of clojure -Spath do you think?

grzm14:05:19

(looks like it invokes a clojure process anyway, so I’m unlikely to see speed gains there. Not that the speed of the current method is a problem, but faster is nice :)

borkdude14:05:32

In bb.edn you can use the (clojure …) task which invokes deps.clj but shelling out to Clojure should work too

grzm14:05:28

Does the clojure task create a separate clojure process? That was my reading of https://book.babashka.org/#tasks:clojure > The clojure function starts a Clojure process using https://github.com/borkdude/deps.clj.

grzm14:05:15

Here’s what I came up with:

% cat build/src/build/elf.clj 
(ns build.elf
  (:require
   [ :as io]
   [clojure.string :as str]))

(set! *warn-on-reflection* true)

(defn relative-classpath [cp]
  (->> (str/split cp #":")
       (remove (fn [p] (.isAbsolute (io/file p))))
       (str/join ":")))
% cat bb.edn 
{:paths ["build/src"]
 :tasks
 {:requires ([build.elf :as elf])
  lint (let [relative-cp (-> (with-out-str (clojure "-Spath -A:test"))
                             (elf/relative-classpath))]
         (shell (str "clj-kondo --lint " relative-cp)))}}
% bb lint
linting took 131ms, errors: 0, warnings: 0

grzm14:05:44

not sure if I’m happy the current factoring, but it’s Better than Bash™

grzm14:05:51

Thanks, @U04V15CAJ!

👍 2
grzm14:05:32

For a gut check, is this seem like a reasonable thing to want to do? (programmatically determine the paths of just the project)

borkdude14:05:51

well, I've contemplated this, but then there will be people who say: I want to lint this alias, but not that alias and sometimes this and sometimes that. :)

grzm14:05:12

Oh, I’m not asking for this being built into anything: it a feature that’s likely to be really hard to implement and satisfy everyone. I’m just trying to figure out an idiomatic way this could be approached: munging the cp string works but feels janky. inspecting deps.edn directly also feels a bit over-involved. I’ll ask in clojure or tools-deps to see if anyone there has any ideas.