@@ -12,7 +12,7 @@ import { Uri } from 'vscode'
12
12
import { GitIgnoreFilter } from './gitignore'
13
13
14
14
import AdmZip from 'adm-zip'
15
- import { PrepareRepoFailedError } from '../errors'
15
+ import { ContentLengthError , PrepareRepoFailedError } from '../errors'
16
16
import { getLogger } from '../../shared/logger/logger'
17
17
import { maxFileSizeBytes } from '../limits'
18
18
import { createHash } from 'crypto'
@@ -21,6 +21,7 @@ import { ToolkitError } from '../../shared/errors'
21
21
import { AmazonqCreateUpload , Metric } from '../../shared/telemetry/telemetry'
22
22
import { TelemetryHelper } from './telemetryHelper'
23
23
import { sanitizeFilename } from '../../shared/utilities/textUtilities'
24
+ import { maxRepoSizeBytes } from '../constants'
24
25
25
26
export function getExcludePattern ( additionalPatterns : string [ ] = [ ] ) {
26
27
const globAlwaysExcludedDirs = getGlobDirExcludedPatterns ( ) . map ( pattern => `**/${ pattern } /*` )
@@ -94,6 +95,7 @@ export async function collectFiles(
94
95
return prefix === '' ? path : `${ prefix } /${ path } `
95
96
}
96
97
98
+ let totalSizeBytes = 0
97
99
for ( const rootPath of sourcePaths ) {
98
100
const allFiles = await vscode . workspace . findFiles (
99
101
new vscode . RelativePattern ( rootPath , '**' ) ,
@@ -102,29 +104,48 @@ export async function collectFiles(
102
104
const files = respectGitIgnore ? await filterOutGitignoredFiles ( rootPath , allFiles ) : allFiles
103
105
104
106
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
+ }
108
111
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 ( )
122
115
}
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
+ } )
123
131
}
124
132
}
125
133
return storage
126
134
}
127
135
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
+
128
149
const getSha256 = ( file : Buffer ) => createHash ( 'sha256' ) . update ( file ) . digest ( 'base64' )
129
150
130
151
/**
@@ -137,9 +158,9 @@ export async function prepareRepoData(
137
158
span : Metric < AmazonqCreateUpload >
138
159
) {
139
160
try {
161
+ const files = await collectFiles ( repoRootPaths , workspaceFolders , true )
140
162
const zip = new AdmZip ( )
141
163
142
- const files = await collectFiles ( repoRootPaths , workspaceFolders , true )
143
164
let totalBytes = 0
144
165
for ( const file of files ) {
145
166
const fileSize = ( await vscode . workspace . fs . stat ( file . fileUri ) ) . size
@@ -163,6 +184,9 @@ export async function prepareRepoData(
163
184
}
164
185
} catch ( error ) {
165
186
getLogger ( ) . debug ( `featureDev: Failed to prepare repo: ${ error } ` )
187
+ if ( error instanceof ContentLengthError ) {
188
+ throw error
189
+ }
166
190
throw new PrepareRepoFailedError ( )
167
191
}
168
192
}
0 commit comments