70 lines
2.0 KiB
JavaScript
Executable File
70 lines
2.0 KiB
JavaScript
Executable File
#!/usr/bin/env node
|
|
|
|
import { execFileSync } from 'node:child_process'
|
|
import { chmodSync, readFileSync, statSync } from 'node:fs'
|
|
import path from 'node:path'
|
|
import { pathToFileURL } from 'node:url'
|
|
|
|
export function verifyPackageCliBin({
|
|
projectDir = path.resolve(import.meta.dirname, '..', '..'),
|
|
fixExecutable = false,
|
|
runHelp = false
|
|
} = {}) {
|
|
const packageJsonPath = path.join(projectDir, 'package.json')
|
|
const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf8'))
|
|
const binTarget = packageJson.bin?.orca
|
|
if (typeof binTarget !== 'string' || binTarget.length === 0) {
|
|
throw new Error('package.json must declare bin.orca')
|
|
}
|
|
|
|
const binPath = path.resolve(projectDir, binTarget)
|
|
const stats = statSync(binPath)
|
|
if (!stats.isFile()) {
|
|
throw new Error(`bin.orca target is not a file: ${binTarget}`)
|
|
}
|
|
if (stats.size === 0) {
|
|
throw new Error(`bin.orca target is empty: ${binTarget}`)
|
|
}
|
|
|
|
const content = readFileSync(binPath, 'utf8')
|
|
if (!content.startsWith('#!/usr/bin/env node\n')) {
|
|
throw new Error(`bin.orca target must start with a Node shebang: ${binTarget}`)
|
|
}
|
|
|
|
if (process.platform !== 'win32' && (stats.mode & 0o111) === 0) {
|
|
if (!fixExecutable) {
|
|
throw new Error(`bin.orca target is not executable: ${binTarget}`)
|
|
}
|
|
chmodSync(binPath, stats.mode | 0o755)
|
|
}
|
|
|
|
if (runHelp) {
|
|
execFileSync(process.execPath, [binPath, '--help'], {
|
|
cwd: projectDir,
|
|
stdio: 'ignore'
|
|
})
|
|
}
|
|
|
|
return { binPath, size: statSync(binPath).size }
|
|
}
|
|
|
|
function main() {
|
|
const args = new Set(process.argv.slice(2))
|
|
const result = verifyPackageCliBin({
|
|
fixExecutable: args.has('--fix-executable'),
|
|
runHelp: args.has('--run-help')
|
|
})
|
|
console.log(
|
|
`[cli-bin] verified ${path.relative(process.cwd(), result.binPath)} (${result.size} bytes)`
|
|
)
|
|
}
|
|
|
|
if (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) {
|
|
try {
|
|
main()
|
|
} catch (error) {
|
|
console.error(error instanceof Error ? error.message : String(error))
|
|
process.exit(1)
|
|
}
|
|
}
|