From 127d263ce265ad02750ac0c2393017229e6f025b Mon Sep 17 00:00:00 2001 From: Yagiz Nizipli Date: Fri, 18 Aug 2023 15:18:13 -0400 Subject: [PATCH] src: allow absolute paths for `--env-file` --- src/node.cc | 12 +++++++++--- src/node_dotenv.cc | 6 +++--- src/node_dotenv.h | 3 ++- test/parallel/test-dotenv-edge-cases.js | 20 ++++++++++++++++++-- 4 files changed, 32 insertions(+), 9 deletions(-) diff --git a/src/node.cc b/src/node.cc index e6be00eeb3c185..2d0de0f28e6b31 100644 --- a/src/node.cc +++ b/src/node.cc @@ -124,6 +124,7 @@ #include #include #include +#include #include #include @@ -844,10 +845,15 @@ static ExitCode InitializeNodeWithArgsInternal( auto file_path = node::Dotenv::GetPathFromArgs(*argv); if (file_path.has_value()) { - auto cwd = Environment::GetCwd(Environment::GetExecPath(*argv)); - std::string path = cwd + kPathSeparator + file_path.value(); CHECK(!per_process::v8_initialized); - per_process::dotenv_file.ParsePath(path); + + if (file_path->is_absolute()) { + per_process::dotenv_file.ParsePath(file_path->string()); + } else { + auto cwd = Environment::GetCwd(Environment::GetExecPath(*argv)); + std::string path = cwd + kPathSeparator + file_path->string(); + per_process::dotenv_file.ParsePath(path); + } per_process::dotenv_file.AssignNodeOptionsIfAvailable(&node_options); } diff --git a/src/node_dotenv.cc b/src/node_dotenv.cc index d8d6fc1d55d3de..0f1db9db2737aa 100644 --- a/src/node_dotenv.cc +++ b/src/node_dotenv.cc @@ -8,7 +8,7 @@ namespace node { using v8::NewStringType; using v8::String; -std::optional Dotenv::GetPathFromArgs( +std::optional Dotenv::GetPathFromArgs( const std::vector& args) { std::string_view flag = "--env-file"; // Match the last `--env-file` @@ -26,7 +26,7 @@ std::optional Dotenv::GetPathFromArgs( auto equal_char = path->find('='); if (equal_char != std::string::npos) { - return path->substr(equal_char + 1); + return std::filesystem::path(path->substr(equal_char + 1)); } auto next_arg = std::prev(path); @@ -35,7 +35,7 @@ std::optional Dotenv::GetPathFromArgs( return std::nullopt; } - return *next_arg; + return std::filesystem::path(*next_arg); } void Dotenv::SetEnvironment(node::Environment* env) { diff --git a/src/node_dotenv.h b/src/node_dotenv.h index 2fb810386324fc..db40defdf3b09c 100644 --- a/src/node_dotenv.h +++ b/src/node_dotenv.h @@ -5,6 +5,7 @@ #include "util-inl.h" +#include #include #include @@ -23,7 +24,7 @@ class Dotenv { void AssignNodeOptionsIfAvailable(std::string* node_options); void SetEnvironment(Environment* env); - static std::optional GetPathFromArgs( + static std::optional GetPathFromArgs( const std::vector& args); private: diff --git a/test/parallel/test-dotenv-edge-cases.js b/test/parallel/test-dotenv-edge-cases.js index 1d256799bfbb13..81aaade38b8d15 100644 --- a/test/parallel/test-dotenv-edge-cases.js +++ b/test/parallel/test-dotenv-edge-cases.js @@ -2,10 +2,13 @@ const common = require('../common'); const assert = require('node:assert'); +const path = require('node:path'); +const fixtures = require('../common/fixtures'); const { describe, it } = require('node:test'); -const validEnvFilePath = '../fixtures/dotenv/valid.env'; -const relativePath = '../fixtures/dotenv/node-options.env'; +const validEnvFilePath = path.relative(__dirname, fixtures.path('dotenv/valid.env')); +const absolutePath = fixtures.path('dotenv/node-options.env'); +const relativePath = path.relative(__dirname, absolutePath); describe('.env supports edge cases', () => { @@ -35,4 +38,17 @@ describe('.env supports edge cases', () => { assert.strictEqual(child.code, 0); }); + it('should support absolute paths', async () => { + const code = ` + require('assert').strictEqual(process.env.CUSTOM_VARIABLE, 'hello-world'); + `.trim(); + const child = await common.spawnPromisified( + process.execPath, + [ '--env-file', absolutePath, '--eval', code ], + { cwd: __dirname }, + ); + assert.strictEqual(child.stderr, ''); + assert.strictEqual(child.code, 0); + }); + });