Skip to content

Releases: NoahTheDuke/splint

v1.15.2

09 May 13:13
Compare
Choose a tag to compare

Changed

  • Expanded documentation, added CONTRIBUTING.md.
  • Switch all existing uses of deftest (including in new_rule.tmpl) back to using defexpect. Sean fixed the 3-arg issue when I raised it in clojure-expectations/clojure-test#35, and it's nice to only import a single namespace instead of multiple.
  • Add table of namespaces to aliases in naming/conventional-aliases docs.
  • naming/record-name now uses camel-snake-kebab to check and convert the given record name to PascalCase.
  • Add :method-value style to style/new-object to suggest Foo/new instead of Foo..
  • Disable lint/dot-class-method and lint/dot-obj-method when lint/prefer-method-values is enabled.
  • Track rules on ctx instead of passing as a separate argument in runner functions.
  • Move rules from (:config ctx) to (:rules ctx) as map of rule-name to rule map. Add (:rules-by-type ctx), a map of simple-type to vector of rule names. Change check-all-rules-of-type to reduce over rule names and pull the rule map from ctx.

Fixed

  • Remove incorrect guide-ref in lint/duplicate-field-name.
  • Get auto-gen-config working again. (See #16)

v1.15.1

09 May 13:12
Compare
Choose a tag to compare

Changed

  • Updated all rules examples to use "avoid" and "prefer" instead of "bad" and "good". This aligns closer with Splint's perspective on the issues found.
  • Updated configuration docs to be more explicit about enabling and disabling rules and the use of global. (See #11 and #12)

Fixed

  • False positive in lint/assoc-fn when f is a macro. Covered or explicitly, no good generalized solution at the moment. (See #15.)
  • --print-config properly includes the genre of printed rules.

v1.15.0

01 May 14:54
Compare
Choose a tag to compare

New Rules

  • style/is-eq-order: Prefer (is (= 200 status)) over (is (= status 200)) when writing assertions.
  • style/prefer-for-with-literals: Prefer (for [item coll] {:a 1 :b item}) over (map #(hash-map :a 1 :b %) coll). (See #10.)

Added

  • -r/--require cli flag that can be used multiple times and require top-level config option that takes a vector of strings. These are loaded with load-file at run-time to allow for custom rules to be written and used. (See #8.) This is inherently unsafe, so don't run code you don't know.

Changed

  • Slight change to the patterns, now a final-position ?* or ?+ will immediately return the rest of the current input instead of accumulating it one-by-one.
  • Reformatted every file to use Tonsky's Better Clojure formatting.
  • lint/warn-on-reflection now checks that the file contains a proper ns form before issuing a diagnostic.
  • Updated README speed comparison chart.

v1.14.0

19 Feb 14:50
Compare
Choose a tag to compare

Changed

  • General performance increases in rules:

    • lint/body-unquote-splicing
    • lint/if-else-nil
    • lint/underscore-in-namespace
    • lint/warn-on-reflection
    • metrics/parameter-count
    • naming/conversion-function
    • naming/predicate
    • naming/record-name
    • naming/single-segment-namespace
    • style/def-fn
    • style/eq-zero
    • style/prefer-clj-string
    • style/prefer-condp
    • style/reduce-str
    • style/single-key-in
    • style/tostring
    • style/useless-do
  • Remove documentation about ?_ short form, as it's covered by the existing ? and _ binding rules.

  • Expand ?foo short-forms in patterns to their (? foo) special form. Simplifies matching functions, makes the pattern DSL more consistent. Now ?|foo will throw immediately instead of part-way through macroexpansion.

  • Updated pattern docs with a small example at the top.

  • Simplified ?| matcher logic to use a set, as that's faster than creating multiple read-form patterns in a let block and checking each one.

Fixed

  • Correctly suggest Obj/staticMethod when given (. Obj (staticMethod)) in lint/dot-class-usage.
  • Only suggest naming/conversion-functions when there's no - in the part before -to-. (Will warn on f-to-g, will not warn on expect-f-to-c.)
  • Correctly render args in lint/assoc-fn.

v1.13

14 Feb 14:12
Compare
Choose a tag to compare

New Rules

  • lint/prefer-method-values: Prefer (^[] String/toUpperCase "noah") to (.toUpperCase "noah"). Enabled by default.
  • lint/require-explicit-param-tags: Prefer (^[File] File/mkdir (io/file \"a\")) to (File/mkdir (io/file \"a\")). Prefer (^[String String] File/createTempFile \"abc\" \"b\") to (^[_ _] File/createTempFile \"abc\" \"b\"). Has :missing, :wildcard, and :both styles, which check for lack of any :param-tags, usage of _ in a :param-tags, and both. Defaults to :wildcard. Disabled by default.

Changed

  • Add support for lint/prefer-method-values in performance/dot-equals.
  • Switch new_rule.tmpl to use deftest. defexpect is a thin wrapper and has the annoying "if given two non-expect entries, wrap in expect", which doesn't work when we use custom expect macros.

v1.12

10 Feb 02:41
Compare
Choose a tag to compare

Added

  • re-find: and string: syntaxes for path :excludes. re-find uses clojure.core/re-find, so the regex doesn't have to match the entire file path, just any portion. string uses clojure.string/includes?, so a fixed string anywhere in the file path.

Changed

  • Updated edamame to v1.4.25 in support of the new Clojure 1.12 ^[]/:param-tags feature.

1.11

12 Dec 16:08
Compare
Choose a tag to compare

New Rules

  • lint/underscore-in-namespace: Prefer (ns foo-bar) to (ns foo_bar).
  • performance/dot-equals: Prefer (.equals "foo" bar) to (= "foo" bar). Only cares about string literals right now.
  • performance/single-literal-merge: Prefer (assoc m :a 1 :b 2) to (merge m {:a 1 :b 2}). Has :single and :multiple styles, either a single assoc call or threaded multiple calls.
  • performance/into-transducer: Prefer (into [] (map f) coll) to (into [] (map f coll)).
  • style/trivial-for: Prefer (map f items) over (for [item items] (f item)).
  • style/reduce-str: Prefer (clojure.string/join coll) over (reduce str coll).

Added

  • global top-level .splint.edn config that applies to all rules.
  • Support :excludes in both global and rules-specific configs. Accepts a vector of java.nio.file.FileSystem/getPathMatcher globs or regex syntaxes, and will default to "glob:" if the syntax portion is not specified. When in global, matching files are removed from being processed at all. When in a specific rule, the rule is disabled before matching files are checked. For example: {global {:excludes ["foo" "glob:**/bar.clj" "regex:[a-z].clj"]}}

Changed

  • Added min, max, and distinct? to lint/redundant-call.
  • Change style/set-literal-as-fn default to false. It's not idiomatic and I don't know that it's any faster either.

Fixed

  • Project file now accepts all reader macros.
  • --auto-gen-config works again, adds test.

v1.10.1

26 Jul 00:37
Compare
Choose a tag to compare

Fixed

  • performance/assoc-many should only trigger when there are more than 1 pair.

v1.10.0

25 Jul 13:32
Compare
Choose a tag to compare

The big feature here is adding support to run splint without specifying paths. Now Splint will read the deps.edn or project.clj file in the current directory and check the paths in the base definition as well as :dev and :test aliases/profiles if no path argument is given. Splint still doesn't support specifying paths in .splint.edn, nor does it allow for using paths from a project file as well as additional paths when called, but those are planned.

The second big change is moving from the old DSL to the new pangloss/pattern inspired DSL. More flexible, more usable, overall better.

The third is adding performance rules. These are off by default and are designed for those who want to pinch their cycles. Some affect common code (get-in) and some are much more rare (satisfies), but they're all designed to help you be mindful of slower paths.

Breaking

  • Moved spat.parser to splint.parser.
  • Moved spat.pattern to splint.pattern. RIP spat, you treated me well for 9 months, but keeping spat and splint separate is no longer helpful.
  • Switched to the new pattern system, updated all rules.

New Rules

  • performance/assoc-many: Prefer (-> m (assoc :k1 1) (assoc :k2 2)) over (assoc m :k1 1 :k2 2).
  • performance/avoid-satisfies: Do not use clojure.core/satisfies?, full stop.
  • performance/get-in-literals: Prefer (-> m :k1 :k2 :k3) over (get-in m [:k1 :k2 :k3]).
  • performance/get-keyword: Prefer (:k m) over (get m :k).
  • style/redundant-regex-constructor: Prefer #"abc" over (re-pattern #"abc").

Added

  • Implemented faster/more efficient versions of Clojure standard library functions:
    • ->list: concrete list building instead of apply . Useful anywhere a lazy-seq might be returned otherwise. seq/vec input: 40/43 us -> 28/15 us
    • mapv*: mapv but short-circuits empty input and uses object-array. Still unsure of this one. 36 us -> 36 us
    • run!*: run! but short-circuits empty input and uses .iterator to perform the side-effects. Does not support reduced. 7 us -> 950 ns
    • pmap*: Avoids lazy-seq overhead and relies on Java's built-in Executors. 3.34 s -> 202 ms
    • walk* and postwalk*: Primarily useful in replace, but may prove useful otherwise. Only supports simple-type defined types. 72 us -> 25 us
  • splint.config/read-project-file returns a map of :clojure-version and :paths, taken from the project file (deps.edn or project.clj) in the current directory. If no file is found, :paths is nil and :clojure-version is pulled from *clojure-version*.
  • :min-clojure-version in defrule, allowing for rules to specify the minimum version of clojure they require. Rules that are below the supported version are disabled at preparation time and can't be enabled during a run. Acceptable shape is a map of at least one of :major, :minor, and :incremental.
    • Include this in rule documentation.
  • test-helpers/with-temp-file and test-helpers/print-to-file! to test file contents.

Changed

  • Move spat.parser/parse-string and spat.parser/parse-string-all into the test-helper namespace, and replace with parse-file which accepts the file-obj map.
  • Parse data reader/tagged literals as maps instead of lists, and put the extension (dialect) into the symbol's metadata.
  • Defer building cli summary until needed.
  • Use new splint.config/slurp-edn to read config files, parsed with [edamame][edamame].
  • Changed :spat/lit metadata to :splint/lit. :spat/lit still works for the time being, but no promises.
  • splint.printer/print-results now accepts only the results object, which should additionally have :checked-files and :total-time.
  • Output formats simple, full, and clj-kondo now print the number of files checked as well: "Linting took 1ms, checked 3 files, 3 style warnings"
  • Moved splint.replace/revert-splint-reader-macros into splint.printer where it belongs.
  • Rely on undefined behavior in symbol to correctly print unprintable special characters by converting sexprs to strings and then converting those to symbols.
  • Move simple-type and drop-quote to splint.utils.

v1.9.0

25 Jul 13:30
Compare
Choose a tag to compare

New Rules

  • style/prefer-clj-string: Prefer clojure.string functions over raw interop. Defaults to true.

Added

  • --[no]summary cli flag to print or not print the summary line.

Changed

  • :filename in Diagnostic is now a java.io.File object, not a string. This is propogated through everything. I suspect no one is using these so I think I could change the Diagnostic as well, but maybe I'll wait a min.
  • make-edamame-opts now accepts both features and ns-state, and parse-string and parse-string-all take in features instead of ns-state.
  • The runner tracks the filetype of each file and runs over cljc files twice, both clj and cljs, with their respective sides of the reader conditionals applied.
  • Diagnostics are deduped before printing.
  • lint/warn-on-reflection only runs in clj files.
  • Remove farolero. Didn't provide any benefits over judicious try/catch use. :(
  • Extend the matcher-combinators.core/Matcher protocol to java.io.File, making match? work nicely with both strings and file objects.
  • Performance improvements by converting rules-by-type from a map of simple-type -> map of rule name -> rule to simple-type -> vec of rule.

Fixed

  • Correctly print special characters/clojure.core vars (@, not splint/deref, etc).