Skip to content

Commit 8d8a3e5

Browse files
committed
src: add --run-in-directory runtime flag
1 parent 36e89dd commit 8d8a3e5

File tree

5 files changed

+38
-1
lines changed

5 files changed

+38
-1
lines changed

doc/api/cli.md

+10
Original file line numberDiff line numberDiff line change
@@ -2294,6 +2294,16 @@ The following environment variables are set when running a script with `--run`:
22942294
* `NODE_RUN_PACKAGE_JSON_PATH`: The path to the `package.json` that is being
22952295
processed.
22962296

2297+
### `--run-in-directory=<dir>`
2298+
2299+
Run a package.json script in a specific working directory.
2300+
2301+
For example:
2302+
2303+
```console
2304+
$ node --run-in-directory=/path/to/dir --run test
2305+
```
2306+
22972307
### `--secure-heap-min=n`
22982308

22992309
<!-- YAML

src/node_options.cc

+3
Original file line numberDiff line numberDiff line change
@@ -1216,6 +1216,9 @@ PerProcessOptionsParser::PerProcessOptionsParser(
12161216
AddOption("--run",
12171217
"Run a script specified in package.json",
12181218
&PerProcessOptions::run);
1219+
AddOption("--run-in-directory",
1220+
"Run a package.json script in a custom working directory",
1221+
&PerProcessOptions::run_in);
12191222
AddOption(
12201223
"--disable-wasm-trap-handler",
12211224
"Disable trap-handler-based WebAssembly bound checks. V8 will insert "

src/node_options.h

+1
Original file line numberDiff line numberDiff line change
@@ -327,6 +327,7 @@ class PerProcessOptions : public Options {
327327
bool print_version = false;
328328
std::string experimental_sea_config;
329329
std::string run;
330+
std::string run_in_directory;
330331

331332
#ifdef NODE_HAVE_I18N_SUPPORT
332333
std::string icu_data_dir;

src/node_task_runner.cc

+10-1
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,16 @@ void ProcessRunner::OnExit(int64_t exit_status, int term_signal) {
206206

207207
void ProcessRunner::Run() {
208208
// keeps the string alive until destructor
209-
cwd = package_json_path_.parent_path().string();
209+
if (!node::per_process::cli_options->run_in_directory.empty()) {
210+
cwd = node::per_process::cli_options->run_in_directory;
211+
if (!std::filesystem::is_directory(cwd)) {
212+
fprintf(stderr, "Error: %s is not a directory\n", cwd.c_str());
213+
init_result->exit_code_ = ExitCode::kGenericUserError;
214+
return;
215+
}
216+
} else {
217+
cwd = package_json_path_.parent_path().string();
218+
}
210219
options_.cwd = cwd.c_str();
211220
if (int r = uv_spawn(loop_, &process_, &options_)) {
212221
fprintf(stderr, "Error: %s\n", uv_strerror(r));

test/parallel/test-node-run.js

+14
Original file line numberDiff line numberDiff line change
@@ -222,4 +222,18 @@ describe('node --run [command]', () => {
222222
assert.strictEqual(child.stdout, '');
223223
assert.strictEqual(child.code, 1);
224224
});
225+
226+
it('runs script in a custom working directory using --run-in-directory', async () => {
227+
const customDir = fixtures.path('run-script');
228+
const child = await common.spawnPromisified(
229+
process.execPath,
230+
[ '--run-in-directory', customDir, '--run', `pwd${envSuffix}` ],
231+
232+
{ cwd: fixtures.path('run-script/sub-directory') }
233+
);
234+
235+
assert.strictEqual(child.stdout.trim(), customDir);
236+
assert.strictEqual(child.stderr, '');
237+
assert.strictEqual(child.code, 0);
238+
});
225239
});

0 commit comments

Comments
 (0)