Skip to content
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

Merged
merged 4 commits into from
Oct 24, 2017

Conversation

joshkel
Copy link
Contributor

@joshkel joshkel commented Oct 12, 2017

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 as prefix = ${HOME}/.npm-packages that work for NPM will cause Yarn to refuse to run; it instead exits with the following error:

yarn install v1.2.0
error An unexpected error occurred: "Failed to replace env in config: ${HOME}".
info If you think this is a bug, please open a bug report with the information provided in "C:\\src\\yarn\\yarn-error.log".
info Visit https://yarnpkg.com/en/docs/cli/install for documentation about this command.

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.

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.
@buildsize
Copy link

buildsize bot commented Oct 12, 2017

This change will decrease the build size from 9.94 MB to 9.91 MB, a decrease of 22.5 KB (0%)

File name Previous Size New Size Change
yarn-[version].noarch.rpm 859.32 KB 857.36 KB -1.96 KB (0%)
yarn-[version].js 3.78 MB 3.77 MB -8.62 KB (0%)
yarn-legacy-[version].js 3.83 MB 3.82 MB -8.67 KB (0%)
yarn-v[version].tar.gz 864.97 KB 863.21 KB -1.76 KB (0%)
yarn_[version]all.deb 653.99 KB 652.49 KB -1.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;
Copy link
Member

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.

@arcanis
Copy link
Member

arcanis commented Oct 12, 2017

Why don't you just use ~?

Copy link
Member

@BYK BYK left a 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();
Copy link
Member

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

Copy link
Contributor Author

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!

Copy link
Contributor Author

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.

@joshkel
Copy link
Contributor Author

joshkel commented Oct 12, 2017

Why don't you just use ~?

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.

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.)
@BYK
Copy link
Member

BYK commented Oct 17, 2017

@joshkel sorry for the wait didn't realize you've updated the PR. Will review it shortly.

Copy link
Member

@BYK BYK left a 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};
Copy link
Member

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 = {
Copy link
Member

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,
};

@BYK
Copy link
Member

BYK commented Oct 17, 2017

I'll let @arcanis do the final review and merge if there are no blockers.

@arcanis arcanis merged commit 1ccb710 into yarnpkg:master Oct 24, 2017
joaolucasl pushed a commit to joaolucasl/yarn that referenced this pull request Oct 27, 2017
* 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.)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants