@@ -4,6 +4,40 @@ import path from 'path';
44export type PackageManagerResult = execa . ExecaReturnValue & { success : boolean } ;
55export type PackageManagerOptions = execa . Options & { cwd : string } ;
66
7+ /**
8+ * Filter PATH for running npm commands, removing entries that contain shell-script node wrappers.
9+ * Package managers inject temp directories into PATH with node shims — yarn classic uses `yarn--*`
10+ * dirs, yarn berry uses `xfs-*` dirs. These shims are POSIX shell scripts, and POSIX sh drops env
11+ * vars whose names contain characters like / and :, which npm auth token env vars do contain.
12+ * See: https://github.com/yarnpkg/yarn/issues/6685
13+ *
14+ * Workaround for an issue on certain platforms/shells(?) if the parent command was run VIA yarn:
15+ * The auth environment variable (e.g. `npm_config_//someRegistry/:_authToken`) was not being
16+ * passed through to the child process. This might be because:
17+ * - Special characters such as / and : aren't valid in env var names for certain shells/platforms
18+ * - On every `yarn run ...` command, yarn makes temp directories like /<temp>/yarn--1776822418161-0.7992675923334178
19+ * with aliases for `node` and `yarn`. On Linux (and Mac), the `node` alias looks something like:
20+ * #!/bin/sh
21+ * exec "/path/to/node" "$@"
22+ * (see https://github.com/yarnpkg/yarn/issues/6685 for context)
23+ * - Best guess: invalid environment variable names are dropped by this extra `exec` step??
24+ * (This consistently reproed on Ubuntu+bash, but not Mac+zsh or bash. The clue was that the
25+ * tests passed even on Linux when run via debugTests.js, but failed when run via yarn test.)
26+ *
27+ * Removing yarn temp directories from the PATH seems to consistently fix this issue.
28+ * yarn classic (v1) uses `yarn--*` directories; yarn berry (v4) uses `xfs-*` directories.
29+ * Use `checkNpmAuthEnvPassthrough` after this filter to detect unknown variants of this issue.
30+ */
31+ export function filterNpmPath ( pathEnv : string ) : string {
32+ return pathEnv
33+ . split ( path . delimiter )
34+ . filter ( p => {
35+ const base = path . basename ( p ) ;
36+ return ! base . startsWith ( 'yarn--' ) && ! base . startsWith ( 'xfs-' ) ;
37+ } )
38+ . join ( path . delimiter ) ;
39+ }
40+
741/**
842 * Run a package manager command. Returns the error result instead of throwing on failure.
943 * @param manager The package manager to use
@@ -18,28 +52,7 @@ export async function packageManager(
1852) : Promise < PackageManagerResult > {
1953 let pathEnv = options . env ?. PATH || process . env . PATH ;
2054 if ( manager === 'npm' && pathEnv ) {
21- // Workaround for an issue on certain platforms/shells(?) if the parent command was run VIA yarn:
22- // The auth environment variable (e.g. `npm_config_//someRegistry/:_authToken`) was not being
23- // passed through to the child process. This might be because:
24- // - Special characters such as / and : aren't valid in env var names for certain shells/platforms
25- // - On every `yarn run ...` command, yarn makes temp directories like /<temp>/yarn--1776822418161-0.7992675923334178
26- // with aliases for `node` and `yarn`. On Linux (and Mac), the `node` alias looks something like:
27- // #!/bin/sh
28- // exec "/path/to/node" "$@"
29- // (see https://github.com/yarnpkg/yarn/issues/6685 for context)
30- // - Best guess: invalid environment variable names are dropped by this extra `exec` step??
31- // (This consistently reproed on Ubuntu+bash, but not Mac+zsh or bash. The clue was that the
32- // tests passed even on Linux when run via debugTests.js, but failed when run via yarn test.)
33- //
34- // Removing yarn temp directories from the PATH seems to consistently fix this issue.
35- // yarn classic (v1) uses `yarn--*` directories; yarn berry (v4) uses `xfs-*` directories.
36- pathEnv = pathEnv
37- . split ( path . delimiter )
38- . filter ( p => {
39- const base = path . basename ( p ) ;
40- return ! base . startsWith ( 'yarn--' ) && ! base . startsWith ( 'xfs-' ) ;
41- } )
42- . join ( path . delimiter ) ;
55+ pathEnv = filterNpmPath ( pathEnv ) ;
4356 }
4457
4558 try {
0 commit comments