diff --git a/vscode/src/repository/http-utils.ts b/vscode/src/repository/http-utils.ts index 7b9a8b6f..de3fbf14 100644 --- a/vscode/src/repository/http-utils.ts +++ b/vscode/src/repository/http-utils.ts @@ -67,6 +67,7 @@ export async function refreshAccessToken(refreshToken: string): Promise export async function downloadFile(url: string, destinationPath: string, onProgress: (progress: number) => void): Promise { + /// First download on a temp path. This prevents from converting partial downloaded files (due to interruption) into executables. const tempFilePath = `${destinationPath}.tmp`; const response = await axios({ @@ -97,6 +98,6 @@ export async function downloadFile(url: string, destinationPath: string, onProgr writer.on('finish', resolve); writer.on('error', reject); }); - - fs.renameSync(tempFilePath, destinationPath); // Only write file to destination path once download finishes -} + // Downloaded executable is saved as a pre-downloaded file which will be renamed in the next session. + fs.renameSync(tempFilePath, `${destinationPath}.pre-downloaded`); +} \ No newline at end of file diff --git a/vscode/src/utilities/commanddash-integration/dart-cli-client.ts b/vscode/src/utilities/commanddash-integration/dart-cli-client.ts index b75e8407..33683f99 100644 --- a/vscode/src/utilities/commanddash-integration/dart-cli-client.ts +++ b/vscode/src/utilities/commanddash-integration/dart-cli-client.ts @@ -2,7 +2,7 @@ import * as child_process from 'child_process'; import { EventEmitter } from 'events'; import { Task } from './task'; import { join } from 'path'; -import { chmod, existsSync, unlink } from 'fs'; +import { chmod, chmodSync, existsSync, renameSync, unlink } from 'fs'; import { downloadFile, makeHttpRequest } from '../../repository/http-utils'; import { AxiosRequestConfig } from 'axios'; import * as vscode from 'vscode'; @@ -26,16 +26,6 @@ async function setupExecutable(clientVersion: string, executablePath: string, ex return; } await downloadFile(response['url'], executablePath, onProgress); - if (platform === 'darwin' || platform === 'linux') { - // Downloaded file is required to be coverted to an executable. - return new Promise((resolve, reject) => { - chmod(executablePath, '755', (err) => { - if (err) { reject(err); } - console.log('The permissions for the executable have been set'); - resolve(); - }); - }); - } } export async function deleteExecutable(executablePath: string): Promise { @@ -115,8 +105,24 @@ export class DartCLIClient { await deleteExecutable(this.executablePath); } + private renameTempToExecutable(tempFilePath: string) { + renameSync(tempFilePath, this.executablePath); + const platform = os.platform(); + if (platform === 'darwin' || platform === 'linux') { + // Downloaded file is required to be coverted to an executable. + chmodSync(this.executablePath, '755'); + } + } public connect() { + // Verify the presence of the temporary file, indicating a downloaded update during the last IDE session. + // Proceed with updating the executable if applicable. + const tempFilePath = `${this.executablePath}.pre-downloaded`; + if (existsSync(tempFilePath)) { + this.renameTempToExecutable(tempFilePath); + } + + this.proc = child_process.spawn(this.executablePath, ['process']); let buffer = '';