diff --git a/README.md b/README.md index 565d4cb6..ef573b48 100644 --- a/README.md +++ b/README.md @@ -69,6 +69,7 @@ success Already up-to-date. |`--only` | Set package [updating scope](https://docs.npmjs.com/cli/audit): `dev`/`prod` |`--force` | Have audit fix install semver-major updates to toplevel dependencies, not just semver-compatible ones | false |`--audit-level` | Include a vulnerability with a level as defined or higher | moderate +|`--symlink` | Specify symlink type for temp assets: `dir` or `junction` (Windows only) | dir ## License [MIT](./LICENSE) diff --git a/src/main/ts/index.ts b/src/main/ts/index.ts index 1c2100f9..f3f4425a 100644 --- a/src/main/ts/index.ts +++ b/src/main/ts/index.ts @@ -1,9 +1,9 @@ -import fs from 'fs-extra' +import fs, {SymlinkType} from 'fs-extra' import synp from 'synp' import {join} from 'path' import findCacheDir from 'find-cache-dir' import chalk from 'chalk' -import {invoke, formatFlags} from './util' +import {invoke, formatFlags, getSymlinkType} from './util' type TContext = { cwd: string, temp: string, flags: Record } @@ -16,10 +16,10 @@ type TStage = [string, ...TCallback[]] * @param {TContext} cxt * @return {void} */ -const createTempAssets: TCallback = ({temp}) => { +const createTempAssets: TCallback = ({temp, flags}) => { fs.copyFileSync('yarn.lock', join(temp, 'yarn.lock')) fs.copyFileSync('package.json', join(temp, 'package.json')) - fs.createSymlinkSync('node_modules', join(temp, 'node_modules'), 'dir') + fs.createSymlinkSync('node_modules', join(temp, 'node_modules'), getSymlinkType(flags.symlink) as SymlinkType) // TODO fix fs-extra typings issue } /** diff --git a/src/main/ts/util.ts b/src/main/ts/util.ts index d4a8a50e..4456018b 100644 --- a/src/main/ts/util.ts +++ b/src/main/ts/util.ts @@ -1,5 +1,6 @@ import cp from 'child_process' import chalk from 'chalk' +import {FsSymlinkType} from 'fs-extra' export const invoke = (cmd: string, args: string[], cwd: string) => { console.log(chalk.bold('invoke'), cmd, ...args) @@ -26,3 +27,10 @@ export const formatFlags = (flags: Record, ...picklist: string[]): return memo }, []) + +export const isWindows = () => process.platform === 'win32' || /^(msys|cygwin)$/.test(process.env.OSTYPE as string) + +export const getSymlinkType = (type?: string): FsSymlinkType => + type === 'junction' && isWindows() + ? type + : 'dir' diff --git a/src/test/ts/util.ts b/src/test/ts/util.ts index d8208228..09768f4d 100644 --- a/src/test/ts/util.ts +++ b/src/test/ts/util.ts @@ -1,4 +1,4 @@ -import {formatFlags} from '../../main/ts/util' +import {formatFlags, getSymlinkType} from '../../main/ts/util' import minimist from 'minimist' describe('util', () => { @@ -28,4 +28,18 @@ describe('util', () => { }) }) }) + + describe('#getSymlinkType', () => { + it('resolves type by system profile and arg', () => { + process.env.OSTYPE = 'msys' + expect(getSymlinkType('junction')).toBe('junction') + expect(getSymlinkType('foo')).toBe('dir') + expect(getSymlinkType()).toBe('dir') + + process.env.OSTYPE = 'unknown' + expect(getSymlinkType('junction')).toBe('dir') + expect(getSymlinkType('foo')).toBe('dir') + expect(getSymlinkType()).toBe('dir') + }) + }) })