-
-
Notifications
You must be signed in to change notification settings - Fork 31.6k
src: add support to override local env variables option #52531
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
base: main
Are you sure you want to change the base?
Conversation
Review requested:
|
689209b
to
20a9ddc
Compare
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 I miss the whole point. What's the use case and the feature request that resulted in this change?
@anonrig when reading the issue about using .env files, I noticed a discussion about overriding local environment settings: |
I'm not sure who to ping for more eyes/comments on this, but I'll try @nodejs/tooling. |
src/node_options.cc
Outdated
@@ -627,6 +627,11 @@ EnvironmentOptionsParser::EnvironmentOptionsParser() { | |||
"set environment variables from supplied file", | |||
&EnvironmentOptions::env_file); | |||
Implies("--env-file", "[has_env_file_string]"); | |||
AddOption("--override-env-var", | |||
"override environment variables set on machine with variables from " | |||
"supplied file", |
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.
there needs to be a description with the usage of env-file flag or loadEnvFile
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.
@anonrig could you check if it's correct please ?
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.
Lgtm
There isn’t, but generally I encourage people to open an issue proposing a new feature before going ahead and coding the new feature. That way you get preliminary feedback before you implement, which might change the way you implement it and save you time as compared to doing revisions (like renaming this flag, for example). Or if the feedback is very negative, it might save you from wasting your time implementing a feature that won’t land. If nothing else, it separates the feedback related to the idea of the feature from the feedback related to the implementation of the feature; the issue can contain the former and the PR would get the latter. For this feature in particular, since it’s not on the list of anticipated enhancements to |
20a9ddc
to
3607629
Compare
@GeoffreyBooth Thank you for explaining this. I was inspired by the discussions to contribute. |
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.
Small things left on docs and tests. After them I think we can merge this.
doc/api/cli.md
Outdated
|
||
If you want to use the value from the `.env` file, you should add the | ||
`--env-file-override-local` flag when running your application, or use | ||
[`process.loadEnvFile({ override: true })`][] in your code. |
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.
This line is unnecessary for the CLI flag documentation. You should also mention how --env-file flag is required as well
doc/api/process.md
Outdated
```cjs | ||
const assert = require('node:assert'); | ||
const { loadEnvFile } = require('node:process'); | ||
loadEnvFile('.env', { override: true }); |
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.
Process is a global variable. No need to require/import it.
loadEnvFile('.env', { override: true }); | |
process.loadEnvFile('.env', { override: true }); |
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 was forced to import it because of the linter no-restricted-globals
.
I will disable the eslint rule then
}); | ||
|
||
it('supports passing options only', async () => { | ||
process.env.BASIC = 'Original value'; |
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.
If you pass this variable in here, you mutate the current process which gets inherited by the spawn process call. But if you pass { env } as an option, it would not mutate the current process env vars.
The
notable-change
Please suggest a text for the release notes if you'd like to include a more detailed summary, then proceed to update the PR description with the text or a link to the notable change suggested text comment. Otherwise, the commit will be placed in the Other Notable Changes section. |
@@ -2305,6 +2313,52 @@ import { loadEnvFile } from 'node:process'; | |||
loadEnvFile(); | |||
``` | |||
|
|||
Override local environment variables using override option | |||
|
|||
Example: |
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 believe this line is unnecessary, it's not a pattern that exists anywhere else in the docs AFAIK
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.
This sentence appears multiple times in the doc:
https://nodejs.org/api/cli.html#--allow-worker
https://nodejs.org/api/fs.html#fs-constants
https://nodejs.org/api/http.html#httpvalidateheadernamename-label
and more.
If you think this is not a good practice I can remove it.
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.
currently these examples use a very mixed bag of import/require. You import/require assert
, sometimes process
, and sometimes import process
... and a named export of process, and sometimes just a named export of process.
I've never seen mixing the module and a named import, maybe it's just a pattern I'm ignorant of? Either way, IMO we should just be consistent across all examples - named exports are the most direct avenue to that, I think.
Blocking because I'd really like to try to not land docs that are less than ideal and then fix later. Should be a pretty fast tweak, happy to unblock once it's addressed.
From what I can tell the docs are just using
I am not sure if you noticed but that has been the way to write the examples in both ways to allow toggling between CJS/ESM style in the doc (e.g. see https://nodejs.org/docs/latest/api/fs.html#promise-example for how the toggling works in the web page). |
@joyeecheung yep, I'm aware - I've written a handful of docs that do that/added missing CJS or ESM to examples where only one is present. Here's examples of how the docs here are inconsistent: import assert from 'node:assert';
import process from 'node:process'; const assert = require('node:assert');
const { loadEnvFile } = require('node:process');
loadEnvFile('.env', { override: true }); import assert from 'node:assert';
import process, { loadEnvFile } from 'node:process';
loadEnvFile('.env', { override: true });
assert.strictEqual(process.env.API_KEY, 'env-custom-key');
There's kinda a lot in a small space, so I figured pointing issues out broadly as the few categories that occur multiple times would be helpful but if it's not I'm happy to comment every problem individually. |
I see, there are some inconsistencies in import styles though I think in this code base in general, style preferences should not be blocking unless the linter complains. I’d suggest adding linter rules to forbid it or following it up with doc change PR. |
8f4f8c2
to
5328e49
Compare
c39b038
to
ec91591
Compare
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.
disagree that we shouldn't block on docs being inconsistent but I don't think this is the venue to hash that out
I don’t think it’s a blocking concern for this PR. It’s something that can be handled in a follow-up that focuses just on standardizing the code examples in the docs, ideally with a lint rule to enforce future consistency. |
Do you think this PR is ready to be merged, or does it still need additional work? |
I'm sorry I missed this. I think we can merge it. |
de5019c
to
304248e
Compare
@anonrig Could you please run the CI ? |
304248e
to
c723fb0
Compare
Assume you have a local environment variable on your machine | ||
|
||
```bash | ||
API_KEY="local-key" | ||
``` | ||
|
||
Meanwhile, your `.env` file contains: | ||
|
||
```bash | ||
API_KEY='env-custom-key' | ||
``` | ||
|
||
If you want to use the value from the `.env` file, you should add the | ||
`--env-file-override-local` flag when running your application. | ||
This flag requires the use of the `--env-file` flag to load environment files. | ||
|
||
```js | ||
console.log(process.env.API_KEY); // 'env-custom-key' | ||
``` | ||
|
||
If you prefer to keep the local value, do not add the | ||
`--env-file-override-local` flag or avoid providing the override option to | ||
[`process.loadEnvFile()`][] | ||
|
||
```js | ||
console.log(process.env.API_KEY); // 'local-key' | ||
``` |
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 the example should go more straight to the point
Assume you have a local environment variable on your machine | |
```bash | |
API_KEY="local-key" | |
``` | |
Meanwhile, your `.env` file contains: | |
```bash | |
API_KEY='env-custom-key' | |
``` | |
If you want to use the value from the `.env` file, you should add the | |
`--env-file-override-local` flag when running your application. | |
This flag requires the use of the `--env-file` flag to load environment files. | |
```js | |
console.log(process.env.API_KEY); // 'env-custom-key' | |
``` | |
If you prefer to keep the local value, do not add the | |
`--env-file-override-local` flag or avoid providing the override option to | |
[`process.loadEnvFile()`][] | |
```js | |
console.log(process.env.API_KEY); // 'local-key' | |
``` | |
```console | |
$ echo 'API_KEY="local-key"' > .env | |
$ node --env-file=.env -p 'process.env.API_KEY' | |
local-key | |
$ export API_KEY='env-custom-key' | |
$ node --env-file=.env -p 'process.env.API_KEY' | |
env-custom-key | |
$ node --env-file=.env --env-file-override-local -p 'process.env.API_KEY' | |
local-key | |
``` |
Assume you have a local environment variable on your machine | ||
|
||
```bash | ||
API_KEY="local-key" | ||
``` | ||
|
||
Meanwhile, your `.env` file contains: | ||
|
||
```bash | ||
API_KEY='env-custom-key' | ||
``` | ||
|
||
If you want to use the value from the `.env` file | ||
|
||
```js | ||
process.loadEnvFile('.env', { override: true }); | ||
console.log(process.env.API_KEY); // 'env-custom-key' | ||
``` | ||
|
||
Load environment variables with options only | ||
|
||
```js | ||
process.loadEnvFile({ override: true }); | ||
``` | ||
|
||
This API is available through the [`--env-file-override-local`][] flag. |
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.
Same here
Assume you have a local environment variable on your machine | |
```bash | |
API_KEY="local-key" | |
``` | |
Meanwhile, your `.env` file contains: | |
```bash | |
API_KEY='env-custom-key' | |
``` | |
If you want to use the value from the `.env` file | |
```js | |
process.loadEnvFile('.env', { override: true }); | |
console.log(process.env.API_KEY); // 'env-custom-key' | |
``` | |
Load environment variables with options only | |
```js | |
process.loadEnvFile({ override: true }); | |
``` | |
This API is available through the [`--env-file-override-local`][] flag. | |
```console | |
$ echo 'API_KEY="local-key"' > .env | |
$ node -p 'process.loadEnvFile('.env');process.env.API_KEY' | |
local-key | |
$ export API_KEY='env-custom-key' | |
$ node -p 'process.loadEnvFile('.env');process.env.API_KEY' | |
env-custom-key | |
$ node -p 'process.loadEnvFile('.env', { override: true });process.env.API_KEY' | |
local-key | |
$ node --env-file-override-local -p 'process.loadEnvFile('.env');process.env.API_KEY' | |
env-custom-key | |
``` |
c723fb0
to
a13b1a2
Compare
"override environment variables set on machine with variables from " | ||
"supplied files via --env-file flag or loadEnvFile() process function", |
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.
Is that correct that the flag has influence over loadEnvFile()
? Could we add a test case for that?
"override environment variables set on machine with variables from " | |
"supplied files via --env-file flag or loadEnvFile() process function", | |
"override environment variables set on machine with variables from " | |
"supplied files via --env-file flag", |
What if #53060 lands? And someone passes both |
I'd argue for the former: it's simpler, more consistent (if you pass multiple |
Following #49148
This PR aims to add support to override local env variables with variables from defined env files.
loadEnvFile