Update
This commit is contained in:
@@ -0,0 +1,49 @@
|
||||
import assert from 'node:assert/strict';
|
||||
import { mkdtemp, mkdir, copyFile, rm } from 'node:fs/promises';
|
||||
import os from 'node:os';
|
||||
import path from 'node:path';
|
||||
import { spawnSync } from 'node:child_process';
|
||||
import test from 'node:test';
|
||||
import shellVerification from '../src/shared/shell-verification.cjs';
|
||||
|
||||
const { bashSyntaxCheckInvocation, normalizeRelativePosixPath } = shellVerification;
|
||||
|
||||
test('Bash syntax validation keeps Windows project roots in cwd and passes a relative POSIX path', () => {
|
||||
const invocation = bashSyntaxCheckInvocation('C:\\Projects\\ForgeFlow');
|
||||
assert.equal(invocation.command, 'bash');
|
||||
assert.deepEqual(invocation.args, ['-n', 'examples/server/forgeflow-deploy']);
|
||||
assert.equal(invocation.options.cwd, 'C:\\Projects\\ForgeFlow');
|
||||
assert.equal(invocation.args[1].includes('\\'), false);
|
||||
assert.equal(/^[A-Za-z]:/.test(invocation.args[1]), false);
|
||||
});
|
||||
|
||||
test('Shell validation refuses absolute and escaping script paths', () => {
|
||||
assert.throws(() => normalizeRelativePosixPath('C:\\Projects\\ForgeFlow\\script.sh'), /must be relative/);
|
||||
assert.throws(() => normalizeRelativePosixPath('/tmp/script.sh'), /must be relative/);
|
||||
assert.throws(() => normalizeRelativePosixPath('../script.sh'), /may not escape/);
|
||||
});
|
||||
|
||||
test('Bash syntax validation works from a project root containing spaces', async (t) => {
|
||||
if (spawnSync('bash', ['--version'], { encoding: 'utf8' }).status !== 0) {
|
||||
t.skip('Bash is not available in this environment.');
|
||||
return;
|
||||
}
|
||||
const tempBase = await mkdtemp(path.join(os.tmpdir(), 'forge flow verify '));
|
||||
try {
|
||||
const relativeDirectory = path.join(tempBase, 'examples', 'server');
|
||||
await mkdir(relativeDirectory, { recursive: true });
|
||||
await copyFile(new URL('../examples/server/forgeflow-deploy', import.meta.url), path.join(relativeDirectory, 'forgeflow-deploy'));
|
||||
const invocation = bashSyntaxCheckInvocation(tempBase);
|
||||
const result = spawnSync(invocation.command, invocation.args, invocation.options);
|
||||
assert.equal(result.status, 0, result.stderr);
|
||||
} finally {
|
||||
try {
|
||||
await rm(tempBase, { recursive: true, force: true, maxRetries: 20, retryDelay: 100 });
|
||||
} catch (error) {
|
||||
// Git Bash on Windows can retain a short-lived working-directory handle
|
||||
// after bash -n exits. Do not fail a successful syntax test solely because
|
||||
// Windows delayed releasing that temporary directory.
|
||||
if (!['EBUSY', 'EPERM', 'ENOTEMPTY'].includes(error?.code)) throw error;
|
||||
}
|
||||
}
|
||||
});
|
||||
Reference in New Issue
Block a user