bhauman / bhauman/clojure-mcp-light

run-cljfmt detects with default rules but fixes with user config, skipping files when they disagree

Open
#31 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Clojure
Stars
188
Forks
25
PR merge metrics
No merged PRs in 30d

Description

`run-cljfmt` in `src/clojure_mcp_light/hook.clj` decides whether to format using cljfmt's
defaults, then formats using the user's config:

```clojure
(let [original (slurp file-path :encoding "UTF-8")
formatted (cljfmt/reformat-string original)] ; library call — default rules, no .cljfmt.edn
(if (not= original formatted)
(cljfmt.main/-main "fix" file-path) ; CLI entry — reads .cljfmt.edn
...))
```

The comment says this "avoids shell spawn for check while respecting user's cljfmt config for
formatting". That holds while the two agree. When they disagree, the detector answers a
different question than the fixer.

The effect is one-sided:

- Wrong under both: the detector fires and `cljfmt.main` applies the user config. Correct.
- Correct under defaults, wrong under user config: the detector sees no diff, returns early,
and `cljfmt.main` never runs. The file is left unformatted.

The second case is where a custom `.cljfmt.edn` has effect, so the config is ignored in the
situation it was written for.

## Reproducing

`.cljfmt.edn` with a custom indent:

```clojure
{:extra-indents {alet [[:block 1]]}}
```

and a file:

```clojure
(defn f [x]
(alet [v (get x :k)]
{:one 1}))
```

The `alet` body is indented as a function-call argument, which is what default cljfmt
produces, so `reformat-string` reports no change and the hook returns early. Running
`cljfmt fix` by hand in the same directory re-indents the body to `:block 1`.

Verified by driving the hook with a `PostToolUse`/`Write` payload against this file, with and
without a local patch removing the fast path: unpatched leaves the file unchanged, patched
formats it. A control file that is misformatted under default rules is formatted in both
cases.

The same applies to any non-default option — `:align-map-columns?`, `:align-form-columns?`
and the `:remove-*` flags all change what counts as correctly formatted.

## Possible fixes

1. Drop the fast path and always call `cljfmt.main/-main "fix"`, comparing file contents
before and after to report whether anything changed.
2. Load the user's config and pass it to `reformat-string` so detection and fixing use the
same rules.

I can send a PR for either if you have a preference.

Found at `d341c239d4b1faa58ccefaf8bc0b1e2a312e2af4`; `HEAD` looks unchanged.

Contributor guide

No contributing guide indexed for this repository

Research direction

Start in src/clojure_mcp_light/hook.clj at run-cljfmt, then reproduce the issue with the shown .cljfmt.edn extra-indents setting and a PostToolUse/Write payload. Compare the default-rule detection with cljfmt fix using the user configuration. Done means custom formatting options are honored, while the control case that violates default rules still formats correctly.

Written by the indexing model from the issue text.

Assessment

Tech stack
clojure
Domain
tooling
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
76/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.