Skip to content

Commit 0580e0e

Browse files
committed
replace renderSync with render (async)
some refactoring
1 parent c8d88b1 commit 0580e0e

File tree

9 files changed

+104
-137
lines changed

9 files changed

+104
-137
lines changed

index.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
import path from 'path'
66
import Cache from 'cache-point'
77
import Explain from './lib/explain.js'
8-
import RenderSync from './lib/render-sync.js'
8+
import Render from './lib/render.js'
99
import arrayify from 'array-back'
1010
import os from 'node:os'
1111

@@ -41,11 +41,11 @@ async function explain (options) {
4141
* @prerequisite Requires node v0.12 or above
4242
* @static
4343
* @example
44-
* jsdoc.renderSync({ files: 'lib/*', destination: 'api-docs' })
44+
* await jsdoc.render({ files: 'lib/*', destination: 'api-docs' })
4545
*/
46-
function renderSync (options) {
46+
async function render (options) {
4747
options = new JsdocOptions(options)
48-
const command = new RenderSync(options)
48+
const command = new Render(options)
4949
return command.execute()
5050
}
5151

@@ -150,4 +150,4 @@ class JsdocOptions {
150150
}
151151
}
152152

153-
export { explain, renderSync, cache }
153+
export { explain, render, cache }

lib/explain.js

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,7 @@ import { spawn } from 'child_process'
1212
* @static
1313
*/
1414
class Explain extends JsdocCommand {
15-
getOutput (err) {
16-
if (err) return Promise.reject(err)
15+
async getOutput () {
1716
if (this.options.cache && !this.options.source) {
1817
return this.readCache().catch(this._runJsdoc.bind(this))
1918
} else {
@@ -33,6 +32,7 @@ class Explain extends JsdocCommand {
3332
.concat(this.options.source ? this.tempFile.path : this.inputFileSet.files)
3433
jsdocArgs.unshift(this.jsdocPath)
3534

35+
/* TODO: replace with exec if you're only collecting the output */
3636
const handle = spawn('node', jsdocArgs)
3737
jsdocOutput.stdout = (await streamReadAll(handle.stdout)).toString()
3838
jsdocOutput.stderr = (await streamReadAll(handle.stderr)).toString()
@@ -51,6 +51,41 @@ class Explain extends JsdocCommand {
5151
})
5252
})
5353
}
54+
55+
verifyOutput (code, output) {
56+
let parseFailed = false
57+
let parsedOutput
58+
try {
59+
parsedOutput = JSON.parse(output.stdout)
60+
} catch (err) {
61+
parseFailed = true
62+
}
63+
64+
if (code > 0 || parseFailed) {
65+
const firstLineOfStdout = output.stdout.split(/\r?\n/)[0]
66+
const err = new Error(output.stderr.trim() || firstLineOfStdout || 'Jsdoc failed.')
67+
err.name = 'JSDOC_ERROR'
68+
throw err
69+
} else {
70+
return parsedOutput
71+
}
72+
}
73+
74+
/**
75+
* Returns a cached recordset
76+
* @returns {Promise}
77+
* @fulfil {object[]}
78+
*/
79+
async readCache () {
80+
if (this.cache) {
81+
const promises = this.inputFileSet.files.map(file => fs.readFile(file, 'utf8'))
82+
const contents = await Promise.all(promises)
83+
this.cacheKey = contents.concat(this.inputFileSet.files)
84+
return this.cache.read(this.cacheKey)
85+
} else {
86+
return Promise.reject()
87+
}
88+
}
5489
}
5590

5691
export default Explain

lib/jsdoc-command.js

Lines changed: 8 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -40,95 +40,21 @@ class JsdocCommand {
4040
)
4141
}
4242

43-
/**
44-
* Template method returning the jsdoc output. Invoke later (for example via a command-queuing system) or immediately as required.
45-
*
46-
* 1. preExecute
47-
* 2. validate
48-
* 3. getOutput
49-
* 4. postExecute
50-
*
51-
*/
52-
execute () {
53-
this.preExecute()
54-
const err = this.validate()
55-
this.output = this.getOutput(err)
56-
if (this.output instanceof Promise) {
57-
return this.output
58-
.then(result => {
59-
this.postExecute()
60-
return result
61-
})
62-
.catch(err => {
63-
this.postExecute()
64-
throw err
65-
})
66-
} else {
67-
this.postExecute()
68-
return this.output
69-
}
70-
}
71-
72-
/**
73-
* Perform pre-execution processing here, e.g. expand input glob patterns.
74-
*/
75-
preExecute () {
43+
async execute () {
7644
this.inputFileSet = new FileSet(this.options.files)
77-
}
78-
79-
/**
80-
* Return an Error instance if execution should not proceed.
81-
* @returns {null|Error}
82-
*/
83-
validate () {
8445
assert.ok(
8546
this.options.files.length || this.options.source,
8647
'Must set either .files or .source'
8748
)
88-
}
89-
90-
/**
91-
* perform post-execution cleanup
92-
*/
93-
postExecute () {
94-
if (this.tempFile) {
95-
this.tempFile.delete()
96-
}
97-
}
98-
99-
verifyOutput (code, output) {
100-
let parseFailed = false
101-
let parsedOutput
49+
let result
10250
try {
103-
parsedOutput = JSON.parse(output.stdout)
104-
} catch (err) {
105-
parseFailed = true
106-
}
107-
108-
if (code > 0 || parseFailed) {
109-
const firstLineOfStdout = output.stdout.split(/\r?\n/)[0]
110-
const err = new Error(output.stderr.trim() || firstLineOfStdout || 'Jsdoc failed.')
111-
err.name = 'JSDOC_ERROR'
112-
throw err
113-
} else {
114-
return parsedOutput
115-
}
116-
}
117-
118-
/**
119-
* Returns a cached recordset
120-
* @returns {Promise}
121-
* @fulfil {object[]}
122-
*/
123-
async readCache () {
124-
if (this.cache) {
125-
const promises = this.inputFileSet.files.map(file => fs.readFile(file, 'utf8'))
126-
const contents = await Promise.all(promises)
127-
this.cacheKey = contents.concat(this.inputFileSet.files)
128-
return this.cache.read(this.cacheKey)
129-
} else {
130-
return Promise.reject()
51+
result = await this.getOutput()
52+
} finally {
53+
if (this.tempFile) {
54+
this.tempFile.delete()
55+
}
13156
}
57+
return result
13258
}
13359
}
13460

lib/render-sync.js

Lines changed: 0 additions & 19 deletions
This file was deleted.

lib/render.js

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import JsdocCommand from './jsdoc-command.js'
2+
import toSpawnArgs from 'object-to-spawn-args'
3+
import { spawn } from 'child_process'
4+
5+
/**
6+
* @static
7+
*/
8+
class Render extends JsdocCommand {
9+
async getOutput () {
10+
return new Promise((resolve, reject) => {
11+
const jsdocArgs = toSpawnArgs(this.jsdocOptions)
12+
.concat(this.options.source ? this.tempFile.path : this.options.files)
13+
14+
jsdocArgs.unshift(this.jsdocPath)
15+
const handle = spawn('node', jsdocArgs, { stdio: 'inherit' })
16+
handle.on('close', resolve)
17+
})
18+
}
19+
}
20+
21+
export default Render

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
"node": ">=12.17"
2626
},
2727
"scripts": {
28-
"test": "75lb-nature test test/*.js",
28+
"test": "75lb-nature test-runner test/*.js",
2929
"docs": "75lb-nature jsdoc2md -t jsdoc2md/README.hbs index.js lib/*.js > README.md; echo"
3030
},
3131
"dependencies": {

test/explain.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,4 +41,8 @@ test.set('.explain({ files }): generate a warning', async function () {
4141
return jsdoc.explain({ files: 'test/fixture/buggy/ignore-with-value.js' })
4242
})
4343

44+
test.set('.explain({ files }): files is empty', async function () {
45+
return jsdoc.explain({ files: [] })
46+
})
47+
4448
export { test, only, skip }

test/render-sync.js

Lines changed: 0 additions & 28 deletions
This file was deleted.

test/render.js

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import * as jsdoc from 'jsdoc-api'
2+
import Fixture from './lib/fixture.js'
3+
import { statSync } from 'fs'
4+
import { strict as a } from 'assert'
5+
6+
const [test, only, skip] = [new Map(), new Map(), new Map()]
7+
8+
test.set('.render({ files })', async function () {
9+
Fixture.createTmpFolder('tmp')
10+
Fixture.createTmpFolder('tmp/render')
11+
const f = new Fixture('class-all')
12+
await jsdoc.render({ files: f.sourcePath, destination: 'tmp/render/out' })
13+
a.doesNotThrow(function () {
14+
statSync('./tmp/render/out/index.html')
15+
})
16+
})
17+
18+
test.set('.render({ source, destination })', async function () {
19+
Fixture.createTmpFolder('tmp')
20+
Fixture.createTmpFolder('tmp/render')
21+
const f = new Fixture('class-all')
22+
await jsdoc.render({ source: f.getSource(), destination: 'tmp/render/out' })
23+
a.doesNotThrow(function () {
24+
statSync('./tmp/render/out/index.html')
25+
})
26+
})
27+
28+
export { test, only, skip }

0 commit comments

Comments
 (0)