diff --git a/CHANGELOG.md b/CHANGELOG.md index 8b6e4d85..e35152ae 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,13 @@ 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. -## [Unreleased](https://github.com/motdotla/dotenv/compare/v16.4.4...master) +## [Unreleased](https://github.com/motdotla/dotenv/compare/v16.4.5...master) + +## [16.4.5](https://github.com/motdotla/dotenv/compare/v16.4.4...v16.4.5) (2024-02-19) + +### Changed + +- 🐞 fix recent regression when using `path` option. return to historical behavior: do not attempt to auto find `.env` if `path` set. (regression was introduced in `16.4.3`) [#814](https://github.com/motdotla/dotenv/pull/814) ## [16.4.4](https://github.com/motdotla/dotenv/compare/v16.4.3...v16.4.4) (2024-02-13) diff --git a/lib/main.js b/lib/main.js index 1a99afdf..314f49ad 100644 --- a/lib/main.js +++ b/lib/main.js @@ -215,52 +215,48 @@ function configDotenv (options) { } } - let optionPathsThatExist = [] + let optionPaths = [dotenvPath] // default, look for .env if (options && options.path) { if (!Array.isArray(options.path)) { - if (fs.existsSync(options.path)) { - optionPathsThatExist = [_resolveHome(options.path)] - } + optionPaths = [_resolveHome(options.path)] } else { + optionPaths = [] // reset default for (const filepath of options.path) { - if (fs.existsSync(filepath)) { - optionPathsThatExist.push(_resolveHome(filepath)) - } + optionPaths.push(_resolveHome(filepath)) } } - - if (!optionPathsThatExist.length) { - optionPathsThatExist = [dotenvPath] - } } - // If we have options.path, and it had valid paths, use them. Else fall back to .env - const pathsToProcess = optionPathsThatExist.length ? optionPathsThatExist : [dotenvPath] - // Build the parsed data in a temporary object (because we need to return it). Once we have the final // parsed data, we will combine it with process.env (or options.processEnv if provided). - - const parsed = {} - try { - for (const path of pathsToProcess) { + let lastError + const parsedAll = {} + for (const path of optionPaths) { + try { // Specifying an encoding returns a string instead of a buffer - const singleFileParsed = DotenvModule.parse(fs.readFileSync(path, { encoding })) - DotenvModule.populate(parsed, singleFileParsed, options) - } + const parsed = DotenvModule.parse(fs.readFileSync(path, { encoding })) - let processEnv = process.env - if (options && options.processEnv != null) { - processEnv = options.processEnv + DotenvModule.populate(parsedAll, parsed, options) + } catch (e) { + if (debug) { + _debug(`Failed to load ${path} ${e.message}`) + } + lastError = e } + } - DotenvModule.populate(processEnv, parsed, options) - } catch (e) { - if (debug) { - _debug(`Failed to load ${pathsToProcess} ${e.message}`) - } - return { error: e } + let processEnv = process.env + if (options && options.processEnv != null) { + processEnv = options.processEnv + } + + DotenvModule.populate(processEnv, parsedAll, options) + + if (lastError) { + return { parsed: parsedAll, error: lastError } + } else { + return { parsed: parsedAll } } - return { parsed } } // Populates process.env from .env file diff --git a/tests/test-config.js b/tests/test-config.js index a3780a6d..029d29ba 100644 --- a/tests/test-config.js +++ b/tests/test-config.js @@ -88,16 +88,12 @@ t.test('takes URL for path option', ct => { }) t.test('takes option for path along with home directory char ~', ct => { - const existsSyncStub = sinon.stub(fs, 'existsSync').returns(true) const readFileSyncStub = sinon.stub(fs, 'readFileSync').returns('test=foo') const mockedHomedir = '/Users/dummy' const homedirStub = sinon.stub(os, 'homedir').returns(mockedHomedir) const testPath = '~/.env' dotenv.config({ path: testPath }) - ct.equal(existsSyncStub.args[0][0], testPath) - ct.ok(existsSyncStub.called) - ct.equal(readFileSyncStub.args[0][0], path.join(mockedHomedir, '.env')) ct.ok(homedirStub.called)