Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/weak-stars-sort.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'steiger': minor
---

Add a --ignore-warnings CLI option to report errors only.
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,12 @@ To run in watch mode, add `-w`/`--watch` to the command:
npx steiger ./src --watch
```

To report errors only and hide warnings, use `--ignore-warnings`. `--ignore-warnings` cannot be used together with `--fail-on-warnings`.

```bash
npx steiger ./src --ignore-warnings
```

## Configuration

Steiger is zero-config! If you don't want to disable certain rules, you can safely skip this section.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
Without --ignore-warnings:

┌ src/app/ui
× Layer "app" should not have "ui" segment.
└ fsd/no-ui-in-app: https://github.com/feature-sliced/steiger/tree/master/packages/steiger-plugin-fsd/src/no-ui-in-app

┌ src/processes
‼ Layer "processes" is deprecated, avoid using it
└ fsd/no-processes: https://github.com/feature-sliced/steiger/tree/master/packages/steiger-plugin-fsd/src/no-processes

─────────────────────────────────────────────────────────────
Found 1 error and 1 warning (none can be fixed automatically)


With --ignore-warnings:

┌ src/app/ui
× Layer "app" should not have "ui" segment.
└ fsd/no-ui-in-app: https://github.com/feature-sliced/steiger/tree/master/packages/steiger-plugin-fsd/src/no-ui-in-app

───────────────────────────────────────────────
Found 1 error (none can be fixed automatically)

Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
Without --ignore-warnings:

┌ src\app\ui
× Layer "app" should not have "ui" segment.
└ fsd/no-ui-in-app: https://github.com/feature-sliced/steiger/tree/master/packages/steiger-plugin-fsd/src/no-ui-in-app

┌ src\processes
‼ Layer "processes" is deprecated, avoid using it
└ fsd/no-processes: https://github.com/feature-sliced/steiger/tree/master/packages/steiger-plugin-fsd/src/no-processes

─────────────────────────────────────────────────────────────
Found 1 error and 1 warning (none can be fixed automatically)


With --ignore-warnings:

┌ src\app\ui
× Layer "app" should not have "ui" segment.
└ fsd/no-ui-in-app: https://github.com/feature-sliced/steiger/tree/master/packages/steiger-plugin-fsd/src/no-ui-in-app

───────────────────────────────────────────────
Found 1 error (none can be fixed automatically)

90 changes: 90 additions & 0 deletions integration-tests/tests/ignore-warnings.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import * as fs from 'node:fs/promises'
import os from 'node:os'
import { dirname, join } from 'node:path'
import { fileURLToPath, pathToFileURL } from 'node:url'
import { exec } from 'tinyexec'
import { replaceSymbols } from 'figures'

import { expect, test } from 'vitest'

import { getSteigerBinPath } from '../utils/get-bin-path.js'

const temporaryDirectory = await fs.realpath(os.tmpdir())
const steiger = await getSteigerBinPath()
const kitchenSinkExample = join(dirname(fileURLToPath(import.meta.url)), '../../examples/kitchen-sink-of-fsd-issues')
const fsdPluginUrl = pathToFileURL(
join(dirname(fileURLToPath(import.meta.url)), '../../packages/steiger-plugin-fsd/dist/index.js'),
).href
const pathPlatform = os.platform() === 'win32' ? 'windows' : 'posix'

test('ignores warnings in the kitchen sink example project', async () => {
const project = join(temporaryDirectory, 'ignore-warnings')

await fs.rm(project, { recursive: true, force: true })
await fs.cp(kitchenSinkExample, project, { recursive: true })

await fs.writeFile(
join(project, 'steiger.config.mjs'),
`
import fsd from ${JSON.stringify(fsdPluginUrl)}

export default [
fsd.plugin,
{
rules: {
'fsd/no-ui-in-app': 'error',
'fsd/no-processes': 'warn',
},
},
]
`,
)

let { stderr: regularStderr } = await exec('node', [steiger, 'src'], {
nodeOptions: {
cwd: project,
env: { NO_COLOR: '1' },
},
})

const ignoreWarningsRun = await exec('node', [steiger, 'src', '--ignore-warnings'], {
nodeOptions: {
cwd: project,
env: { NO_COLOR: '1' },
},
})

let ignoreWarningsStderr = ignoreWarningsRun.stderr

regularStderr = replaceSymbols(regularStderr, {
useFallback: true,
})
ignoreWarningsStderr = replaceSymbols(ignoreWarningsStderr, {
useFallback: true,
})

expect(ignoreWarningsRun.exitCode).toBe(1)

await expect(
['Without --ignore-warnings:', regularStderr, 'With --ignore-warnings:', ignoreWarningsStderr].join('\n'),
).toMatchFileSnapshot(join('__snapshots__', `ignore-warnings-stderr-${pathPlatform}.txt`))
}, 15_000)

test('does not allow ignore-warnings with fail-on-warnings', async () => {
const project = join(temporaryDirectory, 'conflicting-warning-options')

await fs.rm(project, { recursive: true, force: true })
await fs.cp(kitchenSinkExample, project, {
recursive: true,
})

const result = await exec('node', [steiger, 'src', '--ignore-warnings', '--fail-on-warnings'], {
nodeOptions: {
cwd: project,
env: { NO_COLOR: '1' },
},
})

expect(result.exitCode).not.toBe(0)
expect(result.stderr).toContain('mutually exclusive')
})
14 changes: 12 additions & 2 deletions packages/steiger/src/cli.ts
Comment thread
Solant marked this conversation as resolved.
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,12 @@ const yargsProgram = yargs(hideBin(process.argv))
describe: 'exit with an error code if there are warnings',
type: 'boolean',
})
.option('ignore-warnings', {
demandOption: false,
describe: 'report errors only',
type: 'boolean',
})
.conflicts('ignore-warnings', 'fail-on-warnings')
.option('reporter', {
demandOption: false,
describe: 'specify output format (pretty or json)',
Expand Down Expand Up @@ -116,10 +122,14 @@ if (inputPaths.length > 0) {
}

const printDiagnostics = (diagnostics: Array<Diagnostic>) => {
const diagnosticsToReport = consoleArgs['ignore-warnings']
? diagnostics.filter((diagnostic) => diagnostic.severity === 'error')
: diagnostics

if (consoleArgs.reporter === 'json') {
console.log(JSON.stringify(diagnostics, null, 2))
console.log(JSON.stringify(diagnosticsToReport, null, 2))
} else {
reportPretty(diagnostics, process.cwd())
reportPretty(diagnosticsToReport, process.cwd())
}
}

Expand Down
Loading