66import * as vscode from 'vscode'
77import * as path from 'path'
88import {
9- collectFiles ,
109 CollectFilesFilter ,
1110 defaultExcludePatterns ,
1211 getWorkspaceFoldersByPrefixes ,
@@ -28,6 +27,7 @@ import { ZipStream } from '../../shared/utilities/zipStream'
2827import { isPresent } from '../../shared/utilities/collectionUtils'
2928import { AuthUtil } from '../../codewhisperer/util/authUtil'
3029import { TelemetryHelper } from '../util/telemetryHelper'
30+ import { zipProject } from './zipProjectUtil'
3131
3232export const SvgFileExtension = '.svg'
3333
@@ -102,86 +102,60 @@ export async function prepareRepoData(
102102 const fileSizeByteLimit = options ?. fileSizeByteLimit
103103 ? Math . min ( options . fileSizeByteLimit , maxFileSizeBytes )
104104 : maxFileSizeBytes
105- const zip = options ?. zip ?? new ZipStream ( )
106105
107106 const autoBuildSetting = CodeWhispererSettings . instance . getAutoBuildSetting ( )
108107 const useAutoBuildFeature = autoBuildSetting [ repoRootPaths [ 0 ] ] ?? false
109108 const { excludePatterns, filterFn } = getFilterAndExcludePattern ( useAutoBuildFeature , includeInfraDiagram )
110109
111- const files = await collectFiles ( repoRootPaths , workspaceFolders , {
112- maxTotalSizeBytes : maxRepoSizeBytes ,
113- excludeByGitIgnore : true ,
114- excludePatterns : excludePatterns ,
115- filterFn : filterFn ,
116- } )
117-
118- let totalBytes = 0
119110 const ignoredExtensionMap = new Map < string , number > ( )
120- const addedFilePaths = new Set ( )
121-
122- for ( const file of files ) {
123- if ( addedFilePaths . has ( file . zipFilePath ) || ! ( await fs . exists ( file . fileUri . fsPath ) ) ) {
124- continue
125- }
126- addedFilePaths . add ( file . zipFilePath )
127-
128- const fileSize = ( await fs . stat ( file . fileUri . fsPath ) ) . size
129-
130- const isCodeFile_ = isCodeFile ( file . relativeFilePath )
131- const isDevFile = file . relativeFilePath === 'devfile.yaml'
132- const isInfraDiagramFileExt = isInfraDiagramFile ( file . relativeFilePath )
111+ const isExcluded = ( relativeFilePath : string , fileSize : number ) => {
112+ const isCodeFile_ = isCodeFile ( relativeFilePath )
113+ const isDevFile = relativeFilePath === 'devfile.yaml'
114+ const isInfraDiagramFileExt = isInfraDiagramFile ( relativeFilePath )
133115
134116 let isExcludeFile = fileSize >= fileSizeByteLimit
135117 // When useAutoBuildFeature is on, only respect the gitignore rules filtered earlier and apply the size limit
136118 if ( ! isExcludeFile && ! useAutoBuildFeature ) {
137119 isExcludeFile = isDevFile || ( ! isCodeFile_ && ( ! includeInfraDiagram || ! isInfraDiagramFileExt ) )
138120 }
139-
121+ // Side-effect of isExcluded
140122 if ( isExcludeFile ) {
141123 if ( ! isCodeFile_ ) {
142124 const re = / (?: \. ( [ ^ . ] + ) ) ? $ /
143- const extensionArray = re . exec ( file . relativeFilePath )
125+ const extensionArray = re . exec ( relativeFilePath )
144126 const extension = extensionArray ?. length ? extensionArray [ 1 ] : undefined
145127 if ( extension ) {
146128 const currentCount = ignoredExtensionMap . get ( extension )
147129
148130 ignoredExtensionMap . set ( extension , ( currentCount ?? 0 ) + 1 )
149131 }
150132 }
151- continue
152133 }
153134
154- totalBytes += fileSize
155- // Paths in zip should be POSIX compliant regardless of OS
156- // Reference: https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT
157- const posixPath = file . zipFilePath . split ( path . sep ) . join ( path . posix . sep )
158-
159- try {
160- zip . writeFile ( file . fileUri . fsPath , posixPath )
161- } catch ( error ) {
162- if ( error instanceof Error && error . message . includes ( 'File not found' ) ) {
163- // No-op: Skip if file was deleted or does not exist
164- // Reference: https://github.com/cthackers/adm-zip/blob/1cd32f7e0ad3c540142a76609bb538a5cda2292f/adm-zip.js#L296-L321
165- continue
166- }
167- throw error
168- }
135+ return isExcludeFile
169136 }
170137
138+ const zipResult = await zipProject (
139+ repoRootPaths ,
140+ workspaceFolders ,
141+ {
142+ maxTotalSizeBytes : maxRepoSizeBytes ,
143+ excludeByGitIgnore : true ,
144+ excludePatterns : excludePatterns ,
145+ filterFn : filterFn ,
146+ } ,
147+ isExcluded ,
148+ { zip : options ?. zip ?? new ZipStream ( ) }
149+ )
150+
171151 await emitIgnoredExtensionTelemetry ( ignoredExtensionMap )
172152
173153 if ( telemetry ) {
174- telemetry . setRepositorySize ( totalBytes )
154+ telemetry . setRepositorySize ( zipResult . totalFileBytes )
175155 }
176156
177- span . record ( { amazonqRepositorySize : totalBytes } )
178- const zipResult = await zip . finalize ( )
179-
180- const zipFileBuffer = zipResult . streamBuffer . getContents ( ) || Buffer . from ( '' )
181- return {
182- zipFileBuffer,
183- zipFileChecksum : zipResult . hash ,
184- }
157+ span . record ( { amazonqRepositorySize : zipResult . totalFileBytes } )
158+ return zipResult
185159 } catch ( error ) {
186160 getLogger ( ) . debug ( `Failed to prepare repo: ${ error } ` )
187161 if ( error instanceof ToolkitError && error . code === 'ContentLengthError' ) {
0 commit comments