-
Notifications
You must be signed in to change notification settings - Fork 2.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow ${HOME} in .npmrc to work in Windows #4693
Conversation
Windows doesn't set the HOME environment variable by default, but NPM has logic to set process.env.HOME based on the current OS home directory. See https://github.com/npm/npm/blob/fb28e5868a9dbbe21a15f23fe8cf8b3703e8adf2/lib/config/defaults.js#L81 Yarn doesn't do this, so configs such as `prefix = ${HOME}/.npm-packages` that work for NPM will cause Yarn to refuse to run. This commit updates Yarn's behavior to be closer to NPM's. Unlike NPM, this commit only sets HOME if it's not already set, to avoid potentially incompatible changes with existing Yarn users.
This change will decrease the build size from 9.94 MB to 9.91 MB, a decrease of 22.5 KB (0%)
|
src/rc.js
Outdated
export function prepareEnv() { | ||
// Allow ${HOME} in, e.g., .npmrc to work even on Windows. | ||
if (rcUtil.home && !process.env.HOME) { | ||
process.env.HOME = rcUtil.home; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't like this. We shouldn't overwrite environment variables and, if we really must, we shouldn't do it in this file.
Why don't you just use |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks a lot for the PR!
I've left a comment in the code. Also we need tests to ensure this doesn't break in the future and to make sure the code actually works :)
src/cli/index.js
Outdated
@@ -537,6 +537,7 @@ export function main({ | |||
} | |||
|
|||
async function start(): Promise<void> { | |||
prepareEnv(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this should be done in getRcConfigForCwd
instead of changing the whole process.env
. I don't think it is a good idea to patch/mutate process.env
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Normally, I'd agree. In this case, though, I figured that setting HOME only if it's not already set should be safe (the fact that NPM does it could be evidence for its safety?), and, since Yarn is promoted as a drop-in replacement for NPM, I figured there's benefit to doing what NPM does. (My thinking here is probably colored by my running into #1538.)
I'm happy to go either way, though, so I can change the PR this evening to use getRcConfigForCwd
.
Thanks for the feedback!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Upon further investigation, I don't think that getRcConfigForCwd
is correct. That finds config files but doesn't process them. The environment variable changes instead need to be made within NpmRegistry
. I just pushed an updated PR with these changes.
Because I didn't realize I could. 🙂 (I think I copied that config from an online source when I was first getting familiar with NPM and never thought about it again.) Thanks for the suggestion. |
This reverts commit 436422d.
Windows doesn't set the HOME environment variable by default, but NPM has logic to set process.env.HOME based on the current OS home directory. See https://github.com/npm/npm/blob/fb28e5868a9dbbe21a15f23fe8cf8b3703e8adf2/lib/config/defaults.js#L81 Yarn doesn't do this, so configs such as `prefix = ${HOME}/.npm-packages` that work for NPM will cause Yarn to refuse to run. This commit updates Yarn's behavior to be closer to NPM's, by using a custom/modified environment when processing NPM configurations. Add a Flow type `Env` to represent a set of environment variables.
(A separate `describe` block seems like overkill.)
@joshkel sorry for the wait didn't realize you've updated the PR. Will review it shortly. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this new version looks pretty great, thanks a lot!
@@ -1,7 +1,9 @@ | |||
/* @flow */ | |||
const ENV_EXPR = /(\\*)\$\{([^}]+)\}/g; | |||
|
|||
export default function envReplace(value: string, env: {[key: string]: ?string} = process.env): string { | |||
export type Env = {[key: string]: ?string}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
❤️
@@ -206,11 +207,20 @@ export default class NpmRegistry extends Registry { | |||
return actuals; | |||
} | |||
|
|||
static getConfigEnv(env: Env = process.env): Env { | |||
// To match NPM's behavior, HOME is always the user's home directory. | |||
const overrideEnv = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
protip:
return {
...env,
HOME: home,
};
I'll let @arcanis do the final review and merge if there are no blockers. |
* Allow ${HOME} in .npmrc to work in Windows Windows doesn't set the HOME environment variable by default, but NPM has logic to set process.env.HOME based on the current OS home directory. See https://github.com/npm/npm/blob/fb28e5868a9dbbe21a15f23fe8cf8b3703e8adf2/lib/config/defaults.js#L81 Yarn doesn't do this, so configs such as `prefix = ${HOME}/.npm-packages` that work for NPM will cause Yarn to refuse to run. This commit updates Yarn's behavior to be closer to NPM's. Unlike NPM, this commit only sets HOME if it's not already set, to avoid potentially incompatible changes with existing Yarn users. * Revert "Allow ${HOME} in .npmrc to work in Windows" This reverts commit 436422d. * Allow ${HOME} in .npmrc to work in Windows Windows doesn't set the HOME environment variable by default, but NPM has logic to set process.env.HOME based on the current OS home directory. See https://github.com/npm/npm/blob/fb28e5868a9dbbe21a15f23fe8cf8b3703e8adf2/lib/config/defaults.js#L81 Yarn doesn't do this, so configs such as `prefix = ${HOME}/.npm-packages` that work for NPM will cause Yarn to refuse to run. This commit updates Yarn's behavior to be closer to NPM's, by using a custom/modified environment when processing NPM configurations. Add a Flow type `Env` to represent a set of environment variables. * Ensure environment is restored after test (A separate `describe` block seems like overkill.)
Windows doesn't set the HOME environment variable by default, but NPM has logic to set process.env.HOME based on the current OS home directory. See here.
Yarn doesn't do this, so an
.npmrc
config such asprefix = ${HOME}/.npm-packages
that work for NPM will cause Yarn to refuse to run; it instead exits with the following error:This commit updates Yarn's behavior to be closer to NPM's.
Unlike NPM, this commit only sets HOME if it's not already set, to avoid potentially incompatible changes with existing Yarn users.