a44c7c21e466
count a repo's lines as source lines only: files in a known language, tests, docs and data left out, recounting existing mirrors once (v3.0.104)
- time
- 2026-09-29 18:11 UTC · 2 weeks ago
- machine
- Junes-MacBook-Pro.local
- agent
- claude-opus-5-5
- session
- match kepr 2 repo page
- parent
- b420f182b4cc
↓ kepr-a44c7c21.tar.gzatlas at this save
files changed3 files
package.json+1 −1src/mirror/store.ts+12 −6tests/sync.test.ts+3 −4package.json+1 −1
@@ -1,6 +1,6 @@11 {22 "name": "kepr",3- "version": "3.0.103",3+ "version": "3.0.104",44 "private": true,55 "type": "module",66 "scripts": {src/mirror/store.ts+12 −6
@@ -102,6 +102,10 @@102102 103103 // Vendored code is someone else's: counting Koh 3's bundled SQLite made it read as 290k lines of C.104104 const VENDORED = /(^|\/)(vendor|third_party|node_modules)\//;105+// Tests are not the program: counted, Koh 3's read as 18k lines of V where it has 11k.106+const TEST = /(^|\/)(tests?|__tests__)\/|_test\.|\.(test|spec)\.|(^|\/)test_[^/]*\.py$/;107+// Bumped when what counts as a line changes, so every mirror recounts once when it opens.108+const STATS_RULE = "source-only";105109 106110 const open = new Map<string, Database>();107111 @@ -131,9 +135,8 @@131135 db.run(`PRAGMA user_version = ${SCHEMA_VERSION}`);132136 })();133137 }134- // Mirrors whose stats predate `stats_save` (per-language lines, counted past checkpoints) are135- // recounted now, not at the next save.136- if (mirrorState(db, "head") && mirrorState(db, "stats_save") === null) refreshStats(db);138+ // Mirrors counted under an older rule are recounted now, not at the next save.139+ if (mirrorState(db, "head") && mirrorState(db, "stats_rule") !== STATS_RULE) refreshStats(db);137140 open.set(path, db);138141 return db;139142 }@@ -242,6 +245,7 @@242245 243246 // Lines and languages never change between syncs, so they are counted once here, not per view. They244247 // come from the newest real save, not `head`: a checkpoint's files are not public history (§21.4).248+// Lines are source lines: files in a known language, tests left out; docs and data never count.245249 function refreshStats(db: Database): void {246250 const save =247251 db@@ -257,15 +261,16 @@257261 let lines = 0;258262 const byLanguage = new Map<string, number>();259263 for (const file of files) {260- if (VENDORED.test(file.path) || file.size > MAX_COUNTED) continue;264+ const language = LANGUAGES[file.path.split(".").pop() ?? ""];265+ if (!language || VENDORED.test(file.path) || TEST.test(file.path)) continue;266+ if (file.size > MAX_COUNTED) continue;261267 const bytes = inflateSync(file.data);262268 if (bytes.includes(0)) continue;263269 let count = 0;264270 for (const byte of bytes) if (byte === 10) count++;265271 if (bytes.length > 0 && bytes[bytes.length - 1] !== 10) count++;266272 lines += count;267- const language = LANGUAGES[file.path.split(".").pop() ?? ""];268- if (language) byLanguage.set(language, (byLanguage.get(language) ?? 0) + count);273+ byLanguage.set(language, (byLanguage.get(language) ?? 0) + count);269274 }270275 const languages = [...byLanguage].sort((a, b) => b[1] - a[1]);271276 const setState = db.query("INSERT OR REPLACE INTO state (key, value) VALUES (?, ?)");@@ -273,4 +278,5 @@273278 setState.run("language", languages[0]?.[0] ?? "");274279 setState.run("languages", JSON.stringify(languages));275280 setState.run("stats_save", save);281+ setState.run("stats_rule", STATS_RULE);276282 }tests/sync.test.ts+3 −4
@@ -86,10 +86,9 @@8686 const stats = repoStats(t.mirror());8787 expect(stats.saves).toBe(3);8888 expect(stats.language).toBe("TypeScript");89- // README 9 + guide 3 + secret 1 + util 1 + main 2 + .kohignore90- expect(stats.lines).toBeGreaterThan(16);91- // vendor/big.c's 100 lines of C count toward neither.92- expect(stats.lines).toBeLessThan(100);89+ // Source lines only: util.ts 2 + main.ts 2. The README, guide, secret and .kohignore are not90+ // code, and vendor/big.c's 100 lines of C are someone else's.91+ expect(stats.lines).toBe(4);9392 expect(stats.updated).toBe(saveByPrefix(t.mirror(), head())?.created_at ?? -1);9493 });9594