executeWithStdin function
Execute a command with content piped to its stdin.
Uses Process.start to launch the command via sh -c and writes
stdinContent to the process stdin before closing it.
Variable expansion should be applied to command by the caller
BEFORE calling this method. The stdinContent is passed through
without variable expansion to avoid conflicts with language-specific
$ syntax (e.g., Dart string interpolation).
Returns true if the command exits with code 0.
Implementation
Future<bool> executeWithStdin({
required String command,
required String stdinContent,
String? workingDirectory,
Map<String, String>? environment,
bool dryRun = false,
bool verbose = false,
}) async {
if (dryRun) {
final lines = stdinContent.split('\n');
print(' [DRY RUN] Would pipe stdin to: $command');
for (final line in lines.take(5)) {
print(' | $line');
}
if (lines.length > 5) {
print(' | ... (${lines.length - 5} more lines)');
}
return true;
}
if (verbose) {
final lines = stdinContent.split('\n');
print(' Piping stdin to: $command');
for (final line in lines) {
print(' | $line');
}
}
try {
final process = await Process.start(
'sh',
['-c', command],
workingDirectory: workingDirectory,
environment: environment,
);
// Write stdin content and close
process.stdin.write(stdinContent);
await process.stdin.close();
// Capture output
final stdoutStr = await process.stdout.transform(utf8.decoder).join();
final stderrStr = await process.stderr.transform(utf8.decoder).join();
final exitCode = await process.exitCode;
if (stdoutStr.isNotEmpty) {
stdout.write(stdoutStr);
}
if (stderrStr.isNotEmpty) {
stderr.write(stderrStr);
}
if (exitCode != 0) {
print(' Command failed with exit code $exitCode');
return false;
}
return true;
} catch (e) {
print(' Error executing command with stdin: $e');
return false;
}
}