All notable changes to this project will be documented in this file.
.cljs source
files via the public cljs.analyzer.api and admits both Plumatic Schema
and Malli declarations on cljs vars. .cljc files are admitted twice
(once per host language); identical findings from both passes are deduped
with their lang set to ["clj","cljs"].clojure -M:skeptic deps.edn entrypoint via skeptic.cli.main. Skeptic
is now usable from a deps.edn alias in addition to the existing
Leiningen plugin; the analyzer must load the project's namespaces, so
clj -T (tool installation) is not supported.--paths PATHS and --alias ALIAS flags (deps.edn entrypoint only) for
overriding the discovered source paths or merging additional deps.edn
aliases before path resolution.--cljs-disable flag to skip ClojureScript admission entirely. With the
flag set, .cljs files are dropped and .cljc files are admitted as
:clj-only — the :cljs reader-conditional branch is discarded.lang field on every JSONL location object identifying the host
language the reported type was admitted under: "clj", "cljs", or a
sorted JSON array ["clj","cljs"] when both passes of a .cljc file
produced the same finding.--plumatic-disable and --malli-disable CLI flags to switch off either
intake stream entirely. A disabled stream contributes no entries to the
merged type dict, no provenance, and no findings whose source matches the
disabled stream's tag (schema for --plumatic-disable, malli for
--malli-disable). --plumatic-disable additionally suppresses
:skeptic/type-overrides since overrides are a Plumatic-domain construct.
A Var declared via both streams is still admitted via the enabled one;
combining both flags leaves only Skeptic's built-in native-fn declarations.:malli/schema var
metadata. Skeptic now converts simple [:=> [:cat ...] out] function
schemas, primitive leaves, :maybe, :or, :enum, and recognized
predicate symbols into the checker type domain. Unsupported Malli forms
currently remain dynamic.Runnable, Callable, Comparator, and the java.util.function.*
single-abstract-method interfaces). Previously a :- Runnable parameter
produced a confusing (=> Any) but expected java.lang.Runnable mismatch
for any Clojure fn; now skeptic checks the source fn's arity against the
interface's abstract-method arity and casts its declared return type to
Bool for Predicate / BiPredicate, Int for Comparator, and Dyn
for the rest.--explain-full to show
fully expanded structural forms.lein skeptic runs the analysis pass under
schema.core/without-fn-validation, avoiding Plumatic Schema function
validation overhead in projects that have runtime Schema validation enabled.{(s/required-key "a") s/Int}) now check correctly: correct
call sites are no longer flagged with a spurious unexpected-key
finding, and missing-required-key cases are now reported instead of
being silently dropped. Keyword required keys were already handled
by Plumatic's short-circuit to bare keywords; the bug only affected
string and other non-keyword keys.Expected typed entry on Malli :map or other
unsupported Malli forms encountered while building the per-namespace
declaration dict.defn output is now checked per arity against the declared
return type for that specific arity, instead of comparing every analyzed
method against the first arity's declared output.(assoc nilable-map k v) (and update on a nilable map) no longer
carries a Maybe wrapper through the result, since (assoc nil k v)
returns {k v} — not nil. The nil-branch is captured by downgrading
the inner map's required keys to optional, so callers that previously
saw a spurious nullability finding now get a clean check, while callers
that depended on inner keys being required see a :map-nullable-key
finding instead of a false pass.(when (or (nil? a) (nil? b) ...) (throw ...)) now narrows every
guarded local in subsequent statements, not just the single-variable
shape. Previously a disjunctive throw-guard's De-Morgan negation was
treated as unsupported, so the rest of the enclosing do continued to
see each local as (maybe T) — yielding a spurious nullability
finding on a correct program. The conjunctive shape
(when (and (nil? a) (nil? b)) (throw)) was already handled and is
unchanged.-o/--output OUTPUT_FILE on lein skeptic so skeptic's findings, summary, or JSONL stream can be written to a file while lein/JVM chatter stays on stdout (#2).(or x fallback) no longer reports a spurious nullability error when fallback is truthy.(str/blank? a) or (some? a) guard on a {:keys [a]} destructure refines
the local a itself, not only the parent map, so downstream reads of a
see the narrowed type.org.clojars.nomicflux/skeptic and org.clojars.nomicflux/lein-skeptic, :deploy-repositories for Leiningen, CI checks that keep the library and plugin versions aligned before publish, and GitHub Actions for Release lifecycle (orchestrates phases), Change project versions (reusable version bump), and Publish to Clojars (reusable deploy to Clojars).lein skeptic -p / --porcelain for newline-delimited JSON output (one
JSON object per line), documented in the README.lein skeptic --profile for optional CPU, memory, and wall-clock profiling;
when combined with --porcelain, the profile summary is written to stderr so
stdout stays JSONL-only..skeptic/config.edn with :exclude-files (root-relative
globs that skip loading and checking matched paths) and :type-overrides
(Plumatic Schema forms evaluated with schema.core in scope and merged into
collected declarations, including :output-only overrides).:skeptic/ignore-body and :skeptic/opaque on
s/defn attribute maps, and ^{:skeptic/type T} on expressions (see README
Suppressing checks).README.md that explains what Skeptic checks, how
the plugin works, how to install it, how to interpret its reports, where to
find the algorithm reference, and how to use configuration, JSONL output,
suppressions, and a short “building from source” section.--analyzer CLI flag to print analyzer output while inspecting a
namespace.get
and merge.clojure.tools.analyzer ASTs
instead of the older macroexpansion-driven pipeline.clojure.tools.reader with source logging so
reports can preserve source text and location metadata.throw, case, and cond; numeric tower comparisons; clojure.string/blank?;
conditional branches; maybe / eq / nil edge cases; invoke analysis without
redundant walks; cyclic type graphs; preservation of map projections through
checks; and a single consolidated boundary for schema-side compatibility checks
against inferred types.Can you improve this documentation? These fine people already did:
Michael A. & Michael AndersonEdit on GitHub
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |