Skip to content

Commit d3b5133

Browse files
committed
refactor: add types for customizations
1 parent 1845ac8 commit d3b5133

File tree

4 files changed

+67
-35
lines changed

4 files changed

+67
-35
lines changed

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

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import * as vscode from 'vscode'
77
import * as path from 'path'
88
import {
99
CollectFilesFilter,
10-
CollectFilesResultItem,
1110
defaultExcludePatterns,
1211
getWorkspaceFoldersByPrefixes,
1312
} from '../../shared/utilities/workspaceUtils'
@@ -28,7 +27,7 @@ import { ZipStream } from '../../shared/utilities/zipStream'
2827
import { isPresent } from '../../shared/utilities/collectionUtils'
2928
import { AuthUtil } from '../../codewhisperer/util/authUtil'
3029
import { TelemetryHelper } from '../util/telemetryHelper'
31-
import { zipProject } from './zipProjectUtil'
30+
import { ZipExcluder, zipProject } from './zipProjectUtil'
3231

3332
export const SvgFileExtension = '.svg'
3433

@@ -109,7 +108,7 @@ export async function prepareRepoData(
109108
const { excludePatterns, filterFn } = getFilterAndExcludePattern(useAutoBuildFeature, includeInfraDiagram)
110109

111110
const ignoredExtensionMap = new Map<string, number>()
112-
const isExcluded = (file: CollectFilesResultItem) => {
111+
const isExcluded: ZipExcluder = (file) => {
113112
const isCodeFile_ = isCodeFile(file.relativeFilePath)
114113
const isDevFile = file.relativeFilePath === 'devfile.yaml'
115114
const isInfraDiagramFileExt = isInfraDiagramFile(file.relativeFilePath)

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

Lines changed: 45 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,14 @@
22
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
33
* SPDX-License-Identifier: Apache-2.0
44
*/
5+
import vscode from 'vscode'
56
import path from 'path'
6-
import { collectFiles, CollectFilesOptions, CollectFilesResultItem } from '../../shared/utilities/workspaceUtils'
7+
import {
8+
collectFiles,
9+
CollectFilesOptions,
10+
CollectFilesResultItem,
11+
getFileInfo,
12+
} from '../../shared/utilities/workspaceUtils'
713
import { CurrentWsFolders } from '../commons/types'
814
import { ZipStream } from '../../shared/utilities/zipStream'
915

@@ -28,14 +34,19 @@ interface ZipProjectOptions {
2834
nonPosixPath?: boolean
2935
}
3036

37+
export type ZipExcluder = (file: Omit<CollectFilesResultItem, 'workspaceFolder'>) => boolean
38+
export type ZipErrorCheck = (file: Omit<CollectFilesResultItem, 'workspaceFolder'>) => Error | undefined
39+
export type ZipTracker = (file: Omit<CollectFilesResultItem, 'workspaceFolder'>) => Promise<void> | void
40+
3141
interface ZipProjectCustomizations {
32-
isExcluded?: (file: CollectFilesResultItem) => boolean
33-
checkForError?: (file: CollectFilesResultItem) => Error | undefined
34-
computeSideEffects?: (file: CollectFilesResultItem) => Promise<void> | void
42+
isExcluded?: ZipExcluder
43+
checkForError?: ZipErrorCheck
44+
computeSideEffects?: ZipTracker
3545
}
3646

3747
export async function addFileToZip(
38-
file: CollectFilesResultItem,
48+
file: Omit<CollectFilesResultItem, 'workspaceFolder'>,
49+
targetFilePath: string,
3950
zip: ZipStream,
4051
customizations?: ZipProjectCustomizations,
4152
options?: ZipProjectOptions
@@ -48,19 +59,12 @@ export async function addFileToZip(
4859
throw errorToThrow
4960
}
5061

51-
// Paths in zip should be POSIX compliant regardless of OS
52-
// Reference: https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT
53-
const zipFilePath = options?.includeProjectName
54-
? path.join(path.basename(file.workspaceFolder.uri.fsPath), file.zipFilePath)
55-
: file.zipFilePath
56-
const posixPath = options?.nonPosixPath ? zipFilePath : zipFilePath.split(path.sep).join(path.posix.sep)
57-
5862
try {
5963
// filepath will be out-of-sync for files with unsaved changes.
6064
if (file.isText) {
61-
zip.writeString(file.fileContent, posixPath)
65+
zip.writeString(file.fileContent, targetFilePath)
6266
} else {
63-
zip.writeFile(file.fileUri.fsPath, path.dirname(posixPath))
67+
zip.writeFile(file.fileUri.fsPath, path.dirname(targetFilePath))
6468
}
6569
} catch (error) {
6670
if (error instanceof Error && error.message.includes('File not found')) {
@@ -95,7 +99,14 @@ export async function addProjectToZip(
9599
}
96100
zippedFiles.add(file.zipFilePath)
97101

98-
const addFileResult = await addFileToZip(file, zip, customizations, options)
102+
// Paths in zip should be POSIX compliant regardless of OS
103+
// Reference: https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT
104+
const zipFilePath = options?.includeProjectName
105+
? path.join(path.basename(file.workspaceFolder.uri.fsPath), file.zipFilePath)
106+
: file.zipFilePath
107+
const targetPath = options?.nonPosixPath ? zipFilePath : zipFilePath.split(path.sep).join(path.posix.sep)
108+
109+
const addFileResult = await addFileToZip(file, targetPath, zip, customizations, options)
99110
if (addFileResult.result === 'added') {
100111
totalBytes += addFileResult.addedBytes
101112
}
@@ -127,3 +138,22 @@ export async function zipProject(
127138
totalFileBytes: totalBytesAdded,
128139
}
129140
}
141+
// TODO: remove vscode dep
142+
export async function zipFile(
143+
file: vscode.Uri,
144+
targetPath: string,
145+
customizations?: ZipProjectCustomizations,
146+
options?: ZipProjectOptions
147+
) {
148+
return await addFileToZip(
149+
{
150+
...(await getFileInfo(file, true)),
151+
zipFilePath: targetPath,
152+
relativeFilePath: file.fsPath,
153+
},
154+
targetPath,
155+
new ZipStream(),
156+
customizations,
157+
options
158+
)
159+
}

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

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,7 @@ import { fs } from '../../shared/fs/fs'
1212
import { getLoggerForScope } from '../service/securityScanHandler'
1313
import { runtimeLanguageContext } from './runtimeLanguageContext'
1414
import { CodewhispererLanguage } from '../../shared/telemetry/telemetry.gen'
15-
import {
16-
CollectFilesOptions,
17-
CollectFilesResultItem,
18-
CurrentWsFolders,
19-
defaultExcludePatterns,
20-
} from '../../shared/utilities/workspaceUtils'
15+
import { CollectFilesOptions, CurrentWsFolders, defaultExcludePatterns } from '../../shared/utilities/workspaceUtils'
2116
import {
2217
FileSizeExceededError,
2318
NoActiveFileError,
@@ -30,7 +25,7 @@ import { ProjectZipError } from '../../amazonqTest/error'
3025
import { removeAnsi } from '../../shared/utilities/textUtilities'
3126
import { normalize } from '../../shared/utilities/pathUtils'
3227
import { ZipStream } from '../../shared/utilities/zipStream'
33-
import { addProjectToZip } from '../../amazonq/util/zipProjectUtil'
28+
import { addProjectToZip, ZipErrorCheck, ZipExcluder, ZipTracker } from '../../amazonq/util/zipProjectUtil'
3429

3530
export interface ZipMetadata {
3631
rootDir: string
@@ -430,17 +425,17 @@ export class ZipUtil {
430425
: defaultExcludePatterns,
431426
includeContent: true,
432427
}
433-
const isExcluded = (file: CollectFilesResultItem) =>
428+
const isExcluded: ZipExcluder = (file) =>
434429
ZipConstants.knownBinaryFileExts.includes(path.extname(file.fileUri.fsPath)) &&
435430
useCase === FeatureUseCase.TEST_GENERATION
436431

437-
const checkForError = (file: CollectFilesResultItem) =>
432+
const checkForError: ZipErrorCheck = (file) =>
438433
this.reachSizeLimit(this._totalSize, CodeWhispererConstants.CodeAnalysisScope.PROJECT) ||
439434
this.willReachSizeLimit(this._totalSize, file.fileSizeBytes)
440435
? new ProjectSizeExceededError()
441436
: undefined
442437

443-
const computeSideEffects = (file: CollectFilesResultItem) => {
438+
const computeSideEffects: ZipTracker = (file) => {
444439
if (file.isText) {
445440
this._totalLines += file.fileContent.split(ZipConstants.newlineRegex).length
446441
this.incrementCountForLanguage(file.fileUri, languageCount)

packages/core/src/shared/utilities/workspaceUtils.ts

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -330,17 +330,17 @@ async function filterOutGitignoredFiles(
330330
return gitIgnoreFilter.filterFiles(files)
331331
}
332332

333-
export type FileInformation = {
333+
type FileInformation = {
334334
fileUri: vscode.Uri
335335
fileSizeBytes: number
336336
isText: boolean
337337
}
338338

339339
export interface CollectFilesResultItem extends FileInformation {
340340
workspaceFolder: vscode.WorkspaceFolder
341+
zipFilePath: string
341342
relativeFilePath: string
342343
fileContent: string
343-
zipFilePath: string
344344
}
345345
export type CollectFilesFilter = (relativePath: string) => boolean // returns true if file should be filtered out
346346
export interface CollectFilesOptions {
@@ -426,7 +426,7 @@ export async function collectFiles(
426426
continue
427427
}
428428

429-
const fileStats = await getFileStats(file, includeContent, fileStat.size)
429+
const fileStats = await getFileInfo(file, includeContent, fileStat.size)
430430
if (fileStats) {
431431
storage.push({
432432
...fileStats,
@@ -480,7 +480,18 @@ const workspaceFolderPrefixGuards = {
480480
maximumFoldersWithMatchingSubfolders: 10_000,
481481
}
482482

483-
export async function getFileStats(file: vscode.Uri, includeContent: boolean, fileSize?: number) {
483+
export async function getFileInfo(
484+
file: vscode.Uri,
485+
includeContent: true,
486+
fileSize?: number
487+
): Promise<FileInformation & { fileContent: string }>
488+
export async function getFileInfo(file: vscode.Uri, includeContent: false, fileSize?: number): Promise<FileInformation>
489+
export async function getFileInfo(
490+
file: vscode.Uri,
491+
includeContent: boolean,
492+
fileSize?: number
493+
): Promise<FileInformation | (FileInformation & { fileContent: string })>
494+
export async function getFileInfo(file: vscode.Uri, includeContent: boolean, fileSize?: number) {
484495
const fileWithoutContent = {
485496
fileUri: file,
486497
fileSizeBytes: fileSize ?? (await fs.stat(file)).size,
@@ -490,9 +501,6 @@ export async function getFileStats(file: vscode.Uri, includeContent: boolean, fi
490501
const hasUnsavedChanges = isFileOpenAndDirty(file)
491502
const fileContent =
492503
fileWithoutContent.isText && hasUnsavedChanges ? await getCurrentTextContent(file) : await readFile(file)
493-
if (fileContent === undefined) {
494-
return
495-
}
496504
return {
497505
...fileWithoutContent,
498506
fileContent,

0 commit comments

Comments
 (0)