1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
[]
= "codediff"
= "0.0.7"
= "2024"
= "1.85"
= "Fast, robust, syntax-aware code diffing using tree-sitter ASTs"
= "AGPL-3.0-or-later"
= "https://github.com/ivankovic/codediff"
= "README.md"
= ["diff", "ast", "tree-sitter", "cli", "git"]
= ["command-line-utilities", "development-tools", "text-processing"]
= [
"research/**",
# Checkout-only: the `stats`- and `test-fixtures`-gated [[bin]] targets below (ten total)
# cannot be built from the published/packaged crate once their source is excluded here
# (confirmed via `cargo package` + a build against the extracted tarball with `--features
# stats`: cargo reports no such bin target at all). That's intentional - these are
# dataset-analysis/dev-fixture-curation tools, not part of the published product (see README's
# Installation section) - but nothing else signals this boundary, so `cargo install codediff
# --features stats` fails with a confusing error rather than an explanatory one. Noted here for
# whoever next touches this.
"src/bin/**",
"src/test/data/**",
]
# No [profile.release] section existed before this (2026-07-25, speed-goal investigation) - Cargo's
# own defaults (codegen-units = 16, lto = false) leave real, free performance on the table for a
# CPU-bound algorithmic tool like this one. `lto = "fat"` lets the optimizer see across crate
# boundaries (tree-sitter, the APTED engine's own module split); `codegen-units = 1` trades slower
# release builds for better cross-function inlining within this crate. Pure compiler-flag change -
# zero source code touched, output is bit-for-bit the same algorithm, so this carries none of the
# correctness risk a concurrency or algorithmic change would.
[]
= "fat"
= 1
[]
= "1.0.100"
= { = "4.5.51", = ["derive"] }
# TUI-only, but also used directly by src/bin/human_solver.rs's own small debug UI - gated by the
# `tui` feature (see [features] below), not unconditional: a pure library consumer of
# `codediff::diff`/`codediff::code` has no use for it.
= { = "2.0.0", = true }
# Only used by src/stats/ (feature-gated) and the stats-gated src/bin/ tools that need concurrent
# filesystem walks (file_stats.rs, commit_stats.rs) - gated the same way as git2/rusqlite below.
= { = "0.5.15", = true }
# Used by both the stats-gated dev tools (materialize_test_diffs.rs, sample_code_pairs.rs,
# sample_test_diffs.rs, benchmark_diff_pairs.rs) and the three that only need test fixtures
# (human_solver.rs, benchmark_optimal_solutions.rs, benchmark_other.rs) - gated by `test-fixtures`,
# which `stats` also includes (see [features] below), so either feature alone is sufficient.
= { = "1.4.0", = true }
= { = "0.20.3", = true }
# Only used by src/stats.rs itself - gated the same way as the rest of the stats-only deps.
= { = "2.0.7", = true }
# Only used by src/bin/file_stats.rs (stats-gated).
= { = "0.2", = true }
# Only used by src/bin/file_stats.rs and commit_stats.rs (both stats-gated).
= { = "1.17.0", = true }
# Only used by src/stats/sampling.rs (feature-gated) and the stats-gated sample_*.rs dev tools.
= { = "0.8", = true }
= "1.12.2"
# Bundled/C-compiled, and (like git2 just above) only used by two of the stats-gated src/bin/
# tools (commit_stats.rs, file_stats.rs) - gated the same way for the same reason: the main
# codediff binary/library has no use for it, so it shouldn't be a mandatory build-time cost for
# every `cargo install`/library consumer.
= { = "0.37.0", = ["bundled"], = true }
= { = "1.0.228", = ["derive"] }
= "1.0"
= "3.10.1"
= "0.3"
# TUI-only, but also used directly by src/bin/commit_stats.rs for concurrent I/O - gated by `tui`,
# same reasoning as confy above.
= { = "1.0", = ["full"], = true }
= "0.25"
# TUI-only (see `tui` feature below) - also used directly by src/bin/human_solver.rs's own small
# debug UI, same as confy/crossterm's siblings above.
= { = "0.26.3", = ["serde", "macros"], = true }
= { = "0.27.0", = ["serde", "event-stream"], = true }
= "0.25"
= "0.24"
= "0.23"
= "0.23"
= "0.25"
= "0.25"
= "0.23"
= "0.23"
= "0.25"
= "0.24"
= "1.1"
= "0.2"
= "0.24"
= "0.25"
= "1.2"
= "0.23.1"
= "0.24"
= "0.24"
= "0.7"
= "0.23"
= "0.4"
= "0.7.0"
= "0.7"
= "2"
= "1.0.7"
= "2.1"
= "0.1.44"
= { = "0.3.23", = ["env-filter", "serde"]}
= "0.2.1"
= { = "0.28.0", = ["derive"] }
# TUI-only - gated by `tui` below.
= { = "0.4.4", = true }
= { = "5.2", = ["default-fancy"], = true }
= { = "0.5.2", = false, = ["syntect-fancy"], = true }
[]
= "1.38.0"
[]
# `tui` on by default so a bare `cargo build`/`cargo install codediff` keeps producing the working
# `codediff` TUI binary, exactly as before this feature existed - a pure library consumer can still
# opt out entirely via `default-features = false`, which was not possible at all before (every one
# of these deps used to be unconditional).
= ["tui"]
# Everything the TUI (src/tui/, src/main.rs) needs. Also required by `test-fixtures`/`stats` below,
# since a couple of the dev-tool bins those gate use some of these deps directly for their own
# unrelated purposes (human_solver.rs has its own small ratatui-based debug UI; commit_stats.rs
# uses tokio for concurrent I/O) - simpler to have every dev-tool feature imply `tui` than to track
# exactly which of these 6 deps each individual bin happens to need.
= ["dep:ratatui", "dep:crossterm", "dep:tokio", "dep:syntect", "dep:two-face", "dep:signal-hook", "dep:confy"]
# Gates `codediff::test` (fixture-loading helpers whose data files under src/test/data/ are
# excluded from the published crate - see this file's own `exclude` list - so the module itself
# must not be part of the crate's default public surface either, or a real dependent would see
# API that's guaranteed to fail at runtime). Needed by every src/bin/ dev tool, not just the three
# that don't otherwise need `stats` (human_solver.rs, benchmark_optimal_solutions.rs,
# benchmark_other.rs) - `stats` includes it below so the other six don't need to list it twice.
= ["dep:csv", "tui"]
# Pulls in git2 (and its openssl/libssh2 build-time deps), rusqlite (a bundled, C-compiled SQLite),
# and the rest of the git-history stats/sampling tools' dependencies for the src/bin/ tools gated
# the same way. Not needed by the main codediff binary or a library consumer, so it's opt-in to
# keep `cargo install codediff` and library consumers free of that dependency chain by default.
= [
"dep:git2",
"dep:rusqlite",
"dep:crossbeam-channel",
"dep:libc",
"dep:num_cpus",
"dep:rand",
"dep:indoc",
"test-fixtures",
]
[[]]
= "codediff"
= "src/main.rs"
= ["tui"]
[[]]
= "ascii_visualizer"
= "src/bin/ascii_visualizer.rs"
# Debug/dev tool only (a plain-text AST dump), no test-fixture or stats deps of its own - reuses
# `test-fixtures` as the general "checkout-only dev tool" gate rather than inventing a feature
# just for this one binary.
= ["test-fixtures"]
[[]]
= "human_solver"
= "src/bin/human_solver.rs"
= ["test-fixtures"]
[[]]
= "benchmark_optimal_solutions"
= "src/bin/benchmark_optimal_solutions.rs"
= ["test-fixtures"]
[[]]
= "benchmark_other"
= "src/bin/benchmark_other.rs"
= ["test-fixtures"]
[[]]
= "generate_mapping_site"
= "src/bin/generate_mapping_site.rs"
= ["test-fixtures"]
[[]]
= "analyze_human_mappings"
= "src/bin/analyze_human_mappings.rs"
= ["test-fixtures"]
[[]]
= "apted_only_worker"
= "src/bin/apted_only_worker.rs"
# Single-pair worker, spawned as a subprocess by apted_only_benchmark (stats-gated, below) -
# doesn't itself need git2/csv, but gated the same way as ascii_visualizer's own bin entry: reuse
# test-fixtures as the general "checkout-only dev tool" gate rather than inventing a feature for
# one binary with no fixture/stats dependency of its own.
= ["test-fixtures"]
[[]]
= "apted_only_benchmark"
= "src/bin/apted_only_benchmark.rs"
# Needs git2 (repo/blob access, same as benchmark_diff_pairs) and csv - both gated by `stats`.
= ["stats"]
[[]]
= "commit_stats"
= "src/bin/commit_stats.rs"
= ["stats"]
[[]]
= "materialize_test_diffs"
= "src/bin/materialize_test_diffs.rs"
= ["stats"]
[[]]
= "benchmark_diff_pairs"
= "src/bin/benchmark_diff_pairs.rs"
= ["stats"]
[[]]
= "file_stats"
= "src/bin/file_stats.rs"
= ["stats"]
[[]]
= "sample_test_diffs"
= "src/bin/sample_test_diffs.rs"
= ["stats"]
[[]]
= "sample_code_pairs"
= "src/bin/sample_code_pairs.rs"
= ["stats"]
[[]]
= "hash_benchmark"
= false
[[]]
= "optimal_iud_benchmark"
= false
[[]]
= "diff_code_benchmark"
= false
[]
= "0.5"
= ["html_reports"]