Skip to content

Commit

Permalink
Merge 154efa2 into fee737e
Browse files Browse the repository at this point in the history
  • Loading branch information
mbland committed Dec 29, 2023
2 parents fee737e + 154efa2 commit 6b1b150
Show file tree
Hide file tree
Showing 10 changed files with 120 additions and 84 deletions.
2 changes: 0 additions & 2 deletions LICENSE.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
Copyright (c) 2023 Mike Bland <mbland@acm.org>

Mozilla Public License Version 2.0
==================================

Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ Source: <https://github.com/mbland/jsdoc-cli-wrapper>
[![CI status](https://github.com/mbland/jsdoc-cli-wrapper/actions/workflows/run-tests.yaml/badge.svg)](https://github.com/mbland/jsdoc-cli-wrapper/actions/workflows/run-tests.yaml?branch=main)
[![Test results](https://github.com/mbland/jsdoc-cli-wrapper/actions/workflows/publish-test-results.yaml/badge.svg)](https://github.com/mbland/jsdoc-cli-wrapper/actions/workflows/publish-test-results.yaml?branch=main)
[![Coverage Status](https://coveralls.io/repos/github/mbland/jsdoc-cli-wrapper/badge.svg?branch=main)][coveralls-jsdw]
[![npm version](https://badge.fury.io/js/jsdoc-cli-wrapper.svg)][npm-jsdw]

## Installation

Expand Down Expand Up @@ -145,6 +146,7 @@ Node.js, JSDoc, and [npm packaging][] exercise as well.
[JSDoc]: https://jsdoc.app/
[cli]: https://github.com/jsdoc/jsdoc
[coveralls-jsdw]: https://coveralls.io/github/mbland/jsdoc-cli-wrapper?branch=main
[npm-jsdw]: https://www.npmjs.com/package/jsdoc-cli-wrapper
[pnpm]: https://pnpm.io/
[mbland/tomcat-servlet-testing-example]: https://github.com/mbland/tomcat-servlet-testing-example
[Gradle]: https://gradle.org/
Expand Down
1 change: 1 addition & 0 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
* Removes the existing destination directory if it exists, runs JSDoc, and
* emits the relative path to the generated index.html file.
* @author Mike Bland <mbland@acm.org>
* @license MPL-2.0
*/

import { runJsdoc } from './lib/index.js'
Expand Down
20 changes: 10 additions & 10 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ import path from 'node:path'
* @param {string[]} argv - JSDoc command line interface arguments
* @param {object} env - environment variables, presumably process.env
* @param {string} platform - the process.platform string
* @returns {Promise<RunJsdocResults>} - result of `jsdoc` execution
* @returns {Promise<RunJsdocResults>} result of `jsdoc` execution
* @throws if `jsdoc` isn't found or can't execute
*/
export async function runJsdoc(argv, env, platform) {
let jsdocPath
Expand Down Expand Up @@ -56,17 +57,18 @@ export async function runJsdoc(argv, env, platform) {
/**
* Determines the key for the command search path within process.env.
* @param {string} platform - the process.platform string
* @returns {string} - On every platform other than 'win32', this will be "PATH"
* @returns {string} On every platform other than 'win32', this will be "PATH"
* On 'win32', this will be "Path".
*/
export const pathKey = (platform) => platform !== 'win32' ? 'PATH' : 'Path'
export const pathKey = platform => platform !== 'win32' ? 'PATH' : 'Path'

/**
* Returns the full path to the specified command
* @param {string} cmdName - command to find in env[pathKey(platform)]
* @param {object} env - environment variables, presumably process.env
* @param {string} platform - the process.platform string
* @returns {Promise<string>} - path to the command
* @returns {Promise<string>} path to the command
* @throws if `jsdoc` isn't found
*/
export async function getPath(cmdName, env, platform) {
const pk = pathKey(platform)
Expand Down Expand Up @@ -95,17 +97,14 @@ export async function getPath(cmdName, env, platform) {
/**
* Analyzes JSDoc CLI args to determine if JSDoc will generate docs and where
* @param {string[]} argv - JSDoc command line interface arguments
* @returns {Promise<ArgvResults>} - analysis results
* @returns {Promise<ArgvResults>} analysis results
*/
export async function analyzeArgv(argv) {
const validArg = nextArg => nextArg !== undefined && !nextArg.startsWith('-')
let destination = undefined
let willGenerate = true
let cmdLineDest = false

const validArg = (nextArg) => (
nextArg !== undefined && !nextArg.startsWith('-')
)

for (let i = 0; i !== argv.length; ++i) {
const arg = argv[i]
const nextArg = argv[i+1]
Expand Down Expand Up @@ -148,7 +147,8 @@ export async function analyzeArgv(argv) {
* Searches for filename within a directory tree via breadth-first search
* @param {string} dirname - current directory to search
* @param {string} filename - name of file to find
* @returns {Promise<string>} - path to filename within dirname
* @returns {Promise<string>} path to filename within dirname
* @throws if filename not found
*/
export async function findFile(dirname, filename) {
const childDirs = [dirname]
Expand Down
4 changes: 4 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,17 @@
"test:ci": "eslint --color --max-warnings 0 . && vitest run -c ci/vitest.config.js",
"jsdoc": "node index.js -c jsdoc.json ."
},
"files": [ "lib/**" ],
"keywords": [
"jsdoc",
"JavaScript"
],
"author": "Mike Bland <mbland@acm.org> (https://mike-bland.com/)",
"license": "MPL-2.0",
"type": "module",
"engines": {
"node": ">= 18.0.0"
},
"homepage": "https://github.com/mbland/jsdoc-cli-wrapper",
"repository": "https://github.com/mbland/jsdoc-cli-wrapper",
"bugs": "https://github.com/mbland/jsdoc-cli-wrapperr/issues",
Expand Down
100 changes: 31 additions & 69 deletions test/fixtures/jsdocStub/jsdoc
Original file line number Diff line number Diff line change
@@ -1,69 +1,31 @@
#!/usr/bin/env node
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/

/**
* Fake jsdoc implementation for testing
*/

import { mkdir, writeFile } from 'node:fs/promises'
import path from 'node:path'
import { exit } from 'node:process'

try {
const {willGenerate, destination, exitCode} = parseArgs(process.argv.slice(2))

if (willGenerate && exitCode === 0) {
const newSubDir = path.join(destination, 'new-subdir')
await mkdir(newSubDir, {recursive: true})
await writeFile(path.join(newSubDir, 'index.html'), 'New Hotness')
}
exit(exitCode)

} catch (err) {
console.error(err)
exit(1)
}

/**
* The parameters parsed from process.argv by parseArgs()
* @typedef {object} ArgsResult
* @property {string} destination - the JSDoc destination directory
* @property {boolean} willGenerate - true unless -h or --no-input-files present
* @property {number} exitCode - the value of --exit-code or 0 by default
*/

/**
* Parses fake jsdoc arguments
* @param {string[]} argv - command line arguments
* @returns {ArgsResult} - parameters determining fake jsdoc behavior
*/
function parseArgs(argv) {
let destination = null
let willGenerate = true
let exitCode = 0

for (let i = 0; i !== argv.length; ++i) {
const arg = argv[i]
const nextArg = argv[i+1]

switch (arg) {
case '-d':
destination = nextArg
break

case '-h':
case '--no-input-files':
willGenerate = false
break

case '--exit-code':
exitCode = nextArg
break
}
}
return {willGenerate, destination, exitCode}
}
#!/bin/sh
#
# Wraps the jsdoc.js command on non-Windows platforms.
#
# This is necessary to support older Node versions as package.json engines
# without removing the `"type": "module"` specifier. Without this shim, running
# `pnpm test` under many older verions caused runJsdoc.test.js and main.test.js
# to fail on the spawn(jsdocPath) call within runJsdoc().
#
# These older versions couldn't grok that the previous `jsdoc` stub was really
# written in ECMAScript Module style without a file extension:
#
# TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension "" for
# .../jsdoc-cli-wrapper/test/fixtures/jsdocStub/jsdoc. Loading extensionless
# files is not supported inside of "type":"module" package.json contexts. The
# package.json file .../jsdoc-cli-wrapper/package.json caused this
# "type":"module" context. Try changing
# .../jsdoc-cli-wrapper/test/fixtures/jsdocStub/jsdoc to have a file
# extension. Note the "bin" field of package.json can point to a file with an
# extension, for example
# {"type":"module","bin":{"jsdoc":"./test/fixtures/jsdocStub/jsdoc.js"}}
#
# I tried adding the `--experimental-default-type=module` flag to the shebang
# line of the former `jsdoc` stub. Only after trying that did I realize that
# `#!/usr/bin/env` style shebangs don't support passing command line arguments
# to the specified interpreter.
#
# Hence moving the original `jsdoc` stub to `jsdoc.js` and invoking it via this
# one-line wrapper.

exec node "${0}.js" "$@"
2 changes: 1 addition & 1 deletion test/fixtures/jsdocStub/jsdoc.CMD
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,4 @@
:: https://ss64.com/nt/
:: https://htipe.wordpress.com/2008/10/09/the-dp0-variable/
@echo off
node "%~dp0\jsdoc" %*
node "%~dp0\jsdoc.js" %*
69 changes: 69 additions & 0 deletions test/fixtures/jsdocStub/jsdoc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
#!/usr/bin/env node
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/

/**
* Fake jsdoc implementation for testing
*/

import { mkdir, writeFile } from 'node:fs/promises'
import path from 'node:path'
import { exit } from 'node:process'

try {
const {willGenerate, destination, exitCode} = parseArgs(process.argv.slice(2))

if (willGenerate && exitCode === 0) {
const newSubDir = path.join(destination, 'new-subdir')
await mkdir(newSubDir, {recursive: true})
await writeFile(path.join(newSubDir, 'index.html'), 'New Hotness')
}
exit(exitCode)

} catch (err) {
console.error(err)
exit(1)
}

/**
* The parameters parsed from process.argv by parseArgs()
* @typedef {object} ArgsResult
* @property {string} destination - the JSDoc destination directory
* @property {boolean} willGenerate - true unless -h or --no-input-files present
* @property {number} exitCode - the value of --exit-code or 0 by default
*/

/**
* Parses fake jsdoc arguments
* @param {string[]} argv - command line arguments
* @returns {ArgsResult} - parameters determining fake jsdoc behavior
*/
function parseArgs(argv) {
let destination = null
let willGenerate = true
let exitCode = 0

for (let i = 0; i !== argv.length; ++i) {
const arg = argv[i]
const nextArg = argv[i+1]

switch (arg) {
case '-d':
destination = nextArg
break

case '-h':
case '--no-input-files':
willGenerate = false
break

case '--exit-code':
exitCode = nextArg
break
}
}
return {willGenerate, destination, exitCode}
}
2 changes: 1 addition & 1 deletion test/getPath.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ describe('getPath', () => {
const envPath = ['usr/local/bin', 'usr/bin', 'bin']
.map(p => path.join(root, p))
.join(path.delimiter)
const makeEnv = (platform) => ({[pathKey(platform)]: envPath})
const makeEnv = platform => ({[pathKey(platform)]: envPath})

test('finds command on POSIX system', async() => {
await expect(getPath('testcmd', makeEnv('linux'), 'linux')).resolves
Expand Down
2 changes: 1 addition & 1 deletion test/main.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ describe('jsdoc-cli-wrapper', () => {
if (stderr) result.stderr = stderr
resolve(result)
})
wrapper.on('error', (err) => reject(err))
wrapper.on('error', err => reject(err))
})

const runMain = (...argv) => spawnMain(envPath, ...argv)
Expand Down

0 comments on commit 6b1b150

Please sign in to comment.