65 lines
2.4 KiB
TypeScript
65 lines
2.4 KiB
TypeScript
/** Reject tracked files that expose the internal repository remote. */
|
|
|
|
import { execFileSync } from 'node:child_process'
|
|
import { existsSync, lstatSync, readFileSync, readlinkSync } from 'node:fs'
|
|
import { resolve } from 'node:path'
|
|
import { pathToFileURL } from 'node:url'
|
|
|
|
const root = resolve(import.meta.dirname, '..')
|
|
const internalRepository = ['deepseek-harness', 'deepseek-harness'].join('/')
|
|
|
|
/** One tracked reference to the internal repository. */
|
|
export interface InternalRepositoryReference {
|
|
/** Repository-relative file path. */
|
|
file: string
|
|
/** One-based source line. */
|
|
line: number
|
|
}
|
|
|
|
/**
|
|
* Locate internal-repository references in one text file.
|
|
* @param file - Repository-relative path used in diagnostics.
|
|
* @param source - Text to inspect.
|
|
* @returns every matching source line.
|
|
*/
|
|
export function findInternalRepositoryReferences(file: string, source: string): InternalRepositoryReference[] {
|
|
const references: InternalRepositoryReference[] = []
|
|
for (const [index, line] of source.split('\n').entries()) {
|
|
if (line.includes(internalRepository)) references.push({ file, line: index + 1 })
|
|
}
|
|
return references
|
|
}
|
|
|
|
function trackedFiles(repoRoot: string): string[] {
|
|
return execFileSync('git', ['ls-files', '-z'], { cwd: repoRoot, encoding: 'utf8' })
|
|
.split('\0')
|
|
.filter(file => file !== '')
|
|
}
|
|
|
|
function scanRepository(repoRoot: string): InternalRepositoryReference[] {
|
|
const references: InternalRepositoryReference[] = []
|
|
for (const file of trackedFiles(repoRoot)) {
|
|
const path = resolve(repoRoot, file)
|
|
if (!existsSync(path)) continue
|
|
const stat = lstatSync(path)
|
|
if (!stat.isFile() && !stat.isSymbolicLink()) continue
|
|
const source = stat.isSymbolicLink() ? readlinkSync(path) : readFileSync(path, 'utf8')
|
|
if (source.includes('\0')) continue
|
|
references.push(...findInternalRepositoryReferences(file, source))
|
|
}
|
|
return references
|
|
}
|
|
|
|
const invokedPath = process.argv[1]
|
|
const isMain = invokedPath !== undefined && import.meta.url === pathToFileURL(resolve(invokedPath)).href
|
|
if (isMain) {
|
|
const references = scanRepository(root)
|
|
if (references.length === 0) {
|
|
console.log('verify-public-repository-links: tracked files expose no internal repository remote.')
|
|
} else {
|
|
console.error('verify-public-repository-links: internal repository references found:')
|
|
for (const reference of references) console.error(` ${reference.file}:${String(reference.line)}`)
|
|
process.exitCode = 1
|
|
}
|
|
}
|