diff --git a/lib/index.js b/lib/index.js index 8a95672..72a784b 100644 --- a/lib/index.js +++ b/lib/index.js @@ -53,16 +53,23 @@ export async function runJsdoc(argv, env, platform) { return {exitCode} } +/** + * The key for the command search path within process.env. + * + * On every system other than Windows, this will be "PATH". On Windows, this + * will be "Path". + */ +export const PATH_KEY = process.platform !== 'win32' ? 'PATH' : 'Path' + /** * Returns the full path to the specified command - * @param {string} cmdName - command to find in env.PATH + * @param {string} cmdName - command to find in env[PATH_KEY] * @param {object} env - environment variables, presumably process.env - * @param {string} env.PATH - the PATH environment variable * @param {string} platform - the process.platform string * @returns {Promise} - path to the command */ export async function getPath(cmdName, env, platform) { - for (const p of env.PATH.split(path.delimiter)) { + for (const p of env[PATH_KEY].split(path.delimiter)) { // pnpm will install both the original script and versions ending with .CMD // and .ps1. We'll just default to .CMD. const extension = (platform === 'win32') ? '.CMD' : '' @@ -73,7 +80,7 @@ export async function getPath(cmdName, env, platform) { return candidate } catch { /* try next candidate */ } } - return Promise.reject(`${cmdName} not found in PATH`) + return Promise.reject(`${cmdName} not found in ${PATH_KEY}`) } /** diff --git a/test/fixtures/index.js b/test/fixtures/index.js index 2532796..6793369 100644 --- a/test/fixtures/index.js +++ b/test/fixtures/index.js @@ -36,5 +36,6 @@ export function fixtureEnv(fixtureName) { const paths = [ path.join('usr', 'local', 'bin'), path.join('usr', 'bin'), 'bin' ] - return { PATH: paths.map(p => path.join(root, p)).join(path.delimiter) } + const pathKey = process.platform !== 'win32' ? 'PATH' : 'Path' + return {[pathKey]: paths.map(p => path.join(root, p)).join(path.delimiter)} } diff --git a/test/fixtures/fakeJsdoc/jsdoc b/test/fixtures/jsdocStub/jsdoc similarity index 100% rename from test/fixtures/fakeJsdoc/jsdoc rename to test/fixtures/jsdocStub/jsdoc diff --git a/test/fixtures/fakeJsdoc/jsdoc.CMD b/test/fixtures/jsdocStub/jsdoc.CMD similarity index 98% rename from test/fixtures/fakeJsdoc/jsdoc.CMD rename to test/fixtures/jsdocStub/jsdoc.CMD index b917d08..d5e0a72 100644 --- a/test/fixtures/fakeJsdoc/jsdoc.CMD +++ b/test/fixtures/jsdocStub/jsdoc.CMD @@ -6,4 +6,5 @@ :: https://stackoverflow.com/questions/5034076/what-does-dp0-mean-and-how-does-it-work :: https://ss64.com/nt/ :: https://htipe.wordpress.com/2008/10/09/the-dp0-variable/ +@echo off node "%~dp0\jsdoc" %* diff --git a/test/getPath.test.js b/test/getPath.test.js index 61b3b7e..aab376c 100644 --- a/test/getPath.test.js +++ b/test/getPath.test.js @@ -5,7 +5,7 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ -import { getPath } from '../lib' +import { getPath, PATH_KEY } from '../lib' import { fixturePath, fixtureEnv } from './fixtures' import { describe, expect, test } from 'vitest' import path from 'node:path' @@ -26,6 +26,6 @@ describe('getPath', () => { test('rejects when command isn\'t found', async () => { await expect(getPath('nonexistent', env, process.platform)).rejects - .toBe('nonexistent not found in PATH') + .toBe(`nonexistent not found in ${PATH_KEY}`) }) }) diff --git a/test/main.test.js b/test/main.test.js index 5ee8099..087cdd3 100644 --- a/test/main.test.js +++ b/test/main.test.js @@ -5,26 +5,25 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ -import { getPath } from '../lib' +import { getPath, PATH_KEY } from '../lib' import { fixturePath } from './fixtures' import DestDirHelper from './DestDirHelper' import { afterEach, describe, expect, test } from 'vitest' import { spawn } from 'node:child_process' import path from 'node:path' +import { fileURLToPath } from 'node:url' describe('jsdoc-cli-wrapper', () => { - const root = fixturePath('fakeJsdoc') + const root = fixturePath('jsdocStub') const destDirHelper = new DestDirHelper() + const mainPath = fileURLToPath(new URL('../index.js', import.meta.url)) afterEach(async () => await destDirHelper.cleanup()) - const spawnMain = async(testEnvPath, ...argv) => { - const origPath = process.env.PATH - process.env.PATH = testEnvPath - - const result = await new Promise(resolve => { - const mainPath = new URL('../index.js', import.meta.url).pathname - const wrapper = spawn(mainPath, argv) + const spawnMain = (testEnvPath, ...argv) => { + return new Promise((resolve, reject) => { + const env = {...process.env, [PATH_KEY]: testEnvPath} + const wrapper = spawn(process.execPath, [mainPath, ...argv], {env}) let stdout = '' let stderr = '' @@ -36,23 +35,21 @@ describe('jsdoc-cli-wrapper', () => { if (stderr) result.stderr = stderr resolve(result) }) + wrapper.on('error', (err) => reject(err)) }) - - process.env.PATH = origPath - return result } const runMain = async (...argv) => { - const testEnvPath = [root, process.env.PATH].join(path.delimiter) + const testEnvPath = [root, process.env[PATH_KEY]].join(path.delimiter) return spawnMain(testEnvPath, ...argv) } const runMainWithoutJsdoc = async (...argv) => { - let testEnvPath = process.env.PATH + let testEnvPath = process.env[PATH_KEY] try { const jsdocPath = await getPath('jsdoc', process.env, process.platform) - const jsdocDir = path.dirname(jsdocPath) + const jsdocDir = path.dirname(jsdocPath).replaceAll('\\', '\\\\') const pat = new RegExp(`${path.delimiter}?${jsdocDir}${path.delimiter}?`) testEnvPath = testEnvPath.replace(pat, '') } catch { /* It's OK if it's not actually installed. */ } diff --git a/test/runJsdoc.test.js b/test/runJsdoc.test.js index 5aab4f1..dd0eb95 100644 --- a/test/runJsdoc.test.js +++ b/test/runJsdoc.test.js @@ -5,15 +5,15 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ -import { runJsdoc } from '../lib' +import { runJsdoc, PATH_KEY } from '../lib' import { fixturePath } from './fixtures' import DestDirHelper from './DestDirHelper' import { afterEach, beforeEach, describe, expect, test } from 'vitest' import path from 'node:path' describe('runJsdoc', () => { - const root = fixturePath('fakeJsdoc') - const env = { PATH: root } + const root = fixturePath('jsdocStub') + const env = { [PATH_KEY]: root } const platform = process.platform const destDirHelper = new DestDirHelper() @@ -35,7 +35,7 @@ describe('runJsdoc', () => { test('emits error if jsdoc not found', async () => { const bogusPath = path.join(root, 'nonexistent') - await expect(runJsdoc(argv, {PATH: bogusPath}, platform)) + await expect(runJsdoc(argv, {[PATH_KEY]: bogusPath}, platform)) .rejects.toContain('npm add -g jsdoc') await expect(readIndexHtml()).resolves.toStrictEqual({ actualPath: origIndexPath, content: 'Old and Busted'