Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions src/util/fs/executeScript.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { execFile } from 'child_process';
import { resolve } from 'path';
import executeScript from './executeScript.js';

jest.mock('child_process', () => ({
Expand Down Expand Up @@ -70,6 +71,25 @@ describe('executeScript', () => {
);
});

it('resolves relative hook paths before changing the working directory', async () => {
expect.assertions(1);
const scriptPath = 'project/.cli/init.js';
const resolvedScriptPath = resolve(scriptPath);
mockExecFileResult(null, 'done');

await executeScript(scriptPath);

expect(execFileMock).toHaveBeenCalledWith(
process.execPath,
[resolvedScriptPath],
{
cwd: resolve('project/.cli'),
encoding: 'utf8',
},
expect.any(Function),
);
});

it('resolves stderr when stdout is empty', async () => {
expect.assertions(1);
mockExecFileResult(null, '', 'well, that went poorly');
Expand Down
10 changes: 6 additions & 4 deletions src/util/fs/executeScript.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { execFile } from 'child_process';
import { dirname } from 'path';
import { dirname, resolve as resolvePath } from 'path';

/**
* Takes a path to a script, and executes it.
Expand All @@ -9,14 +9,16 @@ import { dirname } from 'path';
export default async function executeScript(
scriptPath: string,
): Promise<string> {
const resolvedScriptPath = resolvePath(scriptPath);

return new Promise((resolve, reject) => {
execFile(
process.execPath,
[scriptPath],
[resolvedScriptPath],
{
// Run from the hook directory so hook-relative file operations do not
// depend on the shell location that invoked the CLI.
cwd: dirname(scriptPath),
cwd: dirname(resolvedScriptPath),
encoding: 'utf8',
},
(error, stdout, stderr) => {
Expand All @@ -25,7 +27,7 @@ export default async function executeScript(

return reject(
new Error(
`Unable to execute hook script "${scriptPath}": ${output}`,
`Unable to execute hook script "${resolvedScriptPath}": ${output}`,
),
);
}
Expand Down
Loading