mirror of
https://github.com/stablyai/orca.git
synced 2026-10-01 08:01:56 +00:00
* ci: stage heavy checks and measure affected-test selection * fix(ci): exercise the real Git boundary in unit selection planning * Harden review cancellation and CI demand reporting
85 lines
2.3 KiB
JavaScript
85 lines
2.3 KiB
JavaScript
import { globSync, readFileSync } from 'node:fs'
|
|
import { posix, join } from 'node:path'
|
|
import ts from 'typescript-api'
|
|
|
|
const EXTENSIONS = [
|
|
'',
|
|
'.ts',
|
|
'.tsx',
|
|
'.mjs',
|
|
'.js',
|
|
'.cjs',
|
|
'.json',
|
|
'/index.ts',
|
|
'/index.tsx',
|
|
'/index.js'
|
|
]
|
|
const INDIRECT_INPUT =
|
|
/\b(?:readFile\w*|readdir\w*|glob\w*|spawn\w*|execFile\w*|execSync|runProcess\w*|fork|Worker)\b|\bimport\s*\(\s*[^'"\s]|\brequire\s*\(\s*[^'"\s]|\bnew\s+URL\s*\(/
|
|
|
|
function localPath(file, specifier) {
|
|
if (specifier.startsWith('.')) {
|
|
return posix.join(posix.dirname(file), specifier)
|
|
}
|
|
if (specifier.startsWith('@renderer/')) {
|
|
return `src/renderer/src/${specifier.slice(10)}`
|
|
}
|
|
if (specifier.startsWith('@/')) {
|
|
return `src/renderer/src/${specifier.slice(2)}`
|
|
}
|
|
return null
|
|
}
|
|
|
|
export function buildUnitDependencyGraph(sources) {
|
|
const reverse = new Map()
|
|
const opaque = new Set()
|
|
for (const [file, source] of sources) {
|
|
if (INDIRECT_INPUT.test(source) || file.startsWith('config/') || file.startsWith('tests/')) {
|
|
opaque.add(file)
|
|
}
|
|
for (const imported of ts.preProcessFile(source, true, true).importedFiles) {
|
|
const path = localPath(file, imported.fileName)
|
|
if (path === null) {
|
|
continue
|
|
}
|
|
const resolved = EXTENSIONS.map((extension) => path + extension).find((candidate) =>
|
|
sources.has(candidate)
|
|
)
|
|
if (!resolved) {
|
|
opaque.add(file)
|
|
continue
|
|
}
|
|
if (!reverse.has(resolved)) {
|
|
reverse.set(resolved, new Set())
|
|
}
|
|
reverse.get(resolved).add(file)
|
|
}
|
|
}
|
|
return { reverse, opaque }
|
|
}
|
|
|
|
export function collectUnitDependencyGraph(root = process.cwd()) {
|
|
const files = globSync(
|
|
[
|
|
'src/**/*.{ts,tsx,js,mjs,cjs,json}',
|
|
'config/**/*.{ts,tsx,js,mjs,cjs,json}',
|
|
'tests/**/*.{ts,tsx,js,mjs,cjs,json}'
|
|
],
|
|
{ cwd: root }
|
|
)
|
|
const sources = new Map(
|
|
files.map((file) => [file.replaceAll('\\', '/'), readFileSync(join(root, file), 'utf8')])
|
|
)
|
|
return { ...buildUnitDependencyGraph(sources), files: new Set(sources.keys()) }
|
|
}
|
|
|
|
export function unitConsumers(seeds, reverse) {
|
|
const result = new Set(seeds)
|
|
for (const file of result) {
|
|
for (const consumer of reverse.get(file) ?? []) {
|
|
result.add(consumer)
|
|
}
|
|
}
|
|
return result
|
|
}
|