M-simplifier/formsmith

GitHub: M-simplifier/formsmith

Clojure 原生的后格式化、后 lint 代码美化工具,填补格式化器和静态检查器之间的惯用法空白。

Stars: 0 | Forks: 0

# formsmith `formsmith` 是针对已能运行、已格式化整洁但仍略显单薄的代码的一次 Clojure 原生美化处理。 格式化工具用于规范化代码形状。Bug 检查工具用于指出正确性问题。`formsmith` 则位于两者之后。它在 form 级别重写代码,然后对结果进行格式化,因此一次处理过程不仅能让代码更整洁,还能使其更具 Clojure 风格。 ## 状态 处于预测试阶段,但已在真实仓库中发挥作用。 当前 `v1` 的范围被刻意缩小: - 默认零配置 - 优先进行保守的自动修复 - 覆盖 CLJ、CLJS 以及初始的 ClojureDart 本地风格 - 在需要时提供同一 lint 层面的 `clj-kondo` 发现 当前的里程碑问题是: 这意味着项目目前的姿态是: - 优先考虑仓库的预测试阶段 - 版本化的 GitHub 源码发布 - 用于可合并工作的短生命周期分支与 PR - `bb ci` 作为默认的代码变更关卡 - 当重写行为或公开声明发生变动时使用 `bb benchmark-v1` - 当需要判断公开楔入声明是否确凿时使用 `bb validate-v1` - 当仅限仓库的首次运行路径或新手引导文档发生变动时使用 `bb validate-cold-start` - 在楔入声明得到证实前提供尽力而为的支持 请参阅[贡献指南](./CONTRIBUTING.md)。 当前源码发布版本:`v0.1.0-pre.7`,位于 `decbd33310ada782d9097c195284a1ad9dcd4e39`。 如果您正在通过 AI 编程代理操作该仓库,请将 [AGENTS.md](./AGENTS.md) 作为公开的 AI 操作指南,用于冷启动会话和数据包选择。 ## 为什么在有了 `clj-kondo` 和格式化工具后还要使用它? 因为在常规工具链处理之后,仍然存在一段空白。 这段空白表现为: - 能够工作但弱于惯用写法的 `if` / `when` / `cond` forms - 想要使用 `not-empty`、`if-let` 或 `when-let`,却使用了基于 `seq` 的空值检查 - 想要使用 `blank?`,却使用了空白检查 - 诸如嵌套 `let`、冗余的 `do`、冗余的 `str` 或 `when (not ...)` 的局部包装 `formsmith` 并不想取代所有的格式化工具或代码检查工具。它只想解决这最后一公里的问题。 ## 快速开始 要求: - JDK - Clojure CLI 维护者检查也会使用 Babashka。证明验证使用 Lean,或通过 Nix 来 运行 Lean,经由 `scripts/verify-proofs.sh` 实现。 从仓库运行: ``` clojure -M -m formsmith.main lint src test clojure -M -m formsmith.main check . clojure -M -m formsmith.main fix --check . clojure -M -m formsmith.main fix --check --guarded . clojure -M -m formsmith.main fix . clojure -M -m formsmith.main fix --aggressive . clojure -M -m formsmith.main baseline src test -o .formsmith-baseline.edn clojure -M -m formsmith.main profiles src test clojure -M -m formsmith.main contracts src test ``` 对于其他仓库,请添加一个消费 GitHub 源码发布的 `:formsmith` 别名。 请参阅[安装说明](./docs/install.md)和 [CI](./docs/ci.md)。 如果您只想要 `formsmith` 的发现而不合并 `clj-kondo` 的输出: ``` clojure -M -m formsmith.main lint --no-kondo src test ``` 如果您想要一个不包含任何同级基准仓库的、仅限本仓库的首次运行: ``` bash scripts/cold-start-demo.sh prepare bash scripts/cold-start-demo.sh lint bash scripts/cold-start-demo.sh preview ``` 维护者可以从一个全新的临时工作区副本验证该仅限仓库的路径,使用: ``` bb validate-cold-start ``` 感知框架的输出包括信息性配置文件、仅供报告的 LLM 契约,以及带有显式防护的狭窄局部重写。当前配置文件覆盖范围包括 re-frame、Reagent、HSX、RFX、ClojureDart、Ring、Reitit、Integrant 和 Malli。ClojureDart 支持包括 `.cljd` 文件、Flutter 字符串包依赖,以及从嵌套的 `.child` 链到 `cljd.flutter/nest` 的首个可见 Flutter UI 重写。 请参阅[框架配置文件](./docs/framework-profiles.md)。 ## 推荐工作流 1. 运行 `lint` 以查看全貌。 2. 运行 `check` 以预览 CI 可以强制执行的规范安全重写。 3. 当安全预览看起来不错时,运行 `fix`。 4. 当您想要由静态事实证明的、带有局部符号防护的分析器支持重写时,运行 `fix --guarded --check`。 5. 在整个仓库应用更广泛的语义模式重写之前,运行 `fix --aggressive --check`。 6. 当将 `formsmith` 引入现有仓库,且希望 CI 仅对新的发现报错时,使用 `baseline`。 7. 当您需要目录和安全边界时,使用 `rules` 和 `explain `。 ## 生产采用面 `formsmith` 在默认情况下会读取 `.formsmith.edn`(如果存在)。当前 最小的生产配置面是有意保持微小的: ``` {:ignore-paths ["target" "resources/generated"] :rules {:exclude [:some/rule]} :baseline ".formsmith-baseline.edn" :suppressions [{:file "src/app/core.clj" :rule-id :if/not-condition :line 42}]} ``` 在极少数局部惯用法是有意为之的情况下,支持内联抑制: ``` ;; formsmith-disable-next-line if/not-condition (if (not ready?) :wait :go) ``` 默认的 JSON 输出省略了完整的文件源码和前后对比片段,因此 CI 产物对于私有仓库来说更加安全。仅在本地调试时使用 `--include-source`。 ## 安全模型 - `syntax-safe` `formsmith` 愿意在默认的 `fix` 中自动应用的局部重写。 - `semantic-pattern` 需要 `--aggressive` 才能自动修复的强烈建议。 - `unsafe` 仅报告。这是有用的信号,但不应由工具默认重写。 两个重要命令: - `fix --check` 无写入预览。仅报告实际会应用的发现。 - `check` 用于 CI 的规范无写入检查。等同于默认的安全自动修复配置文件,但不执行写入。 - `fix --guarded` 仅在静态事实证明了当前支持的防护条件时,才应用由分析器防护的重写。 - `fix --rewrite-only` 跳过格式化阶段。当您想要直接检查重写局部性时非常有用。 ## 基准快照 截至 `2026-05-08`,`main` 分支上的当前快照: - 对 `nextmoon/src` 进行纯 `formsmith` lint:`files=18 changed=0 findings=12` - 对 `dirty-clojure/src test` 进行纯 `formsmith` lint:`files=9 changed=0 findings=9` - 对 `nextmoon/src` 的安全预览:`fix --check --rewrite-only` => `files=18 changed=1 findings=1` - 对 `dirty-clojure/src test` 的安全预览:`fix --check --rewrite-only` => `files=9 changed=2 findings=4` - 仅限 CLJS 的激进预览: - `dirty-clojure/frontend/core.cljs` => `files=1 changed=1 findings=7` - `nextmoon/ui/core.cljs` => `files=1 changed=1 findings=1` 这些数字非常重要,因为这两个基准仓库现在都在 `formsmith` 添加额外信号之前通过了其基线测试、lint 和格式检查。 当前维护者的基准数据包更具说服力: - `dirty-clojure` 是一个干净的维护者基准仓库,包含重复的 CLJ 和 CLJS 发现 - `nextmoon` 现在也是一个干净的维护者基准仓库,同时仍作为更强的真实仓库压力面 这意味着 `formsmith` 拥有两个由维护者控制的基准仓库,它们表明 在常规工具处理之后,仍然存在有意义的局部改进空间。自包含的 公开首次运行证据路径是 `bb validate-cold-start`; 更广泛的公开外部压力证据记录在 [实地试验](./docs/field-trials.md)中。 使用以下命令刷新当前矩阵: ``` bb benchmark-v1 ``` 使用以下命令验证实际的楔入证据: ``` bb validate-v1 ``` 这两个证据数据包是维护者命令,并预期存在用于 `nextmoon` 和 `dirty-clojure` 的同级基准检入。全新的公开克隆可以通过 `bb validate-cold-start` 验证捆绑的首次运行路径。 ## 命令 ``` clojure -M -m formsmith.main lint clojure -M -m formsmith.main check clojure -M -m formsmith.main fix clojure -M -m formsmith.main fmt clojure -M -m formsmith.main analyze clojure -M -m formsmith.main profiles clojure -M -m formsmith.main contracts clojure -M -m formsmith.main rules clojure -M -m formsmith.main explain ``` 示例: ``` clojure -M -m formsmith.main fix --check --rewrite-only src test clojure -M -m formsmith.main check src test clojure -M -m formsmith.main fix --check --guarded src test clojure -M -m formsmith.main fix --aggressive src test clojure -M -m formsmith.main explain condition/and-seq clojure -M -m formsmith.main analyze src test clojure -M -m formsmith.main profiles src test clojure -M -m formsmith.main contracts src test clojure -M -m formsmith.main baseline src test -o .formsmith-baseline.edn ``` ## 当前规则面 当前的规则族包括: - 冗余包装器:`redundant-do`、嵌套 `let`、冗余 `str` - 条件清理:`when-not`、`if-not`、`cond -> if/when`、`cond true -> :else` - nil 谓词:`= nil` -> `nil?`、`not= nil` -> `some?` - 关键字查找:`(get m :k)` -> `(:k m)` - 空值与空白:`seq`、`not-empty`、`blank?` - 围绕前端表单和集合检查的面向 CLJS 的局部模式 请查看实时的目录: ``` clojure -M -m formsmith.main rules clojure -M -m formsmith.main explain cond/minimal-form ``` ## 项目边界 `v1` 有意避免成为: - 格式化工具之争 - 通用 Bug 检查工具 - 仓库架构分析器 - 高度依赖配置的风格语言 当前的楔入更简单: 这正是 `formsmith v1` 试图证明的。 ## 文档 - [愿景](./docs/vision.md) - [架构](./docs/architecture.md) - [AI 操作指南](./AGENTS.md) - [安装说明](./docs/install.md) - [CI](./docs/ci.md) - [采用试验](./docs/adoption-trial.md) - [发布说明](./docs/releases/v0.1.0-pre.7.md) - [证明](./docs/proofs.md) - [v1 验证](./docs/v1-validation.md) - [快速开始](./docs/quickstart.md) - [冷启动演示](./docs/cold-start-demo.md) - [冷启动采用](./docs/cold-start-adoption.md) - [基准测试](./docs/benchmarking.md) - [语料库](./docs/corpus.md) - [压力项目](./docs/pressure-projects.md) - [实地试验](./docs/field-trials.md) - [审查消除研究](./docs/review-elimination-study.md) - [审查研究记录](./docs/review-studies/README.md) - [L5 记分卡](./docs/l5-scorecard.md)
标签:AI辅助编程, AST重写, CLJ, clj-kondo, CLJS, Clojure, ClojureDart, DevOps工具, Lisp, 云安全监控, 代码可读性, 代码审查, 代码格式化, 代码规范, 代码重构, 代码静态检查, 函数式编程, 威胁情报, 开发者工具, 操作系统探测, 自动化重构, 静态分析