diff --git a/package.json b/package.json index e44bfa6f..078f4479 100644 --- a/package.json +++ b/package.json @@ -53,12 +53,16 @@ ], "author": "Anton Golub ", "license": "MIT", - "workspaces0": [], + "workspaces0": [ + "packages/*" + ], "dependencies": { "@antongolub/synp": "^2.0.10", + "@types/bash-glob": "^2.0.0", "@types/find-cache-dir": "^3.2.0", "@types/fs-extra": "^9.0.1", "@types/npm": "^2.0.31", + "bash-glob": "^2.0.0", "chalk": "^4.1.0", "find-cache-dir": "^3.3.1", "fs-extra": "^9.0.1", diff --git a/src/main/ts/index.ts b/src/main/ts/index.ts index 088502c0..e377ff29 100644 --- a/src/main/ts/index.ts +++ b/src/main/ts/index.ts @@ -3,7 +3,7 @@ import synp from '@antongolub/synp' import {join} from 'path' import findCacheDir from 'find-cache-dir' import chalk from 'chalk' -import {invoke, formatFlags, getSymlinkType, getNpmBin} from './util' +import {invoke, formatFlags, getSymlinkType, getNpmBin, getWorkspaces} from './util' type TContext = { cwd: string, temp: string, flags: Record } @@ -19,10 +19,25 @@ type TStage = [string, ...TCallback[]] 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'), getSymlinkType(flags.symlink) as SymlinkType) // TODO fix fs-extra typings issue - if (fs.existsSync('packages')) { - fs.createSymlinkSync('packages', join(temp, 'packages'), getSymlinkType(flags.symlink) as SymlinkType) - } +} + +/** + * Provide symlinks to node_modules and workspaces + * @param {TContext} cxt + * @return {void} + */ +const createSymlinks: TCallback = ({temp, flags, cwd}) => { + const symlinkType = getSymlinkType(flags.symlink) as SymlinkType // TODO fix fs-extra typings issue + const workspaces = getWorkspaces(cwd) + const links = [join(cwd, 'node_modules'), ...workspaces] + + links.forEach((pkgPath: string) => { + const rel = pkgPath.replace(/\/package\.json$/, '').slice(cwd.length) + const from = join(cwd, rel) + const to = join(temp, rel) + + fs.createSymlinkSync(from, to, symlinkType) + }) } /** @@ -56,8 +71,8 @@ const npmAuditFix: TCallback = ({temp, flags}) => { */ const yarnImport: TCallback = ({temp, flags}) => { const yarnLockData = synp.npmToYarn(temp) + fs.writeFileSync(join(temp, 'yarn.lock'), yarnLockData) - // invoke('yarn', ['import', ...formatFlags(flags, 'verbose', 'silent')], temp, flags.silent) fs.copyFileSync(join(temp, 'yarn.lock'), 'yarn.lock') } @@ -82,6 +97,7 @@ export const stages: TStage[] = [ 'Preparing temp assets...', clear, createTempAssets, + createSymlinks, ], [ 'Generating package-lock.json from yarn.lock...', diff --git a/src/main/ts/util.ts b/src/main/ts/util.ts index 7d521f02..1c0ce386 100644 --- a/src/main/ts/util.ts +++ b/src/main/ts/util.ts @@ -1,9 +1,10 @@ import cp from 'child_process' import chalk from 'chalk' -import {FsSymlinkType} from 'fs-extra' +import {FsSymlinkType, readFileSync} from 'fs-extra' import minimist from 'minimist' import {join} from 'path' import {sync as pkgDir} from 'pkg-dir' +import glob, {Options as GlobOptions} from 'bash-glob' export const invoke = (cmd: string, args: string[], cwd: string, silent= false) => { !silent && console.log(chalk.bold('invoke'), cmd, ...args) @@ -47,3 +48,29 @@ export const getSymlinkType = (type?: string): FsSymlinkType => : 'dir' export const getNpmBin = () => join(pkgDir(__dirname) as string, 'node_modules/.bin/npm') + +export const getWorkspaces = (cwd: string) => { + const manifest = readJson(join(cwd, 'package.json')) + + let packages = manifest.workspaces + if (packages && packages.packages) { + packages = packages.packages + } + + if (!packages || !packages.length) { + return [] + } + + // Turn workspaces into list of package.json files. + return glob.sync( + packages.map((p: string) => p.replace(/\/?$/, '/package.json')), + { + cwd, + realpath: true, + ignore: '**/node_modules/**', + } as GlobOptions, + ) +} + +export const readJson = (path: string): any => + JSON.parse(readFileSync(path).toString('utf-8').trim()) diff --git a/src/test/ts/index.ts b/src/test/ts/index.ts index 31cea837..cacd517a 100644 --- a/src/test/ts/index.ts +++ b/src/test/ts/index.ts @@ -46,18 +46,16 @@ describe('yarn-audit-fix', () => { expect(fs.emptyDirSync).toHaveBeenCalledWith(temp) expect(fs.copyFileSync).toHaveBeenCalledWith('yarn.lock', join(temp, 'yarn.lock')) expect(fs.copyFileSync).toHaveBeenCalledWith('package.json', join(temp, 'package.json')) - expect(fs.createSymlinkSync).toHaveBeenCalledWith('node_modules', join(temp, 'node_modules'), 'dir') - expect(fs.createSymlinkSync).toHaveBeenCalledWith('packages', join(temp, 'packages'), 'dir') + expect(fs.createSymlinkSync).toHaveBeenCalledWith(join(cwd, 'node_modules'), join(temp, 'node_modules'), 'dir') + // expect(fs.createSymlinkSync).toHaveBeenCalledWith(join(cwd, 'packages/foo'), join(temp, 'packages/foo'), 'dir') // Generating package-lock.json from yarn.lock... - // expect(fs.writeFileSync).toHaveBeenCalledWith(join(temp, 'package.json'), '{}') expect(fs.removeSync).toHaveBeenCalledWith(join(temp, 'yarn.lock')) // Applying npm audit fix... expect(cp.spawnSync).toHaveBeenCalledWith(npmBinPath, ['audit', 'fix', '--package-lock-only', '--verbose'], {cwd: temp, stdio}) // Updating yarn.lock from package-lock.json... - // expect(cp.spawnSync).toHaveBeenCalledWith('yarn', ['import', '--verbose'], {cwd: temp, stdio}) expect(fs.copyFileSync).toHaveBeenCalledWith(join(temp, 'yarn.lock'), 'yarn.lock') expect(cp.spawnSync).toHaveBeenCalledWith('yarn', ['--update-checksums', '--verbose'], {cwd, stdio}) expect(fs.emptyDirSync).toHaveBeenCalledWith(temp) diff --git a/yarn.lock b/yarn.lock index cc00ed19..05ac08c7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1017,6 +1017,11 @@ dependencies: "@babel/types" "^7.3.0" +"@types/bash-glob@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@types/bash-glob/-/bash-glob-2.0.0.tgz#bba8dcad40e615f33e400170fa551daa40ee3c6a" + integrity sha1-u6jcrUDmFfM+QAFw+lUdqkDuPGo= + "@types/color-name@^1.1.1": version "1.1.1" resolved "https://registry.yarnpkg.com/@types/color-name/-/color-name-1.1.1.tgz#1c1261bbeaa10a8055bbc5d8ab84b7b2afc846a0" @@ -7860,7 +7865,7 @@ tar@^4.4.10, tar@^4.4.12, tar@^4.4.13: tar@^6.0.1, tar@^6.0.2: version "6.0.5" resolved "https://registry.yarnpkg.com/tar/-/tar-6.0.5.tgz#bde815086e10b39f1dcd298e89d596e1535e200f" - integrity sha512-0b4HOimQHj9nXNEAA7zWwMM91Zhhba3pspja6sQbgTpynOJf+bkjBnfybNYzbpLbnwXnbyB4LOREvlyXLkCHSg== + integrity sha1-vegVCG4Qs58dzSmOidWW4VNeIA8= dependencies: chownr "^2.0.0" fs-minipass "^2.0.0"