@@ -11,6 +11,7 @@ import {
1111 createWriteStream ,
1212 remove ,
1313 readdir ,
14+ copy ,
1415} from "fs-extra" ;
1516import { basename , join } from "path" ;
1617import type { Octokit } from "@octokit/rest" ;
@@ -64,7 +65,7 @@ export async function promptImportInternetDatabase(
6465
6566 validateUrl ( databaseUrl ) ;
6667
67- const item = await databaseArchiveFetcher (
68+ const item = await fetchDatabaseToWorkspaceStorage (
6869 databaseUrl ,
6970 { } ,
7071 databaseManager ,
@@ -258,7 +259,7 @@ export async function downloadGitHubDatabaseFromUrl(
258259 * We only need the actual token string.
259260 */
260261 const octokitToken = ( ( await octokit . auth ( ) ) as { token : string } ) ?. token ;
261- return await databaseArchiveFetcher (
262+ return await fetchDatabaseToWorkspaceStorage (
262263 databaseUrl ,
263264 {
264265 Accept : "application/zip" ,
@@ -282,14 +283,15 @@ export async function downloadGitHubDatabaseFromUrl(
282283}
283284
284285/**
285- * Imports a database from a local archive.
286+ * Imports a database from a local archive or a test database that is in a folder
287+ * ending with `.testproj`.
286288 *
287- * @param databaseUrl the file url of the archive to import
289+ * @param databaseUrl the file url of the archive or directory to import
288290 * @param databaseManager the DatabaseManager
289291 * @param storagePath where to store the unzipped database.
290292 * @param cli the CodeQL CLI server
291293 */
292- export async function importArchiveDatabase (
294+ export async function importLocalDatabase (
293295 commandManager : AppCommandManager ,
294296 databaseUrl : string ,
295297 databaseManager : DatabaseManager ,
@@ -298,24 +300,27 @@ export async function importArchiveDatabase(
298300 cli : CodeQLCliServer ,
299301) : Promise < DatabaseItem | undefined > {
300302 try {
301- const item = await databaseArchiveFetcher (
303+ const origin : DatabaseOrigin = {
304+ type : databaseUrl . endsWith ( ".testproj" ) ? "testproj" : "archive" ,
305+ path : Uri . parse ( databaseUrl ) . fsPath ,
306+ } ;
307+ const item = await fetchDatabaseToWorkspaceStorage (
302308 databaseUrl ,
303309 { } ,
304310 databaseManager ,
305311 storagePath ,
306312 undefined ,
307- {
308- type : "archive" ,
309- path : databaseUrl ,
310- } ,
313+ origin ,
311314 progress ,
312315 cli ,
313316 ) ;
314317 if ( item ) {
315318 await commandManager . execute ( "codeQLDatabases.focus" ) ;
316319 void showAndLogInformationMessage (
317320 extLogger ,
318- "Database unzipped and imported successfully." ,
321+ origin . type === "testproj"
322+ ? "Test database imported successfully."
323+ : "Database unzipped and imported successfully." ,
319324 ) ;
320325 }
321326 return item ;
@@ -332,10 +337,10 @@ export async function importArchiveDatabase(
332337}
333338
334339/**
335- * Fetches an archive database. The database might be on the internet
340+ * Fetches a database into workspace storage . The database might be on the internet
336341 * or in the local filesystem.
337342 *
338- * @param databaseUrl URL from which to grab the database
343+ * @param databaseUrl URL from which to grab the database. This could be a local archive file, a local directory, or a remote URL.
339344 * @param requestHeaders Headers to send with the request
340345 * @param databaseManager the DatabaseManager
341346 * @param storagePath where to store the unzipped database.
@@ -346,7 +351,7 @@ export async function importArchiveDatabase(
346351 * @param makeSelected make the new database selected in the databases panel (default: true)
347352 * @param addSourceArchiveFolder whether to add a workspace folder containing the source archive to the workspace
348353 */
349- async function databaseArchiveFetcher (
354+ async function fetchDatabaseToWorkspaceStorage (
350355 databaseUrl : string ,
351356 requestHeaders : { [ key : string ] : string } ,
352357 databaseManager : DatabaseManager ,
@@ -374,7 +379,11 @@ async function databaseArchiveFetcher(
374379 ) ;
375380
376381 if ( isFile ( databaseUrl ) ) {
377- await readAndUnzip ( databaseUrl , unzipPath , cli , progress ) ;
382+ if ( origin . type === "testproj" ) {
383+ await copyDatabase ( databaseUrl , unzipPath , progress ) ;
384+ } else {
385+ await readAndUnzip ( databaseUrl , unzipPath , cli , progress ) ;
386+ }
378387 } else {
379388 await fetchAndUnzip ( databaseUrl , requestHeaders , unzipPath , cli , progress ) ;
380389 }
@@ -438,6 +447,8 @@ async function getStorageFolder(
438447 lastName = basename ( url . path ) . substring ( 0 , 250 ) ;
439448 if ( lastName . endsWith ( ".zip" ) ) {
440449 lastName = lastName . substring ( 0 , lastName . length - 4 ) ;
450+ } else if ( lastName . endsWith ( ".testproj" ) ) {
451+ lastName = lastName . substring ( 0 , lastName . length - 9 ) ;
441452 }
442453 }
443454
@@ -484,6 +495,26 @@ function validateUrl(databaseUrl: string) {
484495 }
485496}
486497
498+ /**
499+ * Copies a database folder from the file system into the workspace storage.
500+ * @param scrDirURL the original location of the database as a URL string
501+ * @param destDir the location to copy the database to. This should be a folder in the workspace storage.
502+ * @param progress callback to send progress messages to
503+ */
504+ async function copyDatabase (
505+ srcDirURL : string ,
506+ destDir : string ,
507+ progress ?: ProgressCallback ,
508+ ) {
509+ progress ?.( {
510+ maxStep : 10 ,
511+ step : 9 ,
512+ message : `Copying database ${ basename ( destDir ) } into the workspace` ,
513+ } ) ;
514+ await ensureDir ( destDir ) ;
515+ await copy ( Uri . parse ( srcDirURL ) . fsPath , destDir ) ;
516+ }
517+
487518async function readAndUnzip (
488519 zipUrl : string ,
489520 unzipPath : string ,
0 commit comments