Skip to content

Commit bf6d9d3

Browse files
committed
feat(cli): validate bash syntax on compile
1 parent 7d1b063 commit bf6d9d3

1 file changed

Lines changed: 35 additions & 0 deletions

File tree

src/cli/index.ts

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,10 @@ import { initCommand } from '../templates/init-command.js';
1414
import { DSLIntrospector } from '../dsl/introspection.js';
1515
import { parseWorkflowFile } from '../parsing/parser.js';
1616
import { Command } from 'commander';
17+
import { execFileSync } from 'child_process';
1718
import * as path from 'path';
1819
import * as fs from 'fs';
20+
import * as os from 'os';
1921

2022
// Simple error handling - no fancy logging or correlation IDs
2123
function handleError(error: unknown, operation: string): never {
@@ -53,6 +55,29 @@ async function writeScriptToFile(script: string, outputFile: string): Promise<vo
5355
}
5456
}
5557

58+
/**
59+
* Validate generated script for bash syntax errors.
60+
*/
61+
function validateBashSyntax(script: string): void {
62+
const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'flowsh-syntax-check-'));
63+
const tempFile = path.join(tempDir, 'script.sh');
64+
65+
try {
66+
fs.writeFileSync(tempFile, script, 'utf8');
67+
execFileSync('bash', ['-n', tempFile], { stdio: 'pipe' });
68+
} catch (error: any) {
69+
const errorOutput = error?.stderr?.toString?.() || error?.message || 'Unknown bash error';
70+
throw new Error(`Bash syntax validation failed:\n${errorOutput}`);
71+
} finally {
72+
try {
73+
fs.unlinkSync(tempFile);
74+
fs.rmdirSync(tempDir);
75+
} catch {
76+
// Best-effort cleanup
77+
}
78+
}
79+
}
80+
5681
/**
5782
* Compile command: Convert YAML workflow to shell script
5883
*/
@@ -123,6 +148,16 @@ async function compileCommand(
123148
finalScript = warnings.join('\n') + '\n' + finalScript;
124149
}
125150

151+
if (options.verbose) {
152+
console.error('🔍 Validating bash syntax...');
153+
}
154+
155+
validateBashSyntax(finalScript);
156+
157+
if (options.verbose) {
158+
console.error('✅ Bash syntax validation passed');
159+
}
160+
126161
// Dry-run mode: validate and compile but don't output
127162
if (options.dryRun) {
128163
const nodeCount = parseResult.workflow?.graph?.nodes?.length || 0;

0 commit comments

Comments
 (0)