From f187d4f5a8b60235e781ca476352f208ad12ad53 Mon Sep 17 00:00:00 2001 From: Matt Van Horn Date: Fri, 17 Apr 2026 00:11:47 -0400 Subject: [PATCH 1/2] feat(scoring): add language-specific causes of death Fixes #10 --- src/lib/scoring.test.ts | 44 +++++++++++++++++++++++++++++++++++++++++ src/lib/scoring.ts | 24 ++++++++++++++++++++++ 2 files changed, 68 insertions(+) diff --git a/src/lib/scoring.test.ts b/src/lib/scoring.test.ts index 42f6348..efbd4c0 100644 --- a/src/lib/scoring.test.ts +++ b/src/lib/scoring.test.ts @@ -267,3 +267,47 @@ test('"dependencies" returns dependency hell', () => { const repo = buildRepo({ lastCommitMessage: 'update dependencies', lastCommitDate: new Date().toISOString() }) assert.equal(generateLastWords(repo), 'trapped in dependency hell') }) + +// ── language-specific causes ─────────────────────────────────────── + +test('Ruby repo idle >365 days → Gemfile quip', () => { + const repo = buildRepo({ + language: 'Ruby', + lastCommitDate: '2023-01-01T00:00:00.000Z', + isArchived: false, + isFork: false, + openIssuesCount: 2, + stargazersCount: 5, + description: 'a gem that time forgot', + }) + const cause = determineCauseOfDeath(repo) + assert.equal(cause, 'Gemfile.lock never unlocked') +}) + +test('Perl repo returns Perl-specific cause', () => { + const repo = buildRepo({ + language: 'Perl', + lastCommitDate: '2024-01-01T00:00:00.000Z', + isArchived: false, + isFork: false, + openIssuesCount: 2, + stargazersCount: 5, + description: 'a Perl tool', + }) + const cause = determineCauseOfDeath(repo) + assert.equal(cause, 'Nobody could read it, including the author') +}) + +test('Objective-C repo idle >365 days returns Swift quip', () => { + const repo = buildRepo({ + language: 'Objective-C', + lastCommitDate: '2022-01-01T00:00:00.000Z', + isArchived: false, + isFork: false, + openIssuesCount: 2, + stargazersCount: 5, + description: 'an old iOS lib', + }) + const cause = determineCauseOfDeath(repo) + assert.equal(cause, 'Swift happened') +}) diff --git a/src/lib/scoring.ts b/src/lib/scoring.ts index 25cab40..8ef41b5 100644 --- a/src/lib/scoring.ts +++ b/src/lib/scoring.ts @@ -92,6 +92,30 @@ export function determineCauseOfDeath(repo: RepoData): string { score: isJS && daysSince > 365 ? 5 : 0, cause: 'Lost in dependency hell', }, + { + score: repo.language?.toLowerCase() === 'ruby' && daysSince > 365 ? 4 : 0, + cause: 'Gemfile.lock never unlocked', + }, + { + score: repo.language?.toLowerCase() === 'python' && daysSince > 365 ? 4 : 0, + cause: 'Pip froze, then everything else did', + }, + { + score: repo.language?.toLowerCase() === 'php' && daysSince > 365 ? 4 : 0, + cause: 'Died of PHP fatigue', + }, + { + score: repo.language?.toLowerCase() === 'perl' ? 5 : 0, + cause: 'Nobody could read it, including the author', + }, + { + score: repo.language?.toLowerCase() === 'coffeescript' ? 5 : 0, + cause: 'Outlived by the thing it inspired', + }, + { + score: repo.language?.toLowerCase() === 'objective-c' && daysSince > 365 ? 5 : 0, + cause: 'Swift happened', + }, { score: descLower.includes('microservice') || descLower.includes('enterprise') ? 5 : 0, cause: 'Killed by overengineering', From 072cb53fa6665be4e08d99d01c41b425f31a1d17 Mon Sep 17 00:00:00 2001 From: Matt Van Horn Date: Fri, 17 Apr 2026 00:51:39 -0400 Subject: [PATCH 2/2] test: prevent tie with 'Abandoned for a shinier idea' rule in language tests --- src/lib/scoring.test.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/lib/scoring.test.ts b/src/lib/scoring.test.ts index efbd4c0..88324f3 100644 --- a/src/lib/scoring.test.ts +++ b/src/lib/scoring.test.ts @@ -278,6 +278,7 @@ test('Ruby repo idle >365 days → Gemfile quip', () => { isFork: false, openIssuesCount: 2, stargazersCount: 5, + forksCount: 0, description: 'a gem that time forgot', }) const cause = determineCauseOfDeath(repo) @@ -292,6 +293,7 @@ test('Perl repo returns Perl-specific cause', () => { isFork: false, openIssuesCount: 2, stargazersCount: 5, + forksCount: 0, description: 'a Perl tool', }) const cause = determineCauseOfDeath(repo) @@ -306,6 +308,7 @@ test('Objective-C repo idle >365 days returns Swift quip', () => { isFork: false, openIssuesCount: 2, stargazersCount: 5, + forksCount: 0, description: 'an old iOS lib', }) const cause = determineCauseOfDeath(repo)