11// Exported for testing
22import type { CodeQLCliServer , DbInfo } from "../../codeql-cli/cli" ;
3- import { Uri , workspace } from "vscode" ;
3+ import { FileType , Uri , workspace } from "vscode" ;
44import type { FullDatabaseOptions } from "./database-options" ;
55import { basename , dirname , extname , join } from "path" ;
66import {
@@ -9,7 +9,11 @@ import {
99 encodeSourceArchiveUri ,
1010 zipArchiveScheme ,
1111} from "../../common/vscode/archive-filesystem-provider" ;
12- import type { DatabaseItem , PersistedDatabaseItem } from "./database-item" ;
12+ import type {
13+ DatabaseItem ,
14+ PersistedDatabaseItem ,
15+ SourceArchiveFile ,
16+ } from "./database-item" ;
1317import { isLikelyDatabaseRoot } from "./db-contents-heuristics" ;
1418import { stat } from "fs-extra" ;
1519import { containsPath , pathsEqual } from "../../common/files" ;
@@ -22,6 +26,8 @@ export class DatabaseItemImpl implements DatabaseItem {
2226 public contents : DatabaseContents | undefined ;
2327 /** A cache of database info */
2428 private _dbinfo : DbInfo | undefined ;
29+ /** A cache of source archive files */
30+ private _sourceArchiveFiles : SourceArchiveFile [ ] | undefined ;
2531
2632 public constructor (
2733 public readonly databaseUri : Uri ,
@@ -234,4 +240,66 @@ export class DatabaseItemImpl implements DatabaseItem {
234240 return false ;
235241 }
236242 }
243+
244+ public async getSourceArchiveFiles ( ) : Promise < SourceArchiveFile [ ] > {
245+ if ( this . _sourceArchiveFiles === undefined ) {
246+ this . _sourceArchiveFiles = await this . collectSourceArchiveFiles ( ) ;
247+ }
248+ return this . _sourceArchiveFiles ;
249+ }
250+
251+ private async collectSourceArchiveFiles ( ) : Promise < SourceArchiveFile [ ] > {
252+ const explorerUri = this . getSourceArchiveExplorerUri ( ) ;
253+ const sourceArchiveZipPath =
254+ decodeSourceArchiveUri ( explorerUri ) . sourceArchiveZipPath ;
255+
256+ const items : SourceArchiveFile [ ] = [ ] ;
257+ await this . collectFilesRecursive (
258+ explorerUri ,
259+ sourceArchiveZipPath ,
260+ "" ,
261+ items ,
262+ ) ;
263+ // Sort by file name, then by path
264+ items . sort ( ( a , b ) => {
265+ const nameCmp = a . name . localeCompare ( b . name ) ;
266+ if ( nameCmp !== 0 ) {
267+ return nameCmp ;
268+ }
269+ return a . path . localeCompare ( b . path ) ;
270+ } ) ;
271+ return items ;
272+ }
273+
274+ private async collectFilesRecursive (
275+ dirUri : Uri ,
276+ sourceArchiveZipPath : string ,
277+ prefix : string ,
278+ items : SourceArchiveFile [ ] ,
279+ ) : Promise < void > {
280+ const entries = await workspace . fs . readDirectory ( dirUri ) ;
281+
282+ for ( const [ name , type ] of entries ) {
283+ const childPath = prefix ? `${ prefix } /${ name } ` : name ;
284+ const childUri = encodeSourceArchiveUri ( {
285+ sourceArchiveZipPath,
286+ pathWithinSourceArchive : `${ decodeSourceArchiveUri ( dirUri ) . pathWithinSourceArchive } /${ name } ` ,
287+ } ) ;
288+
289+ if ( type === FileType . File ) {
290+ items . push ( {
291+ name,
292+ path : prefix ,
293+ uri : childUri ,
294+ } ) ;
295+ } else if ( type === FileType . Directory ) {
296+ await this . collectFilesRecursive (
297+ childUri ,
298+ sourceArchiveZipPath ,
299+ childPath ,
300+ items ,
301+ ) ;
302+ }
303+ }
304+ }
237305}
0 commit comments