diff --git a/.changeset/three-crews-end.md b/.changeset/three-crews-end.md new file mode 100644 index 0000000..fa5e877 --- /dev/null +++ b/.changeset/three-crews-end.md @@ -0,0 +1,5 @@ +--- +'steiger': patch +--- + +Make Steiger exit with 1 if errors are reported diff --git a/packages/steiger/src/cli.ts b/packages/steiger/src/cli.ts index 7f15e2e..bdb6c9d 100755 --- a/packages/steiger/src/cli.ts +++ b/packages/steiger/src/cli.ts @@ -74,9 +74,15 @@ if (consoleArgs.watch) { }) } else { const diagnostics = await linter.run(resolve(consoleArgs._[0])) + let stillRelevantDiagnostics = diagnostics reportPretty(diagnostics, process.cwd()) + if (consoleArgs.fix) { - applyAutofixes(diagnostics) + stillRelevantDiagnostics = await applyAutofixes(diagnostics) + } + + if (stillRelevantDiagnostics.length > 0) { + process.exit(1) } } diff --git a/packages/steiger/src/features/autofix.ts b/packages/steiger/src/features/autofix.ts index ec228d4..0570149 100644 --- a/packages/steiger/src/features/autofix.ts +++ b/packages/steiger/src/features/autofix.ts @@ -2,26 +2,55 @@ import { dirname, join } from 'node:path' import { rename, open, mkdir, rm } from 'node:fs/promises' import type { Diagnostic } from '@steiger/types' -export async function applyAutofixes(diagnostics: Array) { +export async function applyAutofixes(diagnostics: Array): Promise { + const stillRelevantDiagnostics = [] + const fixableDiagnostics = [] + + for (const diagnostic of diagnostics) { + const fixes = diagnostic.fixes + + if (!fixes) { + // If we don't know how to fix, it's relevant right away + stillRelevantDiagnostics.push(diagnostic) + continue + } + + fixableDiagnostics.push(diagnostic) + } + + try { + await Promise.all(fixableDiagnostics.map(tryToApplyFixes)) + } catch (error) { + // If for some reason, a fix failed + // then assume the diagnostics are still relevant + // TODO: enhance it to push only failed fixes instead of all + stillRelevantDiagnostics.push(...fixableDiagnostics) + console.error(error) + } + + return stillRelevantDiagnostics +} + +async function tryToApplyFixes(diagnostic: Diagnostic) { + const fixes = diagnostic.fixes ?? [] + return Promise.all( - diagnostics - .flatMap((diagnostic) => diagnostic.fixes ?? []) - .map((fix) => { - switch (fix.type) { - case 'rename': - return rename(fix.path, join(dirname(fix.path), fix.newName)) - case 'create-file': - return open(fix.path, 'w').then((file) => file.close()) - case 'create-folder': - return mkdir(fix.path, { recursive: true }) - case 'delete': - return rm(fix.path, { recursive: true }) - case 'modify-file': - return open(fix.path, 'w').then(async (file) => { - await file.write(fix.content) - return file.close() - }) - } - }), + fixes.map((fix) => { + switch (fix.type) { + case 'rename': + return rename(fix.path, join(dirname(fix.path), fix.newName)) + case 'create-file': + return open(fix.path, 'w').then((file) => file.close()) + case 'create-folder': + return mkdir(fix.path, { recursive: true }) + case 'delete': + return rm(fix.path, { recursive: true }) + case 'modify-file': + return open(fix.path, 'w').then(async (file) => { + await file.write(fix.content) + return file.close() + }) + } + }), ) }