Piping into Code fails if data writes delayed (fix #155341) (#156973)

This commit is contained in:
Benjamin Pasero
2022-08-03 09:41:12 +02:00
committed by GitHub
parent 8125126a03
commit f8ae10c8d0
3 changed files with 17 additions and 9 deletions
+1 -1
View File
@@ -179,7 +179,7 @@ export async function main(argv: string[]): Promise<any> {
// returns a file path where stdin input is written into (write in progress).
try {
readFromStdin(stdinFilePath, !!verbose); // throws error if file can not be written
await readFromStdin(stdinFilePath, !!verbose); // throws error if file can not be written
// Make sure to open tmp file
addArg(argv, stdinFilePath);
+11 -4
View File
@@ -39,26 +39,33 @@ export function getStdinFilePath(): string {
}
export async function readFromStdin(targetPath: string, verbose: boolean): Promise<void> {
let encoding = await resolveTerminalEncoding(verbose);
const iconv = await import('@vscode/iconv-lite-umd');
let [encoding, iconv] = await Promise.all([
resolveTerminalEncoding(verbose), // respect terminal encoding when piping into file
import('@vscode/iconv-lite-umd'), // lazy load encoding module for usage
Promises.appendFile(targetPath, '') // make sure file exists right away (https://github.com/microsoft/vscode/issues/155341)
]);
if (!iconv.encodingExists(encoding)) {
console.log(`Unsupported terminal encoding: ${encoding}, falling back to UTF-8.`);
encoding = 'utf8';
}
// Pipe into tmp file using terminals encoding
// Use a `Queue` to be able to use `appendFile`
// which helps file watchers to be aware of the
// changes because each append closes the underlying
// file descriptor.
// (https://github.com/microsoft/vscode/issues/148952)
const decoder = iconv.getDecoder(encoding);
const appendFileQueue = new Queue();
const decoder = iconv.getDecoder(encoding);
process.stdin.on('data', chunk => {
const chunkStr = decoder.write(chunk);
appendFileQueue.queue(() => Promises.appendFile(targetPath, chunkStr));
});
process.stdin.on('end', () => {
const end = decoder.end();
if (typeof end === 'string') {
+5 -4
View File
@@ -87,7 +87,7 @@ const cliRemoteAuthority = process.env['VSCODE_CLI_AUTHORITY'] as string;
const cliStdInFilePath = process.env['VSCODE_STDIN_FILE_PATH'] as string;
export function main(desc: ProductDescription, args: string[]): void {
export async function main(desc: ProductDescription, args: string[]): Promise<void> {
if (!cliPipe && !cliCommand) {
console.log('Command is only available in WSL or inside a Visual Studio Code terminal.');
return;
@@ -184,7 +184,7 @@ export function main(desc: ProductDescription, args: string[]): void {
let stdinFilePath = cliStdInFilePath;
if (!stdinFilePath) {
stdinFilePath = getStdinFilePath();
readFromStdin(stdinFilePath, verbose); // throws error if file can not be written
await readFromStdin(stdinFilePath, verbose); // throws error if file can not be written
}
// Make sure to open tmp file
@@ -460,5 +460,6 @@ function mapFileToRemoteUri(uri: string): string {
}
const [, , productName, version, commit, executableName, ...remainingArgs] = process.argv;
main({ productName, version, commit, executableName }, remainingArgs);
main({ productName, version, commit, executableName }, remainingArgs).then(null, err => {
console.error(err.message || err.stack || err);
});