Skip to content

Commit

Permalink
Merge pull request #1 from mbland/fix-windows-portability
Browse files Browse the repository at this point in the history
Fix Windows portability issues, move fakeJsdoc to jsdocStub
  • Loading branch information
mbland authored Dec 28, 2023
2 parents 3492207 + 407c5ae commit d62f081
Show file tree
Hide file tree
Showing 7 changed files with 32 additions and 26 deletions.
15 changes: 11 additions & 4 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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<string>} - 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' : ''
Expand All @@ -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}`)
}

/**
Expand Down
3 changes: 2 additions & 1 deletion test/fixtures/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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)}
}
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -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" %*
4 changes: 2 additions & 2 deletions test/getPath.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand All @@ -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}`)
})
})
27 changes: 12 additions & 15 deletions test/main.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 = ''

Expand All @@ -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. */ }
Expand Down
8 changes: 4 additions & 4 deletions test/runJsdoc.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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()

Expand All @@ -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'
Expand Down

0 comments on commit d62f081

Please sign in to comment.