Skip to content

Commit e89a04d

Browse files
authored
Merge pull request #3151 from github/koesie10/variant-analysis-yauzl
Switch to `yauzl` for variant analysis results
2 parents b833591 + 3f6c105 commit e89a04d

File tree

4 files changed

+67
-15
lines changed

4 files changed

+67
-15
lines changed

extensions/ql-vscode/src/common/unzip.ts

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
import { Entry as ZipEntry, open, Options as ZipOptions, ZipFile } from "yauzl";
22
import { Readable } from "stream";
3+
import { dirname, join } from "path";
4+
import { WriteStream } from "fs";
5+
import { createWriteStream, ensureDir } from "fs-extra";
36

47
// We can't use promisify because it picks up the wrong overload.
58
export function openZip(
@@ -82,3 +85,63 @@ export async function openZipBuffer(
8285
});
8386
});
8487
}
88+
89+
async function copyStream(
90+
readable: Readable,
91+
writeStream: WriteStream,
92+
): Promise<void> {
93+
return new Promise((resolve, reject) => {
94+
readable.on("error", (err) => {
95+
reject(err);
96+
});
97+
readable.on("end", () => {
98+
resolve();
99+
});
100+
101+
readable.pipe(writeStream);
102+
});
103+
}
104+
105+
export async function unzipToDirectory(
106+
archivePath: string,
107+
destinationPath: string,
108+
): Promise<void> {
109+
const zipFile = await openZip(archivePath, {
110+
autoClose: false,
111+
strictFileNames: true,
112+
lazyEntries: true,
113+
});
114+
115+
try {
116+
const entries = await readZipEntries(zipFile);
117+
118+
for (const entry of entries) {
119+
const path = join(destinationPath, entry.fileName);
120+
121+
if (/\/$/.test(entry.fileName)) {
122+
// Directory file names end with '/'
123+
124+
await ensureDir(path);
125+
} else {
126+
// Ensure the directory exists
127+
await ensureDir(dirname(path));
128+
129+
const readable = await openZipReadStream(zipFile, entry);
130+
131+
let mode: number | undefined = entry.externalFileAttributes >>> 16;
132+
if (mode <= 0) {
133+
mode = undefined;
134+
}
135+
136+
const writeStream = createWriteStream(path, {
137+
autoClose: true,
138+
mode,
139+
});
140+
141+
await copyStream(readable, writeStream);
142+
}
143+
}
144+
} finally {
145+
zipFile.close();
146+
}
147+
}

extensions/ql-vscode/src/common/zip.ts

Lines changed: 0 additions & 11 deletions
This file was deleted.

extensions/ql-vscode/src/variant-analysis/variant-analysis-results-manager.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import {
1616
} from "./shared/variant-analysis";
1717
import { DisposableObject, DisposeHandler } from "../common/disposable-object";
1818
import { EventEmitter } from "vscode";
19-
import { unzipFile } from "../common/zip";
19+
import { unzipToDirectory } from "../common/unzip";
2020
import { readRepoTask, writeRepoTask } from "./repo-tasks-store";
2121

2222
type CacheKey = `${number}/${string}`;
@@ -106,7 +106,7 @@ export class VariantAnalysisResultsManager extends DisposableObject {
106106
VariantAnalysisResultsManager.RESULTS_DIRECTORY,
107107
);
108108

109-
await unzipFile(zipFilePath, unzippedFilesDirectory);
109+
await unzipToDirectory(zipFilePath, unzippedFilesDirectory);
110110

111111
this._onResultDownloaded.fire({
112112
variantAnalysisId,

extensions/ql-vscode/test/vscode-tests/activated-extension/variant-analysis/variant-analysis-results-manager.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,8 @@ describe(VariantAnalysisResultsManager.name, () => {
5454
});
5555

5656
afterEach(async () => {
57-
if (fs.existsSync(variantAnalysisStoragePath)) {
58-
fs.rmSync(variantAnalysisStoragePath, { recursive: true });
57+
if (await fs.pathExists(variantAnalysisStoragePath)) {
58+
await fs.remove(variantAnalysisStoragePath);
5959
}
6060
});
6161

0 commit comments

Comments
 (0)