Skip to content

Commit c97f9bf

Browse files
authored
fix: Updated doc-check to generate config + format errors (#1255)
Closes #1273 Related: libp2p/js-libp2p#1505
1 parent fe1e121 commit c97f9bf

File tree

10 files changed

+158
-20
lines changed

10 files changed

+158
-20
lines changed

src/document-check.js

+51-20
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
/* eslint-disable no-console */
22

3+
import fs from 'fs-extra'
34
import { globby } from 'globby'
5+
import kleur from 'kleur'
46
import Listr from 'listr'
7+
import merge from 'merge-options'
58
import { compileSnippets } from 'typescript-docs-verifier'
6-
import { hasTsconfig } from './utils.js'
9+
import { formatCode, formatError, fromRoot, hasTsconfig, readJson } from './utils.js'
710
/**
811
* @typedef {import("./types").GlobalOptions} GlobalOptions
912
* @typedef {import("./types").DocsVerifierOptions} DocsVerifierOptions
@@ -23,33 +26,61 @@ const tasks = new Listr(
2326
* @param {Task} task
2427
*/
2528
task: async (ctx, task) => {
26-
let tsconfigPath = 'tsconfig.json'
27-
let markdownFiles = ['README.md']
29+
const isWindows = process.platform === 'win32'
2830

29-
if (ctx.tsConfigPath) {
30-
tsconfigPath = `${ctx.tsConfigPath}/tsconfig.json`
31-
}
31+
if (!isWindows) {
32+
const configPath = './tsconfig-doc-check.aegir.json'
3233

33-
if (ctx.inputFiles) {
34-
markdownFiles = await globby(ctx.inputFiles)
35-
}
34+
let userTSConfig = {}
35+
let markdownFiles = ['README.md']
36+
37+
if (ctx.tsConfigPath && ctx.tsConfigPath !== '.') {
38+
userTSConfig = readJson(`${ctx.tsConfigPath}/tsconfig.json`)
39+
} else {
40+
userTSConfig = readJson(fromRoot('tsconfig.json'))
41+
}
42+
43+
if (ctx.inputFiles) {
44+
markdownFiles = await globby(ctx.inputFiles)
45+
}
46+
47+
try {
48+
fs.writeJsonSync(
49+
configPath,
50+
merge.apply({ concatArrays: true }, [
51+
userTSConfig,
52+
{
53+
compilerOptions: {
54+
target: 'esnext',
55+
module: 'esnext',
56+
noImplicitAny: true,
57+
noEmit: true
58+
}
59+
}
60+
])
61+
)
62+
63+
const results = await compileSnippets({ markdownFiles, project: configPath })
3664

37-
compileSnippets({ markdownFiles, project: tsconfigPath })
38-
.then((results) => {
3965
results.forEach((result) => {
4066
if (result.error) {
41-
console.log(`Error compiling example code block ${result.index} in file ${result.file}`)
42-
console.log(result.error.message)
43-
console.log('Original code:')
44-
console.log(result.snippet)
67+
process.exitCode = 1
68+
console.log(kleur.red().bold(`Error compiling example code block ${result.index} in file ${result.file}:`))
69+
console.log(formatError(result.error))
70+
console.log(kleur.blue().bold('Original code:'))
71+
console.log(formatCode(result.snippet, result.linesWithErrors))
4572
}
4673
})
47-
})
48-
.catch((error) => {
49-
console.error('Error compiling TypeScript snippets', error)
50-
})
74+
} catch (err) {
75+
console.log('Error in trying to compile Typescript code', err)
76+
} finally {
77+
fs.removeSync(configPath)
78+
fs.removeSync(fromRoot('dist', 'tsconfig-doc-check.aegir.tsbuildinfo'))
79+
}
80+
} else {
81+
console.log(kleur.red('The underlying plugin used for TS-doc checks currently does not support Windows OS (See Github issue https://github.com/bbc/typescript-docs-verifier/issues/26). Skipping document check.'))
82+
}
5183
}
52-
5384
}
5485
],
5586
{

src/utils.js

+26
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import envPaths from 'env-paths'
1515
import { execa } from 'execa'
1616
import extract from 'extract-zip'
1717
import fs from 'fs-extra'
18+
import kleur from 'kleur'
1819
import Listr from 'listr'
1920
import { minimatch } from 'minimatch'
2021
import lockfile from 'proper-lockfile'
@@ -513,3 +514,28 @@ async function * _glob (base, dir, pattern, options) {
513514
}
514515
}
515516
}
517+
518+
/**
519+
*
520+
* @param {Error} error
521+
* @returns
522+
*/
523+
export const formatError = (error) => ' ' + error.message.split('\n').join('\n ')
524+
525+
/**
526+
*
527+
* @param {string} code
528+
* @param {number[]} errorLines
529+
* @returns
530+
*/
531+
export const formatCode = (code, errorLines) => {
532+
const lines = code.split('\n').map((line, index) => {
533+
const lineNumber = index + 1
534+
if (errorLines.includes(lineNumber)) {
535+
return kleur.red().bold(`${String(lineNumber).padStart(2)}| ${line}`)
536+
} else {
537+
return `${String(lineNumber).padStart(2)}| ${line}`
538+
}
539+
})
540+
return ' ' + lines.join('\n ')
541+
}

test/document-check.js

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/* eslint-env mocha */
2+
3+
import { createRequire } from 'module'
4+
import path from 'path'
5+
import { fileURLToPath } from 'url'
6+
import { execa } from 'execa'
7+
import { expect } from '../utils/chai.js'
8+
9+
const require = createRequire(import.meta.url)
10+
const __dirname = path.dirname(fileURLToPath(import.meta.url))
11+
const bin = require.resolve('../src/index.js')
12+
const isWindows = process.platform === 'win32'
13+
14+
describe('document check', () => {
15+
// Skip tests on windows until https://github.com/bbc/typescript-docs-verifier/issues/26 is resolved
16+
if (!isWindows) {
17+
it('should fail for errant typescript in docs', async () => {
18+
const cwd = path.join(__dirname, 'fixtures/document-check/ts-fail')
19+
20+
await expect(execa(bin, ['doc-check', '--inputFiles', `${cwd}/*.md`, '--tsConfigPath', `${cwd}`]))
21+
.to.eventually.be.rejected()
22+
.with.property('stdout')
23+
.that.include('Error compiling example code block 1')
24+
})
25+
26+
it('should pass for correct typescript in docs', async () => {
27+
const cwd = path.join(__dirname, 'fixtures/document-check/pass')
28+
29+
await expect(execa(bin, ['doc-check', '--inputFiles', `${cwd}/*.md`])).to.eventually.be.fulfilled()
30+
})
31+
32+
it('should fail for missing tsconfig.json', async () => {
33+
const cwd = path.join(__dirname, 'fixtures/document-check/tsconfig-fail')
34+
35+
await expect(execa(bin, ['doc-check', '--inputFiles', `${cwd}/*.md`, '--tsConfigPath', `${cwd}`]))
36+
.to.eventually.be.rejected()
37+
.with.property('stderr')
38+
.that.include('no such file or directory')
39+
})
40+
}
41+
})
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
```ts
2+
export const a = 1;
3+
```
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"extends": "./../../../../src/config/tsconfig.aegir.json",
3+
"compilerOptions": {
4+
"outDir": "dist",
5+
"emitDeclarationOnly": true,
6+
"isolatedModules": true
7+
},
8+
"include": [
9+
"package.json",
10+
"src",
11+
"test",
12+
"utils"
13+
]
14+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
```typescript
2+
still.bad.code
3+
```
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
```typescript
2+
wrong.code()
3+
```
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"extends": "./../../../../src/config/tsconfig.aegir.json",
3+
"compilerOptions": {
4+
"outDir": "dist",
5+
"emitDeclarationOnly": true
6+
},
7+
"include": [
8+
"package.json",
9+
"src",
10+
"test",
11+
"utils"
12+
]
13+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
```ts
2+
export const a = 1;
3+
```

test/node.js

+1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import './docs.js'
33
import './lint.js'
44
import './fixtures.js'
55
import './dependants.js'
6+
import './document-check.js'
67
import './dependency-check.js'
78
import './utils/echo-server.js'
89
import './utils/get-port.js'

0 commit comments

Comments
 (0)