Created
February 27, 2024 20:01
-
-
Save philipjfulcher/965e896a1838df87ea206c1eb822f01d to your computer and use it in GitHub Desktop.
Churn report example
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { createProjectGraphAsync } from '@nx/devkit'; | |
import { execSync } from 'node:child_process'; | |
export async function churnGenerator( | |
) { | |
const graph = await createProjectGraphAsync(); | |
const projects: Record<string, { ancestors: number; affected: number }> = {}; | |
console.log('Calculating ancestors'); | |
for (const project in graph.dependencies) { | |
graph.dependencies[project] | |
.filter( | |
(project) => | |
!project.target.startsWith('npm') && | |
graph.nodes[project.target].type === 'lib' | |
) | |
.forEach((dependency) => { | |
if (projects[dependency.target] !== undefined) { | |
projects[dependency.target].ancestors++; | |
} else { | |
projects[dependency.target] = { | |
ancestors: 1, | |
affected: 0, | |
}; | |
} | |
}); | |
} | |
console.log(projects); | |
console.log('Calculating how often projects were affected'); | |
const gitOutput = execSync( | |
'git log --pretty=format:"%H" --since=15.days' | |
).toString('utf-8'); | |
const hashes = gitOutput.split('\n'); | |
const pairedHashes = hashes.reduce<Array<[string, string] | [string]>>( | |
(acc, cur) => { | |
const lastTuple = acc.pop(); | |
if (!lastTuple) { | |
acc.push([cur]); | |
} else if (lastTuple.length === 1) { | |
acc.push([...lastTuple, cur]); | |
} else if (lastTuple.length === 2) { | |
acc.push(lastTuple); | |
acc.push([lastTuple[1], cur]); | |
} | |
return acc; | |
}, | |
[] | |
); | |
pairedHashes.forEach((pairedHash) => { | |
const affectedOutput = execSync( | |
`yarn nx show projects --affected --head=${pairedHash[0]} --base=${pairedHash[1]}` | |
).toString('utf-8'); | |
const affected = affectedOutput.split('\n').slice(1, -1); | |
affected.forEach((project) => { | |
if (projects[project] !== undefined) { | |
projects[project].affected++; | |
} | |
}); | |
}); | |
const sortedProjects: { project: string; score: number }[] = []; | |
for (const project in projects) { | |
sortedProjects.push({ | |
project, | |
score: projects[project].affected * projects[project].ancestors, | |
}); | |
} | |
sortedProjects.sort((a, b) => b.score - a.score); | |
console.log(sortedProjects); | |
} | |
export default churnGenerator; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment