import AdmZip , { IZipEntry } from 'adm-zip' ; import * as fs from 'fs' ; import { IDetailsResponse } from 'jfrog-client-js' ; import * as os from 'os' ; import * as path from 'path' ; import { LogManager } from '../log/logManager' ; export enum Type { BUILD_INFO , BUILD_SCAN_RESULTS } export class BuildsScanCache { public static readonly MAX_FILES : number = 100 * 2 ; private static readonly CACHE_BASE_PATH : string = path . resolve ( os . homedir ( ) , '.jfrog-vscode-extension' , 'ci-cache' ) ; private readonly buildsDir : string ; constructor ( private _projectName , private _logger ) { this . buildsDir = path . resolve ( BuildsScanCache . CACHE_BASE_PATH , this . getNameInBase64 ( this . _projectName ) ) ; if ( ! fs . existsSync ( this . buildsDir ) ) { fs . mkdirSync ( this . buildsDir , { recursive : true } ) ; } this . cleanUpOldBuilds ( ) ; } private getNameInBase64 ( str ) { return Buffer . from ( str ) . toString ( 'base64' ) ; } private private cleanUpOldBuilds ( ) { const currentBuildScanCaches = fs . readdirSync ( this . buildsDir ) . sort ( ) . reverse ( ) ; for ( let i = BuildsScanCache . MAX_FILES ; i < currentBuildScanCaches . length ; i ++ ) { const pathToDelete = path . resolve ( this . buildsDir , currentBuildScanCaches [ i ] ) ; this . _logger . logMessage ( 'Deleting ' + pathToDelete , 'DEBUG' ) ; fs . unlinkSync ( pathToDelete ) ; } } public save ( content , timestamp , buildName , buildNumber , projectKey , type ) { let zip = new AdmZip ( ) ; zip . addFile ( type . toString ( ) , Buffer . alloc ( content . length , content ) ) ; zip . writeZip ( this . getZipPath ( timestamp , buildName , buildNumber , projectKey , type ) ) ; } public load ( timestamp , buildName , buildNumber , projectKey , type ) { const buildPath = this . getZipPath ( timestamp , buildName , buildNumber , projectKey , type ) ; if ( ! fs . existsSync ( buildPath ) ) { return '' ; } let zip = new AdmZip ( buildPath ) ; let entry = zip . getEntry ( type . toString ( ) ) ; if ( ! entry ) { throw new Error ( 'Could not find expected content in archive in cache' ) ; } return entry . getData ( ) . toString ( 'utf8' ) ; } public loadBuildInfo ( timestamp , buildName , buildNumber , projectKey ) { let build = this . load ( timestamp , buildName , buildNumber , projectKey , Type . BUILD_INFO ) ; if ( ! build ) { return null ; } return JSON . parse ( build ) ; } public loadScanResults ( timestamp , buildName , buildNumber , projectKey ) { let response = this . load ( timestamp , buildName , buildNumber , projectKey , Type . BUILD_SCAN_RESULTS ) ; if ( ! response ) { return null ; } return Object . assign ( { } as IDetailsResponse , JSON . parse ( response ) ) ; } param timestamp param buildName param buildNumber param projectKey param type public getZipPath ( timestamp , buildName , buildNumber , projectKey , type ) { let buildIdentifier = buildName + '_' + buildNumber ; if ( projectKey ) { buildIdentifier += '_' + projectKey ; } return path . resolve ( this . buildsDir , timestamp + '_' + type . toString ( ) + this . getNameInBase64 ( buildIdentifier ) + '.zip' ) ; } }