fix(windows): cross-platform path separators, JSON quoting, and dollar signs
- Add toPosixPath() helper to normalize output paths to forward slashes - Use string concatenation for relative base paths instead of path.join() - Apply toPosixPath() to all user-facing file paths in init.cjs output - Use array-based execFileSync in test helpers to bypass shell quoting issues with JSON args and dollar signs on Windows cmd.exe Fixes 7 test failures on Windows: frontmatter set/merge (3), init path assertions (2), and state dollar-amount corruption (2). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -107,7 +107,7 @@ describe('frontmatter set', () => {
|
||||
|
||||
test('handles JSON array value', () => {
|
||||
const file = writeTempFile('---\nphase: 01\n---\nbody');
|
||||
const result = runGsdTools(`frontmatter set ${file} --field tags --value '["a","b"]'`);
|
||||
const result = runGsdTools(['frontmatter', 'set', file, '--field', 'tags', '--value', '["a","b"]']);
|
||||
assert.ok(result.success, `Command failed: ${result.error}`);
|
||||
|
||||
const content = fs.readFileSync(file, 'utf-8');
|
||||
@@ -140,7 +140,7 @@ describe('frontmatter set', () => {
|
||||
describe('frontmatter merge', () => {
|
||||
test('merges multiple fields into frontmatter', () => {
|
||||
const file = writeTempFile('---\nphase: 01\n---\nbody');
|
||||
const result = runGsdTools(`frontmatter merge ${file} --data '{"plan":"02","type":"tdd"}'`);
|
||||
const result = runGsdTools(['frontmatter', 'merge', file, '--data', '{"plan":"02","type":"tdd"}']);
|
||||
assert.ok(result.success, `Command failed: ${result.error}`);
|
||||
|
||||
const content = fs.readFileSync(file, 'utf-8');
|
||||
@@ -153,7 +153,7 @@ describe('frontmatter merge', () => {
|
||||
|
||||
test('overwrites existing fields on conflict', () => {
|
||||
const file = writeTempFile('---\nphase: 01\ntype: execute\n---\nbody');
|
||||
const result = runGsdTools(`frontmatter merge ${file} --data '{"phase":"02"}'`);
|
||||
const result = runGsdTools(['frontmatter', 'merge', file, '--data', '{"phase":"02"}']);
|
||||
assert.ok(result.success, `Command failed: ${result.error}`);
|
||||
|
||||
const content = fs.readFileSync(file, 'utf-8');
|
||||
|
||||
@@ -2,20 +2,35 @@
|
||||
* GSD Tools Test Helpers
|
||||
*/
|
||||
|
||||
const { execSync } = require('child_process');
|
||||
const { execSync, execFileSync } = require('child_process');
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
const TOOLS_PATH = path.join(__dirname, '..', 'get-shit-done', 'bin', 'gsd-tools.cjs');
|
||||
|
||||
// Helper to run gsd-tools command
|
||||
/**
|
||||
* Run gsd-tools command.
|
||||
*
|
||||
* @param {string|string[]} args - Command string (shell-interpreted) or array
|
||||
* of arguments (shell-bypassed via execFileSync, safe for JSON and dollar signs).
|
||||
* @param {string} cwd - Working directory.
|
||||
*/
|
||||
function runGsdTools(args, cwd = process.cwd()) {
|
||||
try {
|
||||
const result = execSync(`node "${TOOLS_PATH}" ${args}`, {
|
||||
cwd,
|
||||
encoding: 'utf-8',
|
||||
stdio: ['pipe', 'pipe', 'pipe'],
|
||||
});
|
||||
let result;
|
||||
if (Array.isArray(args)) {
|
||||
result = execFileSync(process.execPath, [TOOLS_PATH, ...args], {
|
||||
cwd,
|
||||
encoding: 'utf-8',
|
||||
stdio: ['pipe', 'pipe', 'pipe'],
|
||||
});
|
||||
} else {
|
||||
result = execSync(`node "${TOOLS_PATH}" ${args}`, {
|
||||
cwd,
|
||||
encoding: 'utf-8',
|
||||
stdio: ['pipe', 'pipe', 'pipe'],
|
||||
});
|
||||
}
|
||||
return { success: true, output: result.trim() };
|
||||
} catch (err) {
|
||||
return {
|
||||
|
||||
@@ -205,7 +205,7 @@ None
|
||||
);
|
||||
|
||||
const result = runGsdTools(
|
||||
"state add-decision --phase 11-01 --summary 'Benchmark prices moved from $0.50 to $2.00 to $5.00' --rationale 'track cost growth'",
|
||||
['state', 'add-decision', '--phase', '11-01', '--summary', 'Benchmark prices moved from $0.50 to $2.00 to $5.00', '--rationale', 'track cost growth'],
|
||||
tmpDir
|
||||
);
|
||||
assert.ok(result.success, `Command failed: ${result.error}`);
|
||||
@@ -233,7 +233,7 @@ None
|
||||
`
|
||||
);
|
||||
|
||||
const result = runGsdTools("state add-blocker --text 'Waiting on vendor quote $1.00 before approval'", tmpDir);
|
||||
const result = runGsdTools(['state', 'add-blocker', '--text', 'Waiting on vendor quote $1.00 before approval'], tmpDir);
|
||||
assert.ok(result.success, `Command failed: ${result.error}`);
|
||||
|
||||
const state = fs.readFileSync(path.join(tmpDir, '.planning', 'STATE.md'), 'utf-8');
|
||||
|
||||
Reference in New Issue
Block a user