I have a problem with linting usage of plumbing.core/?>
(let [live? true]
(-> {}
(plumbing.core/?> live? (assoc :live live))))
I am receiving two :invalid-arity
errors
error: Insufficient input.
error: Expected: associative collection or nil, received: keyword.
Any thoughts on how to fix or ignore linting where it is used?Is this macro syntactically similar to one in core?
it seems similar to cond->
am I right?
@vguzar I think this macro can be regarded as deprecated in favor of clojure.core/cond->
which I think does the same, but I could be missing something
But if you want to keep using it, you can use {:lint-as {plumbing.core/?> clojure.core/cond->}}
seems like you are right that cond-> should be used instead, but I don’t think :lint-as
will work as it is used differently but let me check. By the way is it possible to deprecate by clj-kondo
?
You mean say in your config: I regard these functions are deprecated, so give me a warning when you use them?
yes, something like that
as I suspected lint-as
doesn’t help, ” No matching clause: “?>“” is shown as an error
We do have a deprecated var linter: https://github.com/clj-kondo/clj-kondo/blob/master/doc/linters.md#deprecated-var But no way to add your own vars to that. That could be useful, but it's done automatically if the var is marked deprecated in the library already
That's a weird error message. Let me try this.
I can reproduce that, but it seems like a bug
It could be useful to have your own set of deprecated 3rd party stuff, like stop use that and start use this instead
yeah, I agree. similar stuff has been considered for clojure.core/read-string
for example, but there are cases where you still might want to use that
but if a var is deprecated in favor of something else that is compatible then that config would make sense for :deprecated-var
{:deprecated-var {foo.bar/baz foo.bar/quux}}
=> Var foo.bar/baz is deprecated. Use foo.bar/quux instead
{:deprecated-var {foo.bar/baz foo.bar/quux}}
Shot from the sideline, I'd prefer to be able to specify both what should be used instead (quux), and the reason for deprecation. So if you're designing a data structure for this, I'd put a map on the right side.
Example:
{:deprecated-var {foo.bar/baz {:use-instead foo.bar/quux
:reason "baz has a bad API design, it doesn't handle X use case"}}}
yes, good idea. I also want to put a map in between: {:deprecated-var {:some-name {foo.bar/baz ...}}}
but I don't know what this name should be
Something like
{:deprecated {:vars {foo.bar/baz {:use-instead foo.bar/quux
:reason "..."}}}}
? Not sure what you want to achieve.Usually the structure is {:linter-name {:exclude {...}}
so every setting has an explicit name within the linter map
and here I have another question which could be related to what you have said in corner cases. Is it possible to mark some rules not be run on specific namespaces. For example I want
:private-call
rule fails on production code but ignore it for tests. Could I use something like
:private-call {:level :error
:exclude {:namespaces [".*-tests$"]}}
?In tests you can use #'my.private/var
or you can turn it off in the namespace config:
(ns foo
{:clj-kondo/config '{:linters {:private-call {:level :off}}}})
so it is not possible to set in configuration that some particular rule will be disabled for all namespaces matching pattern “.*-tests$“, is it?
no
This is what you use the namespace local config for
Are you using this in ClojureScript? AFAIK the Clojure compiler forbids using private vars unless via the var object
Can you create an issue about the deprecated var idea? I am fixing the bug with lint-as + cond-> as we speak.
Fixed on master
> Are you using this in ClojureScript? Yes, I’m, probably it should be okay to make them public in such case
In CLJS using #'foo/bar
also works
@borkdude issue for third-party deprecation is created https://github.com/clj-kondo/clj-kondo/issues/1207 Feel free to edit the description by itself
> In CLJS using `#'foo/bar` also works Maybe I got you wrong but this doesn’t work for cljs. (to add I am not so experience in Clojure syntax 😶) I have tried to change from
(ns test
(:require [foo :refer [bar]))
(def test-bar bar)
to
(ns test)
(def test-bar #'foo/bar)
and it fixed the linter but broken the test in the same timeYou should still require the namespace
You don't have to define test-bar, you can do it like this:
(ns test
(:require foo))
(#'foo/bar 1 2 3)
foo=> (ns foo)
WARNING: foo is a single segment namespace at line 1
nil
foo=> (def ^:private x 1)
#'foo/x
foo=> @#'foo/x
1
foo=> (ns bar (:require foo))
WARNING: bar is a single segment namespace at line 1
Execution error (ExceptionInfo) at (<cljs repl>:1).
No such namespace: foo, could not locate foo.cljs, foo.cljc, or JavaScript source providing "foo"
foo=> @#'foo/x
1
This is from a REPL sessionthanks, by bad knowledge on clojure syntax I have missed @