mirror of
https://github.com/djdevin/recflare.git
synced 2026-10-27 16:08:58 -07:00
145 lines
3.5 KiB
TypeScript
145 lines
3.5 KiB
TypeScript
import { Command } from '@commander-js/extra-typings'
|
|
import Table from 'cli-table3'
|
|
|
|
import { getRepoRoot } from '../path'
|
|
import { getOutcome, SHFMT_SKIPPED_EXIT_CODE } from '../proc'
|
|
|
|
export const fixCmd = new Command('fix')
|
|
.description('Fix deps/lint/format issues. If no options are provided, all fixes are run.')
|
|
|
|
.option('-r, --root', 'Run fixes from root of repo. Defaults to cwd', false)
|
|
.option('-d, --deps', 'Fix dependency versions with syncpack')
|
|
.option('-l, --lint', 'Fix oxlint issues')
|
|
.option('-f, --format', 'Format code with prettier')
|
|
.option(
|
|
'-w, --workers-types',
|
|
'Generate Workers runtime types (worker-configuration.d.ts) via wrangler types'
|
|
)
|
|
|
|
.action(async ({ root, deps, lint, format, workersTypes }) => {
|
|
const repoRoot = getRepoRoot()
|
|
if (root) {
|
|
cd(repoRoot)
|
|
}
|
|
|
|
// Run all if none are selected
|
|
if (!deps && !lint && !format && !workersTypes) {
|
|
deps = true
|
|
lint = true
|
|
format = true
|
|
workersTypes = true
|
|
}
|
|
|
|
const cwd = process.cwd()
|
|
const runFromRoot = cwd === repoRoot
|
|
const cwdName = path.basename(cwd)
|
|
|
|
const fixes = {
|
|
deps: ['run-fix-deps'],
|
|
lint: ['run-oxlint', '--fix'],
|
|
workersTypes: ['turbo', 'fix:workers-types'],
|
|
format: ['prettier', '.', '--cache', '--write', '--log-level=warn'],
|
|
formatShell: ['runx', 'shfmt', 'fix', '--skip-if-unavailable'],
|
|
} as const satisfies { [key: string]: string[] }
|
|
|
|
type TableRow = [string, string, string, string]
|
|
const table = new Table({
|
|
head: [
|
|
chalk.whiteBright('Name'),
|
|
chalk.whiteBright('Command'),
|
|
chalk.whiteBright('Outcome'),
|
|
chalk.whiteBright('Ran From'),
|
|
] satisfies TableRow,
|
|
})
|
|
|
|
$.stdio = 'inherit'
|
|
$.verbose = true
|
|
$.nothrow = true
|
|
|
|
let didErr = false
|
|
function getAndCheckOutcome({
|
|
exitCode,
|
|
skippedCode,
|
|
}: {
|
|
exitCode: number | null
|
|
skippedCode?: number
|
|
}): string {
|
|
if (exitCode !== 0 && exitCode !== skippedCode) {
|
|
didErr = true
|
|
}
|
|
return getOutcome({ exitCode, skippedCode })
|
|
}
|
|
|
|
if (deps) {
|
|
const exitCode = await $({
|
|
cwd: repoRoot, // Must be run from root
|
|
})`${fixes.deps}`.exitCode
|
|
table.push([
|
|
'deps',
|
|
fixes.deps.join(' '),
|
|
getAndCheckOutcome({ exitCode }),
|
|
'Root',
|
|
] satisfies TableRow)
|
|
}
|
|
|
|
if (lint) {
|
|
const exitCode = await $`${fixes.lint}`.exitCode
|
|
table.push([
|
|
'lint',
|
|
fixes.lint.join(' '),
|
|
getAndCheckOutcome({ exitCode }),
|
|
runFromRoot ? 'Root' : `cwd (${cwdName})`,
|
|
] satisfies TableRow)
|
|
}
|
|
|
|
if (workersTypes) {
|
|
const exitCode = await $({
|
|
cwd: repoRoot, // Must be run from root
|
|
})`${fixes.workersTypes}`.exitCode
|
|
table.push([
|
|
'workers types',
|
|
fixes.workersTypes.join(' '),
|
|
getAndCheckOutcome({ exitCode }),
|
|
runFromRoot ? 'Root' : `cwd (${cwdName})`,
|
|
] satisfies TableRow)
|
|
}
|
|
|
|
if (format) {
|
|
echo(chalk.dim('formatting with prettier (and shfmt if available)...'))
|
|
|
|
const [prettierProc, shfmtProc] = await Promise.all([
|
|
$({
|
|
cwd: repoRoot, // Must be run from root
|
|
})`${fixes.format}`,
|
|
|
|
$({
|
|
cwd: repoRoot, // Must be run from root
|
|
})`${fixes.formatShell}`,
|
|
])
|
|
|
|
table.push(
|
|
[
|
|
'format',
|
|
fixes.format.join(' '),
|
|
getAndCheckOutcome({ exitCode: prettierProc.exitCode }),
|
|
'Root',
|
|
] satisfies TableRow,
|
|
[
|
|
'format shell',
|
|
fixes.formatShell.join(' '),
|
|
getAndCheckOutcome({
|
|
exitCode: shfmtProc.exitCode,
|
|
skippedCode: SHFMT_SKIPPED_EXIT_CODE,
|
|
}),
|
|
'Root',
|
|
] satisfies TableRow
|
|
)
|
|
}
|
|
|
|
echo(table.toString())
|
|
|
|
if (didErr) {
|
|
process.exit(1)
|
|
}
|
|
})
|