mirror of
https://github.com/stablyai/orca.git
synced 2026-10-31 00:57:45 +00:00
81 lines
2.3 KiB
JavaScript
81 lines
2.3 KiB
JavaScript
import { createHash } from 'node:crypto'
|
|
import { readFileSync } from 'node:fs'
|
|
import { join } from 'node:path'
|
|
|
|
export function unitInputSourceDigest(sources) {
|
|
return createHash('sha256')
|
|
.update(JSON.stringify([...sources].sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0))))
|
|
.digest('hex')
|
|
}
|
|
|
|
function repositoryInput(path) {
|
|
return (
|
|
typeof path === 'string' &&
|
|
/^(?:src|config|tests)\//.test(path) &&
|
|
!/[\\*?[\]{}]/.test(path) &&
|
|
path
|
|
.split('/')
|
|
.every((part, index, parts) =>
|
|
part === '' ? index === parts.length - 1 : part !== '.' && part !== '..'
|
|
)
|
|
)
|
|
}
|
|
|
|
export function readUnitInputOwnership(root) {
|
|
try {
|
|
const manifest = JSON.parse(
|
|
readFileSync(join(root, 'config/scripts/ci-unit-input-ownership.json'), 'utf8')
|
|
)
|
|
return manifest?.version === 1 && Array.isArray(manifest.records) ? manifest.records : []
|
|
} catch {
|
|
return []
|
|
}
|
|
}
|
|
|
|
export function checkUnitInputOwnership(
|
|
records,
|
|
sourceClosure,
|
|
env = process.env,
|
|
contextSha256 = unitInputSourceDigest(new Map())
|
|
) {
|
|
const checked = new Map()
|
|
if (!Array.isArray(records)) {
|
|
return checked
|
|
}
|
|
const counts = new Map()
|
|
for (const record of records) {
|
|
if (typeof record?.file === 'string') {
|
|
counts.set(record.file, (counts.get(record.file) ?? 0) + 1)
|
|
}
|
|
}
|
|
for (const record of records) {
|
|
if (!record || typeof record !== 'object') {
|
|
continue
|
|
}
|
|
const { file, inputs, emptyEnv, sourceClosureSha256, reason } = record
|
|
if (
|
|
counts.get(file) !== 1 ||
|
|
!repositoryInput(file) ||
|
|
file.endsWith('/') ||
|
|
!Array.isArray(inputs) ||
|
|
!inputs.every(repositoryInput) ||
|
|
!Array.isArray(emptyEnv) ||
|
|
!emptyEnv.every((name) => typeof name === 'string' && /^[A-Z][A-Z0-9_]*$/.test(name)) ||
|
|
emptyEnv.some((name) => Boolean(env[name])) ||
|
|
typeof reason !== 'string' ||
|
|
!reason.trim() ||
|
|
typeof sourceClosureSha256 !== 'string' ||
|
|
!/^[a-f0-9]{64}$/.test(sourceClosureSha256) ||
|
|
record.contextSha256 !== contextSha256
|
|
) {
|
|
continue
|
|
}
|
|
const sources = sourceClosure(file)
|
|
if (!sources || !sources.has(file) || unitInputSourceDigest(sources) !== sourceClosureSha256) {
|
|
continue
|
|
}
|
|
checked.set(file, { inputs })
|
|
}
|
|
return checked
|
|
}
|