fish-shell/fish-shell at 9654f5e · static read-only analysis · why-not-rust method 2.0fish-shell/fish-shell @ 9654f5e · 静态只读分析 · why-not-rust 方法 2.0
Repository: github.com/fish-shell/fish-shell at commit 9654f5e, shallow clone, 2,205 tracked files. Scope: the whole repository, with the shell implementation as the target. This is a retrospective assessment of a completed migration, so the gates are run against the decision as it stood in January 2023 and the outcome is checked against what the project said it would buy. Sampling: at HEAD, 218 tracked .rs files hold 103,667 lines (89,836 in src/, 13,627 across 21 workspace crates). Zero files match .cpp, .cc, .cxx or .hpp, and no tracked file contains a namespace, template, or an include of <string>, <vector> or <memory>. Two native files remain: osx/osx_fish_launcher.m at 100 lines, the launcher stub for the macOS .app bundle, and tests/fish_test_helper.c at 284 lines, a dependency-free program that mimics awkward child processes so fish can test job control against it. At 4.0.0 there were three, including a 182-line src/libc.c that has since gone. Counting bases are stated wherever a comparison appears and are never mixed. The pre-port C++ baseline is 78,532 lines across 209 files at tag 3.6.0, split 64,328 lines in 104 .cpp files and 14,204 in 105 .h files; excluding the 7,345-line fish_tests.cpp gives 56,983, which reconciles with the project's own published '57k'. Rust at tag 4.0.0 was 94,638 lines in 194 files, so the growth to HEAD is 9.5%. Over the same span `unsafe` occurrences fell from 420 to 287 across 58 of 218 files. The scripting layer was never in scope: 72,635 lines of .fish under share/ are data the shell reads at runtime, and that is the structural difference from remacs, where 56,553,319 bytes of Elisp sit behind the C being ported. Timeline from the GitHub API: PR 9512 opened 2023-01-28; commit 102ab2c90 removed the FFI code and the C++ on 2024-01-01, 338 days later; 29bd6eebd removed cxx and autocxx on 2024-01-07; 4.0.0 shipped 2025-02-27, 761 days after the proposal, against an RFC estimate of 'Handwaving, 6 months?'. Between 3.7.1 (2024-03-19) and 4.0.0 there were 345 days with no release. Distinct commit authors: 96 in the twelve months to 2023-01-28, 154 in the twelve months from 2025-02-27. Objective: taken from doc_internal/fish-riir-plan.md, the project's own RFC, since no separate requirements document exists. User-supplied facts: none. No Amdahl calculation appears, because no performance requirement was ever stated and substituting a line-count share for a time share would be a method error. The decision turns on G1 and G4, both on directly measured facts; G3 passes on a structural argument, since no in-stack option changes which language contributors are asked to write. Confidence is MEDIUM rather than HIGH because the benefit that justified the work is corroborated by a correlational author count, and because concurrent function execution — the argument that selected Rust over the alternatives — has still not shipped. This is a structured decision protocol, not a statistical predictor.仓库:github.com/fish-shell/fish-shell,commit 9654f5e,shallow clone,2,205 个纳管文件。范围:整个仓库,评估目标是 shell 实现本体。这是对一次已完成迁移的回溯评估,所以四道门是按 2023 年 1 月那个时点的决策来跑的,结果则拿项目自己说要买到的东西来对。采样:HEAD 上 218 个纳管 .rs 文件共 103,667 行(src/ 里 89,836 行,21 个 workspace crate 里 13,627 行)。匹配 .cpp、.cc、.cxx、.hpp 的文件数为 0,并且没有任何纳管文件里出现 namespace、template,或 include <string>/<vector>/<memory>。留下两个原生文件:osx/osx_fish_launcher.m,100 行,macOS .app 包的启动壳;tests/fish_test_helper.c,284 行,一个不依赖 fish 的小程序,专门装成各种别扭的子进程,好让 fish 拿它测作业控制。4.0.0 时还有第三个,182 行的 src/libc.c,后来也没了。凡是出现对比的地方都写明口径,绝不混用。迁移前的 C++ 基线是 3.6.0 这个 tag 上 209 个文件、78,532 行,其中 104 个 .cpp 共 64,328 行,105 个 .h 共 14,204 行;扣掉 7,345 行的 fish_tests.cpp 得到 56,983 行,和项目自己公布的「57k」对得上。4.0.0 上的 Rust 是 194 个文件、94,638 行,到 HEAD 增长 9.5%。同一区间里,`unsafe` 出现次数从 420 降到 287,分布在 218 个文件中的 58 个。脚本层从来不在范围内:share/ 下 72,635 行 .fish 是 shell 运行时读取的数据,这正是和 remacs 的结构性差别——remacs 要移植的那些 C 后面压着 56,553,319 字节的 Elisp。时间线取自 GitHub API:PR 9512 在 2023-01-28 打开;commit 102ab2c90 在 2024-01-01 删掉 FFI 代码和 C++,距提案 338 天;29bd6eebd 在 2024-01-07 删掉 cxx 和 autocxx;4.0.0 在 2025-02-27 发布,距提案 761 天,而 RFC 的估计是「Handwaving, 6 months?」。3.7.1(2024-03-19)到 4.0.0 之间有 345 天没有任何发布。不同提交作者数:到 2023-01-28 的十二个月里 96 位,从 2025-02-27 起的十二个月里 154 位。目标:取自 doc_internal/fish-riir-plan.md,也就是项目自己的 RFC,因为没有单独的需求文档。用户提供的事实:无。本报告没有 Amdahl 计算,因为从头到尾没有人提出性能需求,而拿代码行数占比顶替时间占比是方法错误。决策落在 G1 和 G4 上,两道门都基于直接测量的事实;G3 通过靠的是结构性论证——没有任何栈内方案能改变「请贡献者写哪门语言」这件事。置信度给 MEDIUM 而不是 HIGH,一是支撑这笔投入的收益只有一个相关性的作者数在佐证,二是并发函数执行——那条让 Rust 赢过其他候选的论证——至今没有发出来。这是一套结构化决策流程,不是统计预测器。
| What we don't know证据缺口 | What it would change会改变什么 |
| A published before-and-after profile of shell startup and keystroke latency一份公开的 shell 启动与按键延迟的前后对比 profile | The parity claim is a maintainer's prose summary, not an artifact. The repository ships a benchmark harness with 15 cases and commits no results. While that is missing, D3 stays MODERATE and D4 stays WEAK.打平这个说法是维护者的文字总结,不是可核查的产物。仓库里有一套 15 个用例的基准脚手架,但没有提交任何结果。缺着它,D3 停在 MODERATE,D4 停在 WEAK。 |
| Causal evidence linking the author count to the language change把作者数变化和换语言联系起来的因果证据 | 96 to 154 distinct authors across matched twelve-month windows is the only number attached to the RFC's first objective, and it is correlation. Someone contributing a completion script is unlikely to care what the shell is written in.在两个对齐的十二个月窗口里,不同作者从 96 到 154,是 RFC 第一个目标唯一挂得上的数字,而它是相关性。提交一个补全脚本的人,大概不在意 shell 是用什么写的。 |
| Whether CI was actually green at every commit through the port迁移期间 CI 是否真的每个 commit 都绿 | The RFC required it and the project asserts it. Run-level workflow history was not checked here. It is the load-bearing G4 claim, so a reader who cares about the delivery lesson should verify it rather than take it from this report.RFC 要求过,项目也这么说。这里没有去查 workflow 的逐次运行记录。这是 G4 里吃重的一条,真在意交付这条经验的读者应该自己去核,而不是从这份报告里拿。 |