Skip to content

Commit d82ae9e

Browse files
committed
feat(lint): add output file option (close #4849)
Adds an `output-file` option to the ESLint plugin that saves lint report results to the specified file path. This mimics the [ESLint option](https://eslint.org/docs/user-guide/command-line-interface#options) of the same name.
1 parent 2652ab6 commit d82ae9e

File tree

4 files changed

+71
-2
lines changed

4 files changed

+71
-2
lines changed

packages/@vue/cli-plugin-eslint/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
--no-fix do not fix errors
1616
--max-errors specify number of errors to make build failed (default: 0)
1717
--max-warnings specify number of warnings to make build failed (default: Infinity)
18+
--output-file specify file to write report to
1819
```
1920

2021
Lints and fixes files. If no specific files are given, it lints all files in `src` and `test`.

packages/@vue/cli-plugin-eslint/__tests__/eslintPlugin.spec.js

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,3 +140,58 @@ test('should not throw when src folder is ignored by .eslintignore', async () =>
140140
// should not throw
141141
await run('vue-cli-service lint')
142142
})
143+
144+
test('should save report results to file with --output-file option', async () => {
145+
const project = await create('eslint-output-file', {
146+
plugins: {
147+
'@vue/cli-plugin-babel': {},
148+
'@vue/cli-plugin-eslint': {
149+
config: 'airbnb',
150+
lintOn: 'commit'
151+
}
152+
}
153+
})
154+
const { read, write, run } = project
155+
// should've applied airbnb autofix
156+
const main = await read('src/main.js')
157+
expect(main).toMatch(';')
158+
// remove semicolons
159+
const updatedMain = main.replace(/;/g, '')
160+
await write('src/main.js', updatedMain)
161+
162+
// result file name
163+
const resultsFile = 'lint_results.json'
164+
165+
try {
166+
// lint in JSON format to output-file
167+
await run(`vue-cli-service lint --format json --output-file ${resultsFile} --no-fix`)
168+
} catch (e) {
169+
// lint with no fix should fail
170+
expect(e.code).toBe(1)
171+
expect(e.failed).toBeTruthy()
172+
}
173+
174+
let resultsFileContents = ''
175+
176+
// results file should exist
177+
try {
178+
resultsFileContents = await read(resultsFile)
179+
} catch (e) {
180+
expect(e.code).toBe(0)
181+
expect(e.failed).toBeFalsy()
182+
}
183+
184+
// results file should not be empty
185+
expect(resultsFileContents.length).toBeGreaterThan(0)
186+
187+
// results file is valid JSON
188+
try {
189+
JSON.parse(resultsFileContents)
190+
} catch (e) {
191+
expect(e.code).toBe(0)
192+
expect(e.failed).toBeFalsy()
193+
}
194+
195+
// results file should show "Missing semicolon" errors
196+
expect(resultsFileContents).toEqual(expect.stringContaining('Missing semicolon'))
197+
})

packages/@vue/cli-plugin-eslint/index.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,9 @@ module.exports = (api, options) => {
7272
'--max-errors [limit]':
7373
'specify number of errors to make build failed (default: 0)',
7474
'--max-warnings [limit]':
75-
'specify number of warnings to make build failed (default: Infinity)'
75+
'specify number of warnings to make build failed (default: Infinity)',
76+
'--output-file [file_path]':
77+
'specify file to write report to'
7678
},
7779
details:
7880
'For more options, see https://eslint.org/docs/user-guide/command-line-interface#options'

packages/@vue/cli-plugin-eslint/lint.js

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@ const renamedArgs = {
1515
rule: 'rules',
1616
eslintrc: 'useEslintrc',
1717
c: 'configFile',
18-
config: 'configFile'
18+
config: 'configFile',
19+
'output-file': 'outputFile'
1920
}
2021

2122
module.exports = function lint (args = {}, api) {
@@ -83,6 +84,16 @@ module.exports = function lint (args = {}, api) {
8384

8485
const formatter = engine.getFormatter(args.format || 'codeframe')
8586

87+
if (config.outputFile) {
88+
const outputFilePath = path.resolve(config.outputFile)
89+
try {
90+
fs.writeFileSync(outputFilePath, formatter(report.results))
91+
log(`Lint results saved to ${chalk.blue(outputFilePath)}`)
92+
} catch (err) {
93+
log(`Error saving lint results to ${chalk.blue(outputFilePath)}: ${chalk.red(err)}`)
94+
}
95+
}
96+
8697
if (config.fix) {
8798
CLIEngine.outputFixes(report)
8899
}

0 commit comments

Comments
 (0)