Skip to content

Commit 4416cc0

Browse files
committed
src: add --run-from runtime flag
1 parent 1b5b019 commit 4416cc0

File tree

5 files changed

+72
-1
lines changed

5 files changed

+72
-1
lines changed

doc/api/cli.md

+16
Original file line numberDiff line numberDiff line change
@@ -2294,6 +2294,22 @@ 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-from=<dir>`
2298+
2299+
<!-- YAML
2300+
added: REPLACEME
2301+
-->
2302+
2303+
> Stability: 1.0 - Early development
2304+
2305+
Run a script defined in the package.json located in the specified directory.
2306+
2307+
For example:
2308+
2309+
```bash
2310+
node --run-from=/path/to/dir --run test
2311+
```
2312+
22972313
### `--secure-heap-min=n`
22982314

22992315
<!-- 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-from",
1220+
"Run a package.json script in a specific working directory",
1221+
&PerProcessOptions::run_from);
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_from;
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_from.empty()) {
210+
cwd = node::per_process::cli_options->run_from;
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

+42
Original file line numberDiff line numberDiff line change
@@ -222,4 +222,46 @@ 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-from', async () => {
227+
const customDir = fixtures.path('run-script');
228+
const child = await common.spawnPromisified(
229+
process.execPath,
230+
[ '--run-from', 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+
});
239+
240+
it('returns error on non-directory path for --run-from', async () => {
241+
const nonDirPath = fixtures.path('run-script/package.json');
242+
243+
const child = await common.spawnPromisified(
244+
process.execPath,
245+
[ '--run-from', nonDirPath, '--run', 'pwd' ],
246+
{ cwd: fixtures.path('run-script') }
247+
);
248+
249+
assert.match(child.stderr, /not a directory/);
250+
assert.strictEqual(child.stdout, '');
251+
assert.strictEqual(child.code, 1);
252+
});
253+
254+
it('--run-from should be no-op when used without --run', async () => {
255+
const dirPath = fixtures.path('run-script/package.json');
256+
257+
const child = await common.spawnPromisified(
258+
process.execPath,
259+
[ '--run-from', dirPath, '--print', 'process.cwd()' ],
260+
{ cwd: process.cwd() }
261+
);
262+
263+
assert.strictEqual(child.stderr, '');
264+
assert.strictEqual(child.stdout, process.cwd() + '\n');
265+
assert.strictEqual(child.code, 0);
266+
});
225267
});

0 commit comments

Comments
 (0)