@@ -12,7 +12,7 @@ import { Uri } from 'vscode'
1212import { GitIgnoreFilter } from './gitignore'
1313
1414import AdmZip from 'adm-zip'
15- import { PrepareRepoFailedError } from '../errors'
15+ import { ContentLengthError , PrepareRepoFailedError } from '../errors'
1616import { getLogger } from '../../shared/logger/logger'
1717import { maxFileSizeBytes } from '../limits'
1818import { createHash } from 'crypto'
@@ -21,6 +21,7 @@ import { ToolkitError } from '../../shared/errors'
2121import { AmazonqCreateUpload , Metric } from '../../shared/telemetry/telemetry'
2222import { TelemetryHelper } from './telemetryHelper'
2323import { sanitizeFilename } from '../../shared/utilities/textUtilities'
24+ import { maxRepoSizeBytes } from '../constants'
2425
2526export function getExcludePattern ( additionalPatterns : string [ ] = [ ] ) {
2627 const globAlwaysExcludedDirs = getGlobDirExcludedPatterns ( ) . map ( pattern => `**/${ pattern } /*` )
@@ -94,6 +95,7 @@ export async function collectFiles(
9495 return prefix === '' ? path : `${ prefix } /${ path } `
9596 }
9697
98+ let totalSizeBytes = 0
9799 for ( const rootPath of sourcePaths ) {
98100 const allFiles = await vscode . workspace . findFiles (
99101 new vscode . RelativePattern ( rootPath , '**' ) ,
@@ -102,29 +104,48 @@ export async function collectFiles(
102104 const files = respectGitIgnore ? await filterOutGitignoredFiles ( rootPath , allFiles ) : allFiles
103105
104106 for ( const file of files ) {
105- try {
106- const fileContent = await SystemUtilities . readFile ( file , new TextDecoder ( 'utf8' , { fatal : true } ) )
107- const relativePath = getWorkspaceRelativePath ( file . fsPath , { workspaceFolders } )
107+ const relativePath = getWorkspaceRelativePath ( file . fsPath , { workspaceFolders } )
108+ if ( ! relativePath ) {
109+ continue
110+ }
108111
109- if ( relativePath ) {
110- storage . push ( {
111- workspaceFolder : relativePath . workspaceFolder ,
112- relativeFilePath : relativePath . relativePath ,
113- fileUri : file ,
114- fileContent : fileContent ,
115- zipFilePath : prefixWithFolderPrefix ( relativePath . workspaceFolder , relativePath . relativePath ) ,
116- } )
117- }
118- } catch ( error ) {
119- getLogger ( ) . debug (
120- `featureDev: Failed to read file ${ file . fsPath } when collecting repository: ${ error } . Skipping the file`
121- )
112+ const fileStat = await vscode . workspace . fs . stat ( file )
113+ if ( totalSizeBytes + fileStat . size > maxRepoSizeBytes ) {
114+ throw new ContentLengthError ( )
122115 }
116+
117+ const fileContent = await readFile ( file )
118+ if ( fileContent === undefined ) {
119+ continue
120+ }
121+
122+ // Now that we've read the file, increase our usage
123+ totalSizeBytes += fileStat . size
124+ storage . push ( {
125+ workspaceFolder : relativePath . workspaceFolder ,
126+ relativeFilePath : relativePath . relativePath ,
127+ fileUri : file ,
128+ fileContent : fileContent ,
129+ zipFilePath : prefixWithFolderPrefix ( relativePath . workspaceFolder , relativePath . relativePath ) ,
130+ } )
123131 }
124132 }
125133 return storage
126134}
127135
136+ const readFile = async ( file : vscode . Uri ) => {
137+ try {
138+ const fileContent = await SystemUtilities . readFile ( file , new TextDecoder ( 'utf8' , { fatal : false } ) )
139+ return fileContent
140+ } catch ( error ) {
141+ getLogger ( ) . debug (
142+ `featureDev: Failed to read file ${ file . fsPath } when collecting repository. Skipping the file`
143+ )
144+ }
145+
146+ return undefined
147+ }
148+
128149const getSha256 = ( file : Buffer ) => createHash ( 'sha256' ) . update ( file ) . digest ( 'base64' )
129150
130151/**
@@ -137,9 +158,9 @@ export async function prepareRepoData(
137158 span : Metric < AmazonqCreateUpload >
138159) {
139160 try {
161+ const files = await collectFiles ( repoRootPaths , workspaceFolders , true )
140162 const zip = new AdmZip ( )
141163
142- const files = await collectFiles ( repoRootPaths , workspaceFolders , true )
143164 let totalBytes = 0
144165 for ( const file of files ) {
145166 const fileSize = ( await vscode . workspace . fs . stat ( file . fileUri ) ) . size
@@ -163,6 +184,9 @@ export async function prepareRepoData(
163184 }
164185 } catch ( error ) {
165186 getLogger ( ) . debug ( `featureDev: Failed to prepare repo: ${ error } ` )
187+ if ( error instanceof ContentLengthError ) {
188+ throw error
189+ }
166190 throw new PrepareRepoFailedError ( )
167191 }
168192}
0 commit comments