diff --git a/CHANGELOG.md b/CHANGELOG.md index 5eb68a8014..d75d407507 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,9 @@ Please add one entry in this file for each change in Yarn's behavior. Use the sa ## Master +- Change run command to prioritize cwd/node_modules/.bin. Fixes run/bin in workspaces when the same binary is hoisted and installed in a workspace package. + [#7748](https://github.com/yarnpkg/yarn/issues/7748) - [**priceld**](https://github.com/priceld) + - Prints workspace names with `yarn workspaces` (silence with `-s`) [#7722](https://github.com/yarnpkg/yarn/pull/7722) - [**Orta**](https://twitter.com/orta) diff --git a/__tests__/commands/run.js b/__tests__/commands/run.js index 35a1221e56..1a620047b4 100644 --- a/__tests__/commands/run.js +++ b/__tests__/commands/run.js @@ -207,7 +207,7 @@ test('adds workspace root node_modules/.bin to path when in a workspace', (): Pr expect(envPaths).toContain(path.join(config.cwd, 'packages', 'pkg1', 'node_modules', '.bin')); })); -test('adds cwd node_modules/.bin to path when in a workspace usig nohoist', (): Promise => +test('adds cwd node_modules/.bin to path when in a workspace using nohoist', (): Promise => runRunInWorkspacePackage('packages/pkg1', ['env'], {}, 'nohoist-workspace', (config, reporter): ?Promise => { const logEntry = reporter.getBuffer().find(entry => entry.type === 'log'); const parsedLogData = JSON.parse(logEntry ? logEntry.data.toString() : '{}'); @@ -230,3 +230,31 @@ test('runs script with custom script-shell', (): Promise => customShell: '/usr/bin/dummy', }); })); + +test('runs workspace bin before hoisted bin', (): Promise => + runRunInWorkspacePackage('packages/pkg1', ['duplicated-bin'], {}, 'workspace-bins', (config): ?Promise => { + const expectedCwd = path.join(config.cwd, 'packages', 'pkg1'); + const script = path.join(expectedCwd, 'node_modules', '.bin', 'duplicated-bin'); + + expect(execCommand).toBeCalledWith({ + stage: 'duplicated-bin', + config, + cmd: script, + cwd: expectedCwd, + isInteractive: true, + }); + })); + +test('runs hoisted bin if workspace bin is not found', (): Promise => + runRunInWorkspacePackage('packages/pkg1', ['hoisted-bin'], {}, 'workspace-bins', (config): ?Promise => { + const expectedCwd = path.join(config.cwd, 'packages', 'pkg1'); + const script = path.join(config.cwd, 'node_modules', '.bin', 'hoisted-bin'); + + expect(execCommand).toBeCalledWith({ + stage: 'hoisted-bin', + config, + cmd: script, + cwd: expectedCwd, + isInteractive: true, + }); + })); diff --git a/__tests__/fixtures/request-cache/GET/gitlab.com/leanlabsio/kanban/raw/7f21696fb9d08130dd62abd96c9572f513c05301/package.json.bin b/__tests__/fixtures/request-cache/GET/gitlab.com/leanlabsio/kanban/raw/7f21696fb9d08130dd62abd96c9572f513c05301/package.json.bin new file mode 100644 index 0000000000..938c871236 --- /dev/null +++ b/__tests__/fixtures/request-cache/GET/gitlab.com/leanlabsio/kanban/raw/7f21696fb9d08130dd62abd96c9572f513c05301/package.json.bin @@ -0,0 +1,62 @@ +HTTP/1.1 200 OK +Server: nginx +Date: Mon, 09 Dec 2019 21:52:06 GMT +Content-Type: text/plain; charset=utf-8 +Content-Length: 1181 +Cache-Control: max-age=3600, public +Content-Disposition: inline +Etag: W/"78309fbf8af4479c47eca65b0c5e3f51" +Referrer-Policy: strict-origin-when-cross-origin +Set-Cookie: experimentation_subject_id=ImJmMDg0YTIyLWM5OTgtNDNmOC05MmIxLTBmNzU2YWZkMzNjYSI%3D--a0c3f65ca95e8147c43e228efaf2525fcb3e3688; domain=.gitlab.com; path=/; expires=Fri, 09 Dec 2039 21:52:06 -0000; secure; HttpOnly +X-Content-Type-Options: nosniff +X-Download-Options: noopen +X-Frame-Options: DENY +X-Permitted-Cross-Domain-Policies: none +X-Request-Id: 4YrYRJQgtK1 +X-Runtime: 0.059498 +X-Ua-Compatible: IE=edge +X-Xss-Protection: 1; mode=block +Strict-Transport-Security: max-age=31536000 +Referrer-Policy: strict-origin-when-cross-origin +GitLab-LB: fe-12-lb-gprd +GitLab-SV: web-15-sv-gprd + +{ + "name": "kanban", + "version": "0.0.1", + "repository": "gitlab.com/leanlabsio/kanban", + "scripts": { + "install": "npm install", + "build": "grunt build", + "watch": "grunt watch" + }, + "devDependencies": { + "grunt": "~0.4.1", + "grunt-cli": "~0.1.13", + "grunt-contrib-copy": "^0.5.0", + "grunt-contrib-concat": "~0.5.0", + "grunt-contrib-watch": "~0.5.3", + "grunt-contrib-uglify": "~0.7.0", + "grunt-sass": "1.0.0", + "grunt-contrib-connect": "~0.8.0", + "grunt-connect-proxy": "~0.1.11" + }, + "dependencies": { + "angular": "=1.5.6", + "angular-lodash": "https://github.com/EMSSConsulting/angular-lodash.git#68a726c", + "foundation-sites": "5.5.2", + "angular-foundation": "https://github.com/pineconellc/angular-foundation.git#8f3f260", + "angular-loading-bar": "=0.5.2", + "angular-storage": "=0.0.6", + "angular-ui-router": "=0.3.0", + "angularjs-datepicker": "=0.2.15", + "font-awesome": "=4.6.3", + "markdown-it": "=5.0.2", + "markdown-it-emoji": "=1.1.0", + "ng-sortable": "=1.3.6", + "sass-flex-mixin": "=1.0.3", + "lodash": "=4.13.1", + "twemoji": "=2.1.0", + "angular-file-upload": "=2.3.4" + } +} diff --git a/__tests__/fixtures/run/workspace-bins/node_modules/.bin/duplicated-bin b/__tests__/fixtures/run/workspace-bins/node_modules/.bin/duplicated-bin new file mode 100644 index 0000000000..e69de29bb2 diff --git a/__tests__/fixtures/run/workspace-bins/node_modules/.bin/hoisted-bin b/__tests__/fixtures/run/workspace-bins/node_modules/.bin/hoisted-bin new file mode 100644 index 0000000000..e69de29bb2 diff --git a/__tests__/fixtures/run/workspace-bins/package.json b/__tests__/fixtures/run/workspace-bins/package.json new file mode 100644 index 0000000000..c4ac3364a3 --- /dev/null +++ b/__tests__/fixtures/run/workspace-bins/package.json @@ -0,0 +1,5 @@ +{ + "workspaces": [ + "packages/*" + ] +} diff --git a/__tests__/fixtures/run/workspace-bins/packages/pkg1/node_modules/.bin/duplicated-bin b/__tests__/fixtures/run/workspace-bins/packages/pkg1/node_modules/.bin/duplicated-bin new file mode 100644 index 0000000000..e69de29bb2 diff --git a/__tests__/fixtures/run/workspace-bins/packages/pkg1/package.json b/__tests__/fixtures/run/workspace-bins/packages/pkg1/package.json new file mode 100644 index 0000000000..9e26dfeeb6 --- /dev/null +++ b/__tests__/fixtures/run/workspace-bins/packages/pkg1/package.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/src/cli/commands/run.js b/src/cli/commands/run.js index 33c90d5999..5d66c6a4fe 100644 --- a/src/cli/commands/run.js +++ b/src/cli/commands/run.js @@ -31,8 +31,10 @@ export async function getBinEntries(config: Config): Promise // Setup the node_modules/.bin folders for analysis for (const registryFolder of config.registryFolders) { - binFolders.add(path.resolve(config.cwd, registryFolder, '.bin')); + // Paths should be added in reverse order of precedence (if a bin exists in + // multiple paths, the last path that was added containing the bin will be used) binFolders.add(path.resolve(config.lockfileFolder, registryFolder, '.bin')); + binFolders.add(path.resolve(config.cwd, registryFolder, '.bin')); } // Same thing, but for the pnp dependencies, located inside the cache