Linting is just having tools look for common mistakes and reporting if they find any.
Whereas we automatically format our code to avoid fights, we lint our code to make sure that needed fights are had.
clj-kondo
to your deps.edn{:paths ["src"]
:deps {org.clojure/clojure {:mvn/version "1.12.0"}
ring/ring {:mvn/version "1.13.0"}
metosin/reitit-ring {:mvn/version "0.7.2"}
org.clojure/tools.logging {:mvn/version "1.3.0"}
org.slf4j/slf4j-simple {:mvn/version "2.0.16"}
hiccup/hiccup {:mvn/version "2.0.0-RC3"}}
:aliases {:nREPL
{:extra-paths ["dev"]
:extra-deps
{nrepl/nrepl {:mvn/version "1.3.0"}}}
:dev {:extra-paths ["dev"]}
:format {:deps {dev.weavejester/cljfmt {:mvn/version "0.13.0"}}}
:lint {:deps {clj-kondo/clj-kondo {:mvn/version "2024.09.27"}}}}}
.clj-kondo/config.edn
This file is where you can put configuration for clj-kondo
. There
are some nasty bugs that can come with unexpected reflection, so lets turn that warning on.
{:linters {:warn-on-reflection {:level :warning}}}
Justfile
for linting your code
help:
just --list
run:
clojure -M -m example.main
nrepl:
clojure -M:nREPL -m nrepl.cmdline
format_check:
clojure -M:format -m cljfmt.main check src dev
format:
clojure -M:format -m cljfmt.main fix src dev
lint:
clojure -M:lint -m clj-kondo.main --lint .
just lint
This will show any places in the code the linter thinks are problematic.
$ just lint
clojure -M:lint -m clj-kondo.main --lint .
./src/example/routes.clj:7:4: warning: unused binding system
./src/example/routes.clj:7:11: warning: unused binding request
./src/example/routes.clj:17:4: warning: unused binding system
./src/example/routes.clj:17:11: warning: unused binding request
./src/example/system.clj:15:3: warning: Var *warn-on-reflection* is not set in this namespace.
For fixing unused bindings, you can either remove the binding or prefix it with _
.
(ns example.routes
(:require [clojure.tools.logging :as log]
[hiccup2.core :as hiccup]
[reitit.ring :as reitit-ring]))
(defn hello-handler
[_system _request]
{:status 200
:headers {"Content-Type" "text/html"}
:body (str
(hiccup/html
[:html
[:body
[:h1 "Hello, world"]]]))})
(defn goodbye-handler
[_system _request]
{:status 200
:headers {"Content-Type" "text/html"}
:body (str
(hiccup/html
[:html
[:body
[:h1 "Goodbye, world"]]]))})
...
And that :warn-on-reflection
linter will have you add
(set! *warn-on-reflection* true)
to any files doing Java interop.
(ns example.system
(:require [example.routes :as routes]
[ring.adapter.jetty :as jetty])
(:import (org.eclipse.jetty.server Server)))
(set! *warn-on-reflection* true)
(defn start-server
[system]
(jetty/run-jetty
(partial #'routes/root-handler system)
{:port 9999
:join? false}))
(defn stop-server
[server]
(Server/.stop server))
...