eslint-seatbelt
Version:
Gradually tighten ESLint rules in your codebase
176 lines (166 loc) • 4.69 kB
text/typescript
import {
FallbackEnv,
logStderr,
SeatbeltConfig,
SeatbeltEnv,
} from "./SeatbeltConfig"
import { parse } from "ts-command-line-args"
import { SeatbeltConfigSchema } from "./jsonSchema/SeatbeltConfigSchema"
import { name, version } from "../package.json"
export interface SeatbeltCliConfig extends SeatbeltConfig {
/** Paths are relative to this directory. Default: `process.cwd()` */
pwd?: string
/** Print the version and exit */
version?: boolean
/** Command to execute. Default: `eslint` */
exec?: string
/** Show help and exit */
help?: boolean
}
const ZERO_WIDTH_SPACE = "\u200B"
function parseArgs() {
const fallback = SeatbeltConfig.fromFallbackEnv(process.env as unknown as FallbackEnv)
const overrides = SeatbeltConfig.fromEnvOverrides(process.env as unknown as SeatbeltEnv)
const env = { ...fallback, ...overrides }
const escapeForChalk = (s: string) =>
s
.replaceAll("{", "\\{")
.replaceAll("}", "\\}")
.replaceAll(/^(\s)/gm, (match) => `${ZERO_WIDTH_SPACE}${match}`)
return parse<SeatbeltCliConfig>(
{
pwd: {
type: String,
defaultValue: env.pwd ?? process.cwd(),
description: `Paths are relative to this directory`,
optional: true,
},
seatbeltFile: {
type: String,
alias: "f",
description: escapeForChalk(
SeatbeltConfigSchema.properties.seatbeltFile.description,
),
defaultValue: env.seatbeltFile,
optional: true,
},
keepRules: {
type: String,
description: escapeForChalk(
SeatbeltConfigSchema.properties.keepRules.description,
),
defaultValue: env.keepRules,
multiple: true,
optional: true,
},
allowIncreaseRules: {
alias: "r",
type: String,
description: escapeForChalk(
SeatbeltConfigSchema.properties.allowIncreaseRules.description,
),
defaultValue: env.allowIncreaseRules,
multiple: true,
optional: true,
},
frozen: {
type: Boolean,
description: escapeForChalk(
SeatbeltConfigSchema.properties.frozen.description,
),
defaultValue: env.frozen,
optional: true,
},
disable: {
type: Boolean,
description: escapeForChalk(
SeatbeltConfigSchema.properties.disable.description,
),
defaultValue: env.disable,
optional: true,
},
quiet: {
type: Boolean,
description: escapeForChalk(
SeatbeltConfigSchema.properties.quiet.description,
),
defaultValue: env.quiet,
optional: true,
},
threadsafe: {
type: Boolean,
description: escapeForChalk(
SeatbeltConfigSchema.properties.threadsafe.description,
),
defaultValue: env.threadsafe,
optional: true,
},
verbose: {
type: Boolean,
description: escapeForChalk(
SeatbeltConfigSchema.properties.verbose.description,
),
defaultValue: env.verbose,
optional: true,
},
root: {
type: String,
description: escapeForChalk(
SeatbeltConfigSchema.properties.root.description,
),
defaultValue: env.root,
optional: true,
},
version: {
type: Boolean,
description: "Print the version and exit",
optional: true,
alias: "v",
},
exec: {
type: String,
description: "Command to execute",
optional: true,
defaultValue: "eslint",
},
help: {
type: Boolean,
description: "Show help and exit",
optional: true,
alias: "h",
},
},
{
processExitCode: 2,
showHelpWhenArgsMissing: true,
helpArg: "help",
headerContentSections: [
{
header: name,
content: `Turns command-line arguments into ${name} environment variables, then call 'eslint' or another command with them.`,
},
],
},
)
}
// eslint-disable-next-line no-console
const stdout = (...args: unknown[]) => console.log(...args)
// eslint-disable-next-line no-console
const stderr = (...args: unknown[]) => console.error(...args)
function main() {
const argsConfig = parseArgs()
if (argsConfig.version) {
stdout(`v${version}`)
return
}
if (argsConfig.verbose) {
stderr("Parsed config:", argsConfig)
}
// const args = SeatbeltArgs.fromConfig(argsConfig)
logStderr("command not implemented")
process.exit(1)
}
if (require.main === module) {
main()
}