Skip to content

Commit 40e26e9

Browse files
authored
Merge pull request #889 from motdotla/env-quiet
support passing DOTENV_CONFIG_QUIET=true (and other DOTENV_CONFIG opt…
2 parents 13bc310 + e99c367 commit 40e26e9

File tree

4 files changed

+155
-95
lines changed

4 files changed

+155
-95
lines changed

CHANGELOG.md

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,33 @@
22

33
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
44

5-
## [Unreleased](https://github.com/motdotla/dotenv/compare/v17.1.0...master)
5+
## [Unreleased](https://github.com/motdotla/dotenv/compare/v17.2.0...master)
6+
7+
## [17.2.0](https://github.com/motdotla/dotenv/compare/v17.1.0...v17.2.0) (2025-07-09)
8+
9+
### Added
10+
11+
* Optionally specify `DOTENV_CONFIG_QUIET=true` in your environment or `.env` file to quiet the runtime log ([#889](https://github.com/motdotla/dotenv/pull/889))
12+
* Just like dotenv any `DOTENV_CONFIG_` environment variables take precedence over any code set options like `({quiet: false})`
13+
14+
```ini
15+
# .env
16+
DOTENV_CONFIG_QUIET=true
17+
HELLO="World"
18+
```
19+
```js
20+
// index.js
21+
require('dotenv').config()
22+
console.log(`Hello ${process.env.HELLO}`)
23+
```
24+
```sh
25+
$ node index.js
26+
Hello World
27+
28+
or
29+
30+
$ DOTENV_CONFIG_QUIET=true node index.js
31+
```
632

733
## [17.1.0](https://github.com/motdotla/dotenv/compare/v17.0.1...v17.1.0) (2025-07-07)
834

lib/main.js

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,13 @@ function _getRandomTip () {
2525
return TIPS[Math.floor(Math.random() * TIPS.length)]
2626
}
2727

28+
function parseBoolean (value) {
29+
if (typeof value === 'string') {
30+
return !['false', '0', 'no', 'off', ''].includes(value.toLowerCase())
31+
}
32+
return Boolean(value)
33+
}
34+
2835
function supportsAnsi () {
2936
return process.stdout.isTTY // && process.env.TERM !== 'dumb'
3037
}
@@ -216,8 +223,8 @@ function _resolveHome (envPath) {
216223
}
217224

218225
function _configVault (options) {
219-
const debug = Boolean(options && options.debug)
220-
const quiet = Boolean(options && options.quiet)
226+
const debug = parseBoolean(process.env.DOTENV_CONFIG_DEBUG || (options && options.debug))
227+
const quiet = parseBoolean(process.env.DOTENV_CONFIG_QUIET || (options && options.quiet))
221228

222229
if (debug || !quiet) {
223230
_log('Loading env from encrypted .env.vault')
@@ -238,8 +245,12 @@ function _configVault (options) {
238245
function configDotenv (options) {
239246
const dotenvPath = path.resolve(process.cwd(), '.env')
240247
let encoding = 'utf8'
241-
const debug = Boolean(options && options.debug)
242-
const quiet = Boolean(options && options.quiet)
248+
let processEnv = process.env
249+
if (options && options.processEnv != null) {
250+
processEnv = options.processEnv
251+
}
252+
let debug = parseBoolean(processEnv.DOTENV_CONFIG_DEBUG || (options && options.debug))
253+
let quiet = parseBoolean(processEnv.DOTENV_CONFIG_QUIET || (options && options.quiet))
243254

244255
if (options && options.encoding) {
245256
encoding = options.encoding
@@ -279,13 +290,12 @@ function configDotenv (options) {
279290
}
280291
}
281292

282-
let processEnv = process.env
283-
if (options && options.processEnv != null) {
284-
processEnv = options.processEnv
285-
}
286-
287293
const populated = DotenvModule.populate(processEnv, parsedAll, options)
288294

295+
// handle user settings DOTENV_CONFIG_ options inside .env file(s)
296+
debug = parseBoolean(processEnv.DOTENV_CONFIG_DEBUG || debug)
297+
quiet = parseBoolean(processEnv.DOTENV_CONFIG_QUIET || quiet)
298+
289299
if (debug || !quiet) {
290300
const keysCount = Object.keys(populated).length
291301
const shortPaths = []

tests/test-config-vault.js

Lines changed: 11 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -25,60 +25,6 @@ t.afterEach(() => {
2525
}
2626
})
2727

28-
t.test('logs when no path is set', ct => {
29-
ct.plan(1)
30-
31-
logStub = sinon.stub(console, 'log')
32-
33-
dotenv.config()
34-
ct.ok(logStub.called)
35-
})
36-
37-
t.test('does log by default', ct => {
38-
ct.plan(1)
39-
40-
logStub = sinon.stub(console, 'log')
41-
42-
dotenv.config({ path: testPath })
43-
ct.ok(logStub.called)
44-
})
45-
46-
t.test('does not log if quiet flag passed true', ct => {
47-
ct.plan(1)
48-
49-
logStub = sinon.stub(console, 'log')
50-
51-
dotenv.config({ path: testPath, quiet: true })
52-
ct.ok(logStub.notCalled)
53-
})
54-
55-
t.test('does log if quiet flag false', ct => {
56-
ct.plan(1)
57-
58-
logStub = sinon.stub(console, 'log')
59-
60-
dotenv.config({ path: testPath, quiet: false })
61-
ct.ok(logStub.called)
62-
})
63-
64-
t.test('does log if quiet flag present and undefined/null', ct => {
65-
ct.plan(1)
66-
67-
logStub = sinon.stub(console, 'log')
68-
69-
dotenv.config({ path: testPath, quiet: undefined })
70-
ct.ok(logStub.called)
71-
})
72-
73-
t.test('logs if debug set', ct => {
74-
ct.plan(1)
75-
76-
logStub = sinon.stub(console, 'log')
77-
78-
dotenv.config({ path: testPath, debug: true })
79-
ct.ok(logStub.called)
80-
})
81-
8228
t.test('does log when testPath calls to .env.vault directly (interpret what the user meant)', ct => {
8329
ct.plan(1)
8430

@@ -88,18 +34,10 @@ t.test('does log when testPath calls to .env.vault directly (interpret what the
8834
ct.ok(logStub.called)
8935
})
9036

91-
t.test('logs when testPath calls to .env.vault directly (interpret what the user meant) and debug true', ct => {
92-
ct.plan(1)
93-
94-
logStub = sinon.stub(console, 'log')
95-
96-
dotenv.config({ path: `${testPath}.vault`, debug: true })
97-
ct.ok(logStub.called)
98-
})
99-
10037
t.test('warns if DOTENV_KEY exists but .env.vault does not exist', ct => {
10138
ct.plan(1)
10239

40+
const testPath = 'tests/.env'
10341
logStub = sinon.stub(console, 'log')
10442

10543
const existsSync = sinon.stub(fs, 'existsSync').returns(false) // make .env.vault not exist
@@ -113,6 +51,7 @@ t.test('warns if DOTENV_KEY exists but .env.vault does not exist', ct => {
11351
t.test('warns if DOTENV_KEY exists but .env.vault does not exist (set as array)', ct => {
11452
ct.plan(1)
11553

54+
const testPath = 'tests/.env'
11655
logStub = sinon.stub(console, 'log')
11756

11857
const existsSync = sinon.stub(fs, 'existsSync').returns(false) // make .env.vault not exist
@@ -123,6 +62,15 @@ t.test('warns if DOTENV_KEY exists but .env.vault does not exist (set as array)'
12362
ct.end()
12463
})
12564

65+
t.test('logs when testPath calls to .env.vault directly (interpret what the user meant) and debug true', ct => {
66+
ct.plan(1)
67+
68+
logStub = sinon.stub(console, 'log')
69+
70+
dotenv.config({ path: `${testPath}.vault`, debug: true })
71+
ct.ok(logStub.called)
72+
})
73+
12674
t.test('returns parsed object', ct => {
12775
ct.plan(1)
12876

0 commit comments

Comments
 (0)