Skip to content

Commit 60638ca

Browse files
committed
merge: add changes from zipUtil
1 parent eb29e81 commit 60638ca

File tree

6 files changed

+134
-307
lines changed

6 files changed

+134
-307
lines changed

packages/core/src/amazonq/util/files.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ export async function prepareRepoData(
144144
excludePatterns: excludePatterns,
145145
filterFn: filterFn,
146146
},
147-
isExcluded,
147+
{ isExcluded },
148148
{ zip: options?.zip ?? new ZipStream() }
149149
)
150150

packages/core/src/amazonq/util/zipProjectUtil.ts

Lines changed: 16 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,11 @@
44
*/
55

66
import path from 'path'
7-
import { fs } from '../../shared/fs/fs'
87
import { collectFiles, CollectFilesOptions } from '../../shared/utilities/workspaceUtils'
98
import { CurrentWsFolders } from '../commons/types'
109
import { ZipStream } from '../../shared/utilities/zipStream'
11-
import { hasCode } from '../../shared/errors'
1210

13-
export interface ZippedResult {
11+
export interface ZippedWorkspaceResult {
1412
zipFileBuffer: Buffer
1513
zipFileChecksum: string
1614
totalFileBytes: number
@@ -20,13 +18,19 @@ interface ZipProjectOptions {
2018
zip?: ZipStream
2119
}
2220

21+
interface ZipProjectCustomizations {
22+
isExcluded?: (relativePath: string, fileSize: number) => boolean
23+
checkForError?: (relativePath: string, fileSize: number) => void | never
24+
computeSideEffects?: (filePath: string) => Promise<void> | void
25+
}
26+
2327
export async function zipProject(
2428
repoRootPaths: string[],
2529
workspaceFolders: CurrentWsFolders,
2630
collectFilesOptions: CollectFilesOptions,
27-
isExcluded: (relativePath: string, fileSize: number) => boolean,
31+
customizations?: ZipProjectCustomizations,
2832
options?: ZipProjectOptions
29-
): Promise<ZippedResult> {
33+
): Promise<ZippedWorkspaceResult> {
3034
const zip = options?.zip ?? new ZipStream()
3135
const files = await collectFiles(repoRootPaths, workspaceFolders, collectFilesOptions)
3236
const zippedFiles = new Set()
@@ -37,25 +41,18 @@ export async function zipProject(
3741
}
3842
zippedFiles.add(file.zipFilePath)
3943

40-
const fileSize = await fs
41-
.stat(file.fileUri.fsPath)
42-
.then((r) => r.size)
43-
.catch((e) => {
44-
if (hasCode(e) && e.code === 'ENOENT') {
45-
// No-op: Skip if file does not exist
46-
return
47-
}
48-
throw e
49-
})
50-
if (!fileSize) {
44+
if (customizations?.isExcluded && customizations.isExcluded(file.relativeFilePath, file.fileSizeBytes)) {
5145
continue
5246
}
47+
if (customizations?.checkForError) {
48+
customizations.checkForError(file.relativeFilePath, file.fileSizeBytes)
49+
}
5350

54-
if (isExcluded(file.relativeFilePath, fileSize)) {
55-
continue
51+
if (customizations?.computeSideEffects) {
52+
await customizations.computeSideEffects(file.fileUri.fsPath)
5653
}
5754

58-
totalBytes += fileSize
55+
totalBytes += file.fileSizeBytes
5956
// Paths in zip should be POSIX compliant regardless of OS
6057
// Reference: https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT
6158
const posixPath = file.zipFilePath.split(path.sep).join(path.posix.sep)

packages/core/src/codewhisperer/util/zipUtil.ts

Lines changed: 37 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
33
* SPDX-License-Identifier: Apache-2.0
44
*/
5-
import admZip from 'adm-zip'
65
import * as vscode from 'vscode'
76
import path from 'path'
87
import { tempDirPath, testGenerationLogsDir } from '../../shared/filesystemUtilities'
@@ -25,6 +24,7 @@ import { ChildProcess, ChildProcessOptions } from '../../shared/utilities/proces
2524
import { ProjectZipError } from '../../amazonqTest/error'
2625
import { removeAnsi } from '../../shared/utilities/textUtilities'
2726
import { normalize } from '../../shared/utilities/pathUtils'
27+
import { ZipStream } from '../../shared/utilities/zipStream'
2828

2929
export interface ZipMetadata {
3030
rootDir: string
@@ -109,7 +109,7 @@ export class ZipUtil {
109109
if (!uri) {
110110
throw new NoActiveFileError()
111111
}
112-
const zip = new admZip()
112+
const zip = new ZipStream()
113113

114114
const content = await this.getTextContent(uri)
115115

@@ -121,14 +121,14 @@ export class ZipUtil {
121121
// Set includeWorkspaceFolder to false because we are already manually prepending the projectName
122122
const relativePath = vscode.workspace.asRelativePath(uri, false)
123123
const zipEntryPath = this.getZipEntryPath(projectName, relativePath)
124-
zip.addFile(zipEntryPath, Buffer.from(content, 'utf-8'))
124+
zip.writeString(content, zipEntryPath)
125125

126126
if (scope === CodeWhispererConstants.CodeAnalysisScope.FILE_ON_DEMAND) {
127127
const gitDiffContent = `+++ b/${normalize(zipEntryPath)}` // Sending file path in payload for LLM code review
128-
zip.addFile(ZipConstants.codeDiffFilePath, Buffer.from(gitDiffContent, 'utf-8'))
128+
zip.writeString(gitDiffContent, ZipConstants.codeDiffFilePath)
129129
}
130130
} else {
131-
zip.addFile(uri.fsPath, Buffer.from(content, 'utf-8'))
131+
zip.writeString(content, uri.fsPath)
132132
}
133133

134134
this._pickedSourceFiles.add(uri.fsPath)
@@ -139,7 +139,7 @@ export class ZipUtil {
139139
throw new FileSizeExceededError()
140140
}
141141
const zipFilePath = this.getZipDirPath(FeatureUseCase.CODE_SCAN) + CodeWhispererConstants.codeScanZipExt
142-
zip.writeZip(zipFilePath)
142+
await zip.finalizeToFile(zipFilePath)
143143
return zipFilePath
144144
}
145145

@@ -170,13 +170,13 @@ export class ZipUtil {
170170
* await processMetadataDir(zip, '/path/to/directory');
171171
* ```
172172
*/
173-
protected async processMetadataDir(zip: admZip, metadataDir: string) {
173+
protected async processMetadataDir(zip: ZipStream, metadataDir: string) {
174174
const metadataDirName = path.basename(metadataDir)
175175
// Helper function to add empty directory to zip
176176
const addEmptyDirectory = (dirPath: string) => {
177177
const relativePath = path.relative(metadataDir, dirPath)
178178
const pathWithMetadata = path.join(metadataDirName, relativePath, '/')
179-
zip.addFile(pathWithMetadata, Buffer.from(''))
179+
zip.writeString('', pathWithMetadata)
180180
}
181181

182182
// Recursive function to process directories
@@ -189,11 +189,10 @@ export class ZipUtil {
189189

190190
if (fileType === vscode.FileType.File) {
191191
try {
192-
const fileContent = await vscode.workspace.fs.readFile(vscode.Uri.file(filePath))
193-
const buffer = Buffer.from(fileContent)
192+
const fileUri = vscode.Uri.file(filePath)
194193
const relativePath = path.relative(metadataDir, filePath)
195194
const pathWithMetadata = path.join(metadataDirName, relativePath)
196-
zip.addFile(pathWithMetadata, buffer)
195+
zip.writeFile(fileUri.fsPath, pathWithMetadata)
197196
} catch (error) {
198197
getLogger().error(`Failed to add file ${filePath} to zip: ${error}`)
199198
}
@@ -207,7 +206,7 @@ export class ZipUtil {
207206
}
208207

209208
protected async zipProject(useCase: FeatureUseCase, projectPath?: string, metadataDir?: string) {
210-
const zip = new admZip()
209+
const zip = new ZipStream()
211210
let projectPaths = []
212211
if (useCase === FeatureUseCase.TEST_GENERATION && projectPath) {
213212
projectPaths.push(projectPath)
@@ -232,12 +231,12 @@ export class ZipUtil {
232231
}
233232
this._language = [...languageCount.entries()].reduce((a, b) => (b[1] > a[1] ? b : a))[0]
234233
const zipFilePath = this.getZipDirPath(useCase) + CodeWhispererConstants.codeScanZipExt
235-
zip.writeZip(zipFilePath)
234+
await zip.finalizeToFile(zipFilePath)
236235
return zipFilePath
237236
}
238237

239238
protected async processCombinedGitDiff(
240-
zip: admZip,
239+
zip: ZipStream,
241240
projectPaths: string[],
242241
filePath?: string,
243242
scope?: CodeWhispererConstants.CodeAnalysisScope
@@ -254,7 +253,7 @@ export class ZipUtil {
254253
})
255254
}
256255
if (gitDiffContent) {
257-
zip.addFile(ZipConstants.codeDiffFilePath, Buffer.from(gitDiffContent, 'utf-8'))
256+
zip.writeString(gitDiffContent, ZipConstants.codeDiffFilePath)
258257
}
259258
}
260259

@@ -403,7 +402,7 @@ export class ZipUtil {
403402
}
404403

405404
protected async processSourceFiles(
406-
zip: admZip,
405+
zip: ZipStream,
407406
languageCount: Map<CodewhispererLanguage, number>,
408407
projectPaths: string[] | undefined,
409408
useCase: FeatureUseCase
@@ -412,26 +411,30 @@ export class ZipUtil {
412411
return
413412
}
414413

415-
const sourceFiles = await collectFiles(
416-
projectPaths,
417-
(useCase === FeatureUseCase.TEST_GENERATION
414+
const workspaceFolders = (
415+
useCase === FeatureUseCase.TEST_GENERATION
418416
? [...(vscode.workspace.workspaceFolders ?? [])].sort(
419417
(a, b) => b.uri.fsPath.length - a.uri.fsPath.length
420418
)
421-
: vscode.workspace.workspaceFolders) as CurrentWsFolders,
422-
{
423-
maxTotalSizeBytes: this.getProjectScanPayloadSizeLimitInBytes(),
424-
excludePatterns:
425-
useCase === FeatureUseCase.TEST_GENERATION
426-
? [...CodeWhispererConstants.testGenExcludePatterns, ...defaultExcludePatterns]
427-
: defaultExcludePatterns,
428-
}
429-
)
419+
: vscode.workspace.workspaceFolders
420+
) as CurrentWsFolders
421+
422+
const collectFilesOptions = {
423+
maxTotalSizeBytes: this.getProjectScanPayloadSizeLimitInBytes(),
424+
excludePatterns:
425+
useCase === FeatureUseCase.TEST_GENERATION
426+
? [...CodeWhispererConstants.testGenExcludePatterns, ...defaultExcludePatterns]
427+
: defaultExcludePatterns,
428+
}
429+
430+
const sourceFiles = await collectFiles(projectPaths, workspaceFolders, collectFilesOptions)
431+
430432
for (const file of sourceFiles) {
431433
const projectName = path.basename(file.workspaceFolder.uri.fsPath)
432434
const zipEntryPath = this.getZipEntryPath(projectName, file.relativeFilePath)
435+
const fileExtension = path.extname(file.fileUri.fsPath)
433436

434-
if (ZipConstants.knownBinaryFileExts.includes(path.extname(file.fileUri.fsPath))) {
437+
if (ZipConstants.knownBinaryFileExts.includes(fileExtension)) {
435438
if (useCase === FeatureUseCase.TEST_GENERATION) {
436439
continue
437440
}
@@ -444,7 +447,7 @@ export class ZipUtil {
444447
}
445448
}
446449

447-
protected processOtherFiles(zip: admZip, languageCount: Map<CodewhispererLanguage, number>) {
450+
protected processOtherFiles(zip: ZipStream, languageCount: Map<CodewhispererLanguage, number>) {
448451
for (const document of vscode.workspace.textDocuments
449452
.filter((document) => document.uri.scheme === 'file')
450453
.filter((document) => vscode.workspace.getWorkspaceFolder(document.uri) === undefined)) {
@@ -474,7 +477,7 @@ export class ZipUtil {
474477
}
475478

476479
protected processTextFile(
477-
zip: admZip,
480+
zip: ZipStream,
478481
uri: vscode.Uri,
479482
fileContent: string,
480483
languageCount: Map<CodewhispererLanguage, number>,
@@ -493,10 +496,10 @@ export class ZipUtil {
493496
this._totalLines += fileContent.split(ZipConstants.newlineRegex).length
494497

495498
this.incrementCountForLanguage(uri, languageCount)
496-
zip.addFile(zipEntryPath, Buffer.from(fileContent, 'utf-8'))
499+
zip.writeString(fileContent, zipEntryPath)
497500
}
498501

499-
protected async processBinaryFile(zip: admZip, uri: vscode.Uri, zipEntryPath: string) {
502+
protected async processBinaryFile(zip: ZipStream, uri: vscode.Uri, zipEntryPath: string) {
500503
const fileSize = (await fs.stat(uri.fsPath)).size
501504

502505
if (
@@ -508,7 +511,7 @@ export class ZipUtil {
508511
this._pickedSourceFiles.add(uri.fsPath)
509512
this._totalSize += fileSize
510513

511-
zip.addLocalFile(uri.fsPath, path.dirname(zipEntryPath))
514+
zip.writeFile(uri.fsPath, path.dirname(zipEntryPath))
512515
}
513516

514517
protected incrementCountForLanguage(uri: vscode.Uri, languageCount: Map<CodewhispererLanguage, number>) {

0 commit comments

Comments
 (0)