Skip to content

Commit 87b9842

Browse files
committed
fix: avoid faulty rename when installing
Fixes #233, which Andrea ran into when testing. Instead of staging and renaming, which tends to fail on Windows, write a 'completed' file when the install is done.
1 parent 310c6b2 commit 87b9842

File tree

2 files changed

+10
-21
lines changed

2 files changed

+10
-21
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# Changelog
22

3+
### 2.3.6 | 2022-10-24
4+
5+
- Fix windows sometimes failing on EPERM in download (again)
6+
37
### 2.3.5 | 2022-10-04
48

59
- Fix windows sometimes failing on EPERM in download

lib/download.ts

Lines changed: 6 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ import {
2727
streamToBuffer,
2828
systemDefaultPlatform,
2929
} from './util';
30-
import * as timers from 'timers/promises';
3130

3231
const extensionRoot = process.cwd();
3332
const pipelineAsync = promisify(pipeline);
@@ -332,6 +331,8 @@ function spawnDecompressorChild(command: string, args: ReadonlyArray<string>, in
332331

333332
export const defaultCachePath = path.resolve(extensionRoot, '.vscode-test');
334333

334+
const COMPLETE_FILE_NAME = 'is-complete';
335+
335336
/**
336337
* Download and unzip a copy of VS Code.
337338
* @returns Promise of `vscodeExecutablePath`.
@@ -368,7 +369,7 @@ export async function download(options: Partial<DownloadOptions> = {}): Promise<
368369
reporter.report({ stage: ProgressReportStage.ResolvedVersion, version });
369370

370371
const downloadedPath = path.resolve(cachePath, makeDownloadDirName(platform, version));
371-
if (fs.existsSync(downloadedPath)) {
372+
if (fs.existsSync(path.join(downloadedPath, COMPLETE_FILE_NAME))) {
372373
if (isInsiderVersionIdentifier(version)) {
373374
reporter.report({ stage: ProgressReportStage.FetchingInsidersMetadata });
374375
const { version: currentHash, date: currentDate } = insidersDownloadDirMetadata(downloadedPath, platform);
@@ -408,10 +409,7 @@ export async function download(options: Partial<DownloadOptions> = {}): Promise<
408409

409410
for (let i = 0; ; i++) {
410411
try {
411-
// Use a staging directory and rename after unzipping so partially-
412-
// downloaded/unzipped files aren't "stuck" being used.
413-
const downloadStaging = `${downloadedPath}.tmp`;
414-
await fs.promises.rm(downloadStaging, { recursive: true, force: true });
412+
await fs.promises.rm(downloadedPath, { recursive: true, force: true });
415413

416414
const { stream, format } = await downloadVSCodeArchive({
417415
version,
@@ -422,22 +420,9 @@ export async function download(options: Partial<DownloadOptions> = {}): Promise<
422420
});
423421
// important! do not put anything async here, since unzipVSCode will need
424422
// to start consuming the stream immediately.
425-
await unzipVSCode(reporter, downloadStaging, stream, platform, format);
426-
427-
// Windows file handles can get released asynchronously, give it a few retries:
428-
for (let attempts = 20; attempts >= 0; attempts--) {
429-
try {
430-
await fs.promises.rename(downloadStaging, downloadedPath);
431-
break;
432-
} catch (e) {
433-
if (attempts === 0) {
434-
throw e;
435-
} else {
436-
await timers.setTimeout(200);
437-
}
438-
}
439-
}
423+
await unzipVSCode(reporter, downloadedPath, stream, platform, format);
440424

425+
await fs.promises.writeFile(path.join(downloadedPath, COMPLETE_FILE_NAME), '');
441426
reporter.report({ stage: ProgressReportStage.NewInstallComplete, downloadedPath });
442427
break;
443428
} catch (error) {

0 commit comments

Comments
 (0)