@@ -32,26 +32,34 @@ export class SourcegraphFileSystemProvider implements vscode.FileSystemProvider
3232 private fileNamesByRepository : Map < string , Promise < string [ ] > > = new Map ( )
3333 private metadata : Map < string , RepositoryMetadata > = new Map ( )
3434 private didDownloadFilenames = new vscode . EventEmitter < string > ( )
35- private readonly cache = new Map < string , Blob > ( )
3635
3736 // ======================
3837 // FileSystemProvider API
3938 // ======================
4039 private didChangeFile = new vscode . EventEmitter < vscode . FileChangeEvent [ ] > ( ) // Never used.
4140 public readonly onDidChangeFile : vscode . Event < vscode . FileChangeEvent [ ] > = this . didChangeFile . event
42- public async stat ( uri : vscode . Uri ) : Promise < vscode . FileStat > {
43- const blob = await this . fetchBlob ( this . sourcegraphUri ( uri ) )
41+ public async stat ( vscodeUri : vscode . Uri ) : Promise < vscode . FileStat > {
42+ const uri = this . sourcegraphUri ( vscodeUri )
43+ const files = await this . downloadedFiles ( uri )
44+ const isFile = uri . path && files . includes ( uri . path )
45+ const type = isFile ? vscode . FileType . File : vscode . FileType . Directory
46+ const now = Date . now ( )
4447 return {
45- mtime : blob . time ,
46- ctime : blob . time ,
47- size : blob . byteSize ,
48- type : blob . type ,
48+ // It seems to be OK to return hardcoded values for the timestamps
49+ // and the byte size. If it turns out the byte size needs to be
50+ // correct for some reason, then we can use
51+ // `this.fetchBlob(uri).byteSize` to get the value for files.
52+ mtime : now ,
53+ ctime : now ,
54+ size : 1337 ,
55+ type,
4956 }
5057 }
5158
5259 public async readFile ( vscodeUri : vscode . Uri ) : Promise < Uint8Array > {
5360 const uri = this . sourcegraphUri ( vscodeUri )
54- return ( await this . fetchBlob ( uri ) ) . content
61+ const blob = await this . fetchBlob ( uri )
62+ return blob . content
5563 }
5664
5765 public async readDirectory ( vscodeUri : vscode . Uri ) : Promise < [ string , vscode . FileType ] [ ] > {
@@ -60,13 +68,10 @@ export class SourcegraphFileSystemProvider implements vscode.FileSystemProvider
6068 return [ ]
6169 }
6270 const tree = await this . getFileTree ( uri )
63- if ( ! tree ) {
64- return [ ]
65- }
6671 const children = tree . directChildren ( uri . path || '' )
6772 return children . map ( childUri => {
6873 const child = SourcegraphUri . parse ( childUri )
69- const type = child . isDirectory ? vscode . FileType . Directory : vscode . FileType . File
74+ const type = child . isDirectory ( ) ? vscode . FileType . Directory : vscode . FileType . File
7075 return [ child . basename ( ) , type ]
7176 } )
7277 }
@@ -113,7 +118,7 @@ export class SourcegraphFileSystemProvider implements vscode.FileSystemProvider
113118 fileNames,
114119 } )
115120 } catch {
116- log . appendLine ( `ERROR: failed to download repo files ${ repositoryUri } `)
121+ log . error ( ` failed to download files for repository ' ${ repositoryUri } ' `)
117122 }
118123 }
119124 return promises
@@ -148,12 +153,12 @@ export class SourcegraphFileSystemProvider implements vscode.FileSystemProvider
148153 const token = emptyCancelationToken ( )
149154 const defaultBranch = ( await this . repositoryMetadata ( repositoryName , token ) ) ?. defaultBranch
150155 if ( ! defaultBranch ) {
151- const message = `ERROR defaultBranch no repository '${ repositoryName } '`
152- log . appendLine ( message )
156+ const message = `repository '${ repositoryName } ' has no default branch `
157+ log . error ( message )
153158 throw new Error ( message )
154159 }
155160 const uri = SourcegraphUri . fromParts ( endpointHostnameSetting ( ) , repositoryName , { revision : defaultBranch } )
156- const files = await this . downloadFiles ( uri , defaultBranch )
161+ const files = await this . downloadFiles ( uri )
157162 const readmes = files . filter ( name => name . match ( / r e a d m e / i) )
158163 const candidates = readmes . length > 0 ? readmes : files
159164 let readme : string | undefined
@@ -176,21 +181,18 @@ export class SourcegraphFileSystemProvider implements vscode.FileSystemProvider
176181 }
177182
178183 public async fetchBlob ( uri : SourcegraphUri ) : Promise < Blob > {
179- const result = this . cache . get ( uri . uri )
180- if ( result ) {
181- return result
182- }
183184 await this . repositoryMetadata ( uri . repositoryName )
184185 const token = emptyCancelationToken ( )
185- const revision = uri . revision || ( await this . repositoryMetadata ( uri . repositoryName , token ) ) ?. defaultBranch
186- if ( ! revision ) {
187- throw new Error ( `no uri.revision from uri ${ uri . uri } ` )
186+ if ( ! uri . revision ) {
187+ const error = `missing revision for URI '${ uri . uri } '`
188+ log . error ( error )
189+ throw new Error ( error )
188190 }
189191 const path = uri . path || ''
190192 const content = await contents (
191193 {
192194 repository : uri . repositoryName ,
193- revision,
195+ revision : uri . revision ,
194196 path,
195197 } ,
196198 token
@@ -200,18 +202,17 @@ export class SourcegraphFileSystemProvider implements vscode.FileSystemProvider
200202 const toCacheResult : Blob = {
201203 uri : uri . uri ,
202204 repositoryName : uri . repositoryName ,
203- revision,
205+ revision : uri . revision ,
204206 content : content . content ,
205207 isBinaryFile : content . isBinary ,
206208 byteSize : content . byteSize ,
207209 path,
208210 time : new Date ( ) . getMilliseconds ( ) ,
209211 type : vscode . FileType . File ,
210212 }
211- this . cache . set ( uri . uri , toCacheResult )
212213
213214 // Start downloading the repository files in the background.
214- this . downloadFiles ( uri , revision ) . then (
215+ this . downloadFiles ( uri ) . then (
215216 ( ) => { } ,
216217 ( ) => { }
217218 )
@@ -235,12 +236,19 @@ export class SourcegraphFileSystemProvider implements vscode.FileSystemProvider
235236 return metadata
236237 }
237238
238- public downloadFiles ( uri : SourcegraphUri , revision : string ) : Promise < string [ ] > {
239+ public async downloadedFiles ( uri : SourcegraphUri ) : Promise < string [ ] > {
240+ return this . fileNamesByRepository . get ( uri . repositoryUri ( ) ) || [ ]
241+ }
242+
243+ public downloadFiles ( uri : SourcegraphUri ) : Promise < string [ ] > {
239244 const key = uri . repositoryUri ( )
240245 const fileNamesByRepository = this . fileNamesByRepository
241246 let downloadingFiles = this . fileNamesByRepository . get ( key )
242247 if ( ! downloadingFiles ) {
243- downloadingFiles = filesQuery ( { repository : uri . repositoryName , revision } , emptyCancelationToken ( ) )
248+ downloadingFiles = filesQuery (
249+ { repository : uri . repositoryName , revision : uri . revision } ,
250+ emptyCancelationToken ( )
251+ )
244252 downloadingFiles . then (
245253 ( ) => this . didDownloadFilenames . fire ( key ) ,
246254 ( ) => fileNamesByRepository . delete ( key )
@@ -254,22 +262,8 @@ export class SourcegraphFileSystemProvider implements vscode.FileSystemProvider
254262 return SourcegraphUri . parse ( uri . toString ( true ) )
255263 }
256264
257- public async getFileTree ( uri : SourcegraphUri ) : Promise < FileTree | undefined > {
258- if ( ! uri . revision ) {
259- uri = uri . withRevision ( this . metadata . get ( uri . repositoryName ) ?. defaultBranch )
260- }
261- const key = uri . repositoryUri ( )
262- const downloading = this . fileNamesByRepository . get ( key )
263- if ( ! downloading ) {
264- const keys = JSON . stringify ( [ ...this . fileNamesByRepository . keys ( ) ] )
265- log . error ( `getFileTree(${ uri . uri } ) - empty downloading key=${ key } keys=${ keys } ` )
266- return Promise . resolve ( undefined )
267- }
268- const files = await downloading
269- if ( ! files ) {
270- log . error ( 'getFileTree - empty files' )
271- return Promise . resolve ( undefined )
272- }
265+ public async getFileTree ( uri : SourcegraphUri ) : Promise < FileTree > {
266+ const files = await this . downloadedFiles ( uri )
273267 return new FileTree ( uri , files )
274268 }
275269}
0 commit comments