2020-08-25 16:19:15 +01:00
"use strict" ;
2021-07-27 17:59:59 +01:00
var _ _createBinding = ( this && this . _ _createBinding ) || ( Object . create ? ( function ( o , m , k , k2 ) {
if ( k2 === undefined ) k2 = k ;
Object . defineProperty ( o , k2 , { enumerable : true , get : function ( ) { return m [ k ] ; } } ) ;
} ) : ( function ( o , m , k , k2 ) {
if ( k2 === undefined ) k2 = k ;
o [ k2 ] = m [ k ] ;
} ) ) ;
var _ _setModuleDefault = ( this && this . _ _setModuleDefault ) || ( Object . create ? ( function ( o , v ) {
Object . defineProperty ( o , "default" , { enumerable : true , value : v } ) ;
} ) : function ( o , v ) {
o [ "default" ] = v ;
} ) ;
2020-08-25 16:19:15 +01:00
var _ _importStar = ( this && this . _ _importStar ) || function ( mod ) {
if ( mod && mod . _ _esModule ) return mod ;
var result = { } ;
2021-07-27 17:59:59 +01:00
if ( mod != null ) for ( var k in mod ) if ( k !== "default" && Object . prototype . hasOwnProperty . call ( mod , k ) ) _ _createBinding ( result , mod , k ) ;
_ _setModuleDefault ( result , mod ) ;
2020-08-25 16:19:15 +01:00
return result ;
} ;
2022-06-13 22:34:44 +00:00
var _ _importDefault = ( this && this . _ _importDefault ) || function ( mod ) {
return ( mod && mod . _ _esModule ) ? mod : { "default" : mod } ;
} ;
2020-08-25 16:19:15 +01:00
Object . defineProperty ( exports , "__esModule" , { value : true } ) ;
2022-08-11 10:00:12 -07:00
exports . validateQueryFilters = exports . runCleanup = exports . runFinalize = exports . createQuerySuiteContents = exports . convertPackToQuerySuiteEntry = exports . runQueries = exports . dbIsFinalized = exports . createdDBForScannedLanguages = exports . CodeQLAnalysisError = void 0 ;
2020-08-25 16:19:15 +01:00
const fs = _ _importStar ( require ( "fs" ) ) ;
const path = _ _importStar ( require ( "path" ) ) ;
2022-08-24 11:59:11 +01:00
const perf _hooks _1 = require ( "perf_hooks" ) ; // We need to import `performance` on Node 12
2020-11-20 11:35:59 +01:00
const toolrunner = _ _importStar ( require ( "@actions/exec/lib/toolrunner" ) ) ;
2022-06-13 22:34:44 +00:00
const del _1 = _ _importDefault ( require ( "del" ) ) ;
2021-06-28 10:07:51 +01:00
const yaml = _ _importStar ( require ( "js-yaml" ) ) ;
2020-08-25 16:19:15 +01:00
const analysisPaths = _ _importStar ( require ( "./analysis-paths" ) ) ;
const codeql _1 = require ( "./codeql" ) ;
2022-06-27 13:13:55 -07:00
const configUtils = _ _importStar ( require ( "./config-utils" ) ) ;
2021-04-16 14:52:39 -07:00
const count _loc _1 = require ( "./count-loc" ) ;
2020-08-25 16:19:15 +01:00
const languages _1 = require ( "./languages" ) ;
const sharedEnv = _ _importStar ( require ( "./shared-environment" ) ) ;
2022-02-17 15:45:00 +00:00
const tracer _config _1 = require ( "./tracer-config" ) ;
2020-08-25 16:19:15 +01:00
const util = _ _importStar ( require ( "./util" ) ) ;
2020-10-22 10:22:27 +02:00
class CodeQLAnalysisError extends Error {
constructor ( queriesStatusReport , message ) {
super ( message ) ;
this . name = "CodeQLAnalysisError" ;
this . queriesStatusReport = queriesStatusReport ;
}
}
exports . CodeQLAnalysisError = CodeQLAnalysisError ;
2020-09-11 11:07:27 +02:00
async function setupPythonExtractor ( logger ) {
const codeqlPython = process . env [ "CODEQL_PYTHON" ] ;
if ( codeqlPython === undefined || codeqlPython . length === 0 ) {
// If CODEQL_PYTHON is not set, no dependencies were installed, so we don't need to do anything
return ;
}
2020-09-23 09:27:54 +02:00
let output = "" ;
2020-09-11 11:07:27 +02:00
const options = {
listeners : {
stdout : ( data ) => {
output += data . toString ( ) ;
2020-09-23 09:27:54 +02:00
} ,
} ,
2020-09-11 11:07:27 +02:00
} ;
2020-11-20 11:35:59 +01:00
await new toolrunner . ToolRunner ( codeqlPython , [
2020-09-23 09:27:54 +02:00
"-c" ,
2020-09-23 18:06:08 +02:00
"import os; import pip; print(os.path.dirname(os.path.dirname(pip.__file__)))" ,
2020-09-23 09:27:54 +02:00
] , options ) . exec ( ) ;
logger . info ( ` Setting LGTM_INDEX_IMPORT_PATH= ${ output } ` ) ;
process . env [ "LGTM_INDEX_IMPORT_PATH" ] = output ;
output = "" ;
2020-11-20 11:35:59 +01:00
await new toolrunner . ToolRunner ( codeqlPython , [ "-c" , "import sys; print(sys.version_info[0])" ] , options ) . exec ( ) ;
2020-09-23 09:27:54 +02:00
logger . info ( ` Setting LGTM_PYTHON_SETUP_VERSION= ${ output } ` ) ;
process . env [ "LGTM_PYTHON_SETUP_VERSION" ] = output ;
2020-09-11 11:07:27 +02:00
}
2022-11-14 13:54:35 -08:00
async function createdDBForScannedLanguages ( codeql , config , logger ) {
2020-08-25 16:19:15 +01:00
// Insert the LGTM_INDEX_X env vars at this point so they are set when
// we extract any scanned languages.
analysisPaths . includeAndExcludeAnalysisPaths ( config ) ;
for ( const language of config . languages ) {
2022-11-14 13:54:35 -08:00
if ( ( 0 , languages _1 . isScannedLanguage ) ( language ) &&
2021-06-28 10:07:51 +01:00
! dbIsFinalized ( config , language , logger ) ) {
2020-09-14 10:44:43 +01:00
logger . startGroup ( ` Extracting ${ language } ` ) ;
2020-09-11 11:07:27 +02:00
if ( language === languages _1 . Language . python ) {
await setupPythonExtractor ( logger ) ;
}
2022-09-13 11:19:13 +00:00
await codeql . extractScannedLanguage ( config , language ) ;
2020-08-25 16:19:15 +01:00
logger . endGroup ( ) ;
}
}
}
2022-06-27 16:01:48 +00:00
exports . createdDBForScannedLanguages = createdDBForScannedLanguages ;
2021-06-28 10:07:51 +01:00
function dbIsFinalized ( config , language , logger ) {
const dbPath = util . getCodeQLDatabasePath ( config , language ) ;
try {
const dbInfo = yaml . load ( fs . readFileSync ( path . resolve ( dbPath , "codeql-database.yml" ) , "utf8" ) ) ;
return ! ( "inProgress" in dbInfo ) ;
}
catch ( e ) {
logger . warning ( ` Could not check whether database for ${ language } was finalized. Assuming it is not. ` ) ;
return false ;
}
}
2022-07-29 12:00:07 +02:00
exports . dbIsFinalized = dbIsFinalized ;
2022-11-14 13:54:35 -08:00
async function finalizeDatabaseCreation ( config , threadsFlag , memoryFlag , logger ) {
2021-09-10 13:53:13 -07:00
const codeql = await ( 0 , codeql _1 . getCodeQL ) ( config . codeQLCmd ) ;
2022-08-24 11:59:11 +01:00
const extractionStart = perf _hooks _1 . performance . now ( ) ;
2022-11-14 13:54:35 -08:00
await createdDBForScannedLanguages ( codeql , config , logger ) ;
2022-08-24 11:59:11 +01:00
const extractionTime = perf _hooks _1 . performance . now ( ) - extractionStart ;
const trapImportStart = perf _hooks _1 . performance . now ( ) ;
2020-08-25 16:19:15 +01:00
for ( const language of config . languages ) {
2021-06-28 10:07:51 +01:00
if ( dbIsFinalized ( config , language , logger ) ) {
logger . info ( ` There is already a finalized database for ${ language } at the location where the CodeQL Action places databases, so we did not create one. ` ) ;
}
else {
logger . startGroup ( ` Finalizing ${ language } ` ) ;
2021-08-12 16:02:19 +01:00
await codeql . finalizeDatabase ( util . getCodeQLDatabasePath ( config , language ) , threadsFlag , memoryFlag ) ;
2021-06-28 10:07:51 +01:00
logger . endGroup ( ) ;
}
2020-08-25 16:19:15 +01:00
}
2022-08-24 11:59:11 +01:00
const trapImportTime = perf _hooks _1 . performance . now ( ) - trapImportStart ;
return {
scanned _language _extraction _duration _ms : Math . round ( extractionTime ) ,
trap _import _duration _ms : Math . round ( trapImportTime ) ,
} ;
2020-08-25 16:19:15 +01:00
}
// Runs queries and creates sarif files in the given folder
2022-10-11 10:39:40 -07:00
async function runQueries ( sarifFolder , memoryFlag , addSnippetsFlag , threadsFlag , automationDetailsId , config , logger , featureEnablement ) {
2020-09-10 18:02:33 +01:00
const statusReport = { } ;
2021-09-28 09:25:35 +01:00
let locPromise = Promise . resolve ( { } ) ;
const cliCanCountBaseline = await cliCanCountLoC ( ) ;
2022-06-28 22:49:42 +01:00
const countLocDebugMode = process . env [ "INTERNAL_CODEQL_ACTION_DEBUG_LOC" ] || config . debugMode ;
if ( ! cliCanCountBaseline || countLocDebugMode ) {
2021-09-28 09:25:35 +01:00
// count the number of lines in the background
locPromise = ( 0 , count _loc _1 . countLoc ) ( path . resolve ( ) ,
// config.paths specifies external directories. the current
// directory is included in the analysis by default. Replicate
// that here.
config . paths , config . pathsIgnore , config . languages , logger ) ;
}
2022-06-29 12:50:24 -07:00
const codeql = await ( 0 , codeql _1 . getCodeQL ) ( config . codeQLCmd ) ;
2022-10-11 10:39:40 -07:00
await util . logCodeScanningConfigInCli ( codeql , featureEnablement , logger ) ;
2020-09-14 10:44:43 +01:00
for ( const language of config . languages ) {
2020-09-10 18:02:33 +01:00
const queries = config . queries [ language ] ;
2022-06-27 13:13:55 -07:00
const queryFilters = validateQueryFilters ( config . originalUserInput [ "query-filters" ] ) ;
2021-06-03 09:32:44 -07:00
const packsWithVersion = config . packs [ language ] || [ ] ;
2021-07-27 17:59:59 +01:00
const hasBuiltinQueries = ( queries === null || queries === void 0 ? void 0 : queries . builtin . length ) > 0 ;
const hasCustomQueries = ( queries === null || queries === void 0 ? void 0 : queries . custom . length ) > 0 ;
2021-06-04 13:12:49 -07:00
const hasPackWithCustomQueries = packsWithVersion . length > 0 ;
if ( ! hasBuiltinQueries && ! hasCustomQueries && ! hasPackWithCustomQueries ) {
2020-09-14 10:44:43 +01:00
throw new Error ( ` Unable to analyse ${ language } as no queries were selected for this language ` ) ;
2020-08-25 16:19:15 +01:00
}
try {
2022-10-11 10:39:40 -07:00
if ( await util . useCodeScanningConfigInCli ( codeql , featureEnablement ) ) {
2022-06-29 12:50:24 -07:00
// If we are using the codescanning config in the CLI,
// much of the work needed to generate the query suites
// is done in the CLI. We just need to make a single
// call to run all the queries for each language and
// another to interpret the results.
logger . startGroup ( ` Running queries for ${ language } ` ) ;
2021-05-28 18:32:53 +01:00
const startTimeBuiltIn = new Date ( ) . getTime ( ) ;
2022-06-29 12:50:24 -07:00
await runQueryGroup ( language , "all" , undefined , undefined ) ;
// TODO should not be using `builtin` here. We should be using `all` instead.
// The status report does not support `all` yet.
2021-04-01 12:38:13 +01:00
statusReport [ ` analyze_builtin_queries_ ${ language } _duration_ms ` ] =
2021-05-28 18:32:53 +01:00
new Date ( ) . getTime ( ) - startTimeBuiltIn ;
2022-06-29 12:50:24 -07:00
logger . startGroup ( ` Interpreting results for ${ language } ` ) ;
const startTimeInterpretResults = new Date ( ) . getTime ( ) ;
const sarifFile = path . join ( sarifFolder , ` ${ language } .sarif ` ) ;
2022-07-13 13:27:04 -07:00
const analysisSummary = await runInterpretResults ( language , undefined , sarifFile , config . debugMode ) ;
2022-06-29 12:50:24 -07:00
statusReport [ ` interpret_results_ ${ language } _duration_ms ` ] =
new Date ( ) . getTime ( ) - startTimeInterpretResults ;
logger . endGroup ( ) ;
logger . info ( analysisSummary ) ;
2021-04-01 12:38:13 +01:00
}
2022-06-29 12:50:24 -07:00
else {
logger . startGroup ( ` Running queries for ${ language } ` ) ;
const querySuitePaths = [ ] ;
if ( queries [ "builtin" ] . length > 0 ) {
const startTimeBuiltIn = new Date ( ) . getTime ( ) ;
2022-08-11 14:16:50 -07:00
querySuitePaths . push ( ( await runQueryGroup ( language , "builtin" , createQuerySuiteContents ( queries [ "builtin" ] , queryFilters ) , undefined ) ) ) ;
2022-06-29 12:50:24 -07:00
statusReport [ ` analyze_builtin_queries_ ${ language } _duration_ms ` ] =
new Date ( ) . getTime ( ) - startTimeBuiltIn ;
}
const startTimeCustom = new Date ( ) . getTime ( ) ;
let ranCustom = false ;
for ( let i = 0 ; i < queries [ "custom" ] . length ; ++ i ) {
if ( queries [ "custom" ] [ i ] . queries . length > 0 ) {
2022-08-11 14:16:50 -07:00
querySuitePaths . push ( ( await runQueryGroup ( language , ` custom- ${ i } ` , createQuerySuiteContents ( queries [ "custom" ] [ i ] . queries , queryFilters ) , queries [ "custom" ] [ i ] . searchPath ) ) ) ;
2022-06-29 12:50:24 -07:00
ranCustom = true ;
}
}
if ( packsWithVersion . length > 0 ) {
2022-08-11 14:16:50 -07:00
querySuitePaths . push ( await runQueryPacks ( language , "packs" , packsWithVersion , queryFilters ) ) ;
2021-06-04 14:28:55 +01:00
ranCustom = true ;
2020-09-10 18:02:33 +01:00
}
2022-06-29 12:50:24 -07:00
if ( ranCustom ) {
statusReport [ ` analyze_custom_queries_ ${ language } _duration_ms ` ] =
new Date ( ) . getTime ( ) - startTimeCustom ;
}
logger . endGroup ( ) ;
logger . startGroup ( ` Interpreting results for ${ language } ` ) ;
const startTimeInterpretResults = new Date ( ) . getTime ( ) ;
const sarifFile = path . join ( sarifFolder , ` ${ language } .sarif ` ) ;
2022-07-13 13:27:04 -07:00
const analysisSummary = await runInterpretResults ( language , querySuitePaths , sarifFile , config . debugMode ) ;
2022-06-29 12:50:24 -07:00
if ( ! cliCanCountBaseline ) {
await injectLinesOfCode ( sarifFile , language , locPromise ) ;
}
statusReport [ ` interpret_results_ ${ language } _duration_ms ` ] =
new Date ( ) . getTime ( ) - startTimeInterpretResults ;
logger . endGroup ( ) ;
logger . info ( analysisSummary ) ;
2020-09-10 18:02:33 +01:00
}
2022-07-13 13:27:04 -07:00
if ( ! cliCanCountBaseline || countLocDebugMode ) {
2021-09-28 09:25:35 +01:00
printLinesOfCodeSummary ( logger , language , await locPromise ) ;
2022-06-29 12:50:24 -07:00
}
if ( cliCanCountBaseline ) {
2021-09-28 09:25:35 +01:00
logger . info ( await runPrintLinesOfCode ( language ) ) ;
2022-06-29 12:50:24 -07:00
}
2020-08-25 16:19:15 +01:00
}
catch ( e ) {
2021-09-10 13:53:13 -07:00
logger . info ( String ( e ) ) ;
if ( e instanceof Error ) {
logger . info ( e . stack ) ;
}
2020-09-10 18:02:33 +01:00
statusReport . analyze _failure _language = language ;
2020-10-22 10:22:27 +02:00
throw new CodeQLAnalysisError ( statusReport , ` Error running analysis for ${ language } : ${ e } ` ) ;
2020-08-25 16:19:15 +01:00
}
}
2020-09-10 18:02:33 +01:00
return statusReport ;
2022-06-28 22:51:46 +01:00
async function runInterpretResults ( language , queries , sarifFile , enableDebugLogging ) {
2021-06-04 14:28:55 +01:00
const databasePath = util . getCodeQLDatabasePath ( config , language ) ;
2022-10-26 16:14:02 +01:00
return await codeql . databaseInterpretResults ( databasePath , queries , sarifFile , addSnippetsFlag , threadsFlag , enableDebugLogging ? "-vv" : "-v" , automationDetailsId , featureEnablement ) ;
2021-06-04 14:28:55 +01:00
}
2021-09-28 09:25:35 +01:00
async function cliCanCountLoC ( ) {
return await util . codeQlVersionAbove ( await ( 0 , codeql _1 . getCodeQL ) ( config . codeQLCmd ) , codeql _1 . CODEQL _VERSION _COUNTS _LINES ) ;
}
async function runPrintLinesOfCode ( language ) {
const databasePath = util . getCodeQLDatabasePath ( config , language ) ;
return await codeql . databasePrintBaseline ( databasePath ) ;
}
2021-06-09 12:43:17 -07:00
async function runQueryGroup ( language , type , querySuiteContents , searchPath ) {
2021-05-17 10:35:09 +01:00
const databasePath = util . getCodeQLDatabasePath ( config , language ) ;
2021-04-01 12:38:13 +01:00
// Pass the queries to codeql using a file instead of using the command
// line to avoid command line length restrictions, particularly on windows.
2022-06-29 12:50:24 -07:00
const querySuitePath = querySuiteContents
? ` ${ databasePath } -queries- ${ type } .qls `
: undefined ;
if ( querySuiteContents && querySuitePath ) {
fs . writeFileSync ( querySuitePath , querySuiteContents ) ;
logger . debug ( ` Query suite file for ${ language } - ${ type } ... \n ${ querySuiteContents } ` ) ;
}
2021-06-04 14:28:55 +01:00
await codeql . databaseRunQueries ( databasePath , searchPath , querySuitePath , memoryFlag , threadsFlag ) ;
logger . debug ( ` BQRS results produced for ${ language } (queries: ${ type } )" ` ) ;
return querySuitePath ;
2021-04-01 12:38:13 +01:00
}
2022-06-27 13:13:55 -07:00
async function runQueryPacks ( language , type , packs , queryFilters ) {
2022-04-26 19:47:59 -07:00
const databasePath = util . getCodeQLDatabasePath ( config , language ) ;
for ( const pack of packs ) {
logger . debug ( ` Running query pack for ${ language } - ${ type } : ${ pack } ` ) ;
}
2022-06-27 13:13:55 -07:00
// combine the list of packs into a query suite in order to run them all simultaneously.
const querySuite = packs . map ( convertPackToQuerySuiteEntry ) . concat ( queryFilters ) ;
const querySuitePath = ` ${ databasePath } -queries- ${ type } .qls ` ;
fs . writeFileSync ( querySuitePath , yaml . dump ( querySuite ) ) ;
logger . debug ( ` BQRS results produced for ${ language } (queries: ${ type } )" ` ) ;
await codeql . databaseRunQueries ( databasePath , undefined , querySuitePath , memoryFlag , threadsFlag ) ;
return querySuitePath ;
2022-04-26 19:47:59 -07:00
}
2020-08-25 16:19:15 +01:00
}
2020-09-10 18:02:33 +01:00
exports . runQueries = runQueries ;
2022-06-27 13:13:55 -07:00
function convertPackToQuerySuiteEntry ( packStr ) {
var _a , _b , _c , _d ;
const pack = configUtils . parsePacksSpecification ( packStr ) ;
return {
qlpack : ! pack . path ? pack . name : undefined ,
from : pack . path ? pack . name : undefined ,
version : pack . version ,
query : ( ( _a = pack . path ) === null || _a === void 0 ? void 0 : _a . endsWith ( ".ql" ) ) ? pack . path : undefined ,
queries : ! ( ( _b = pack . path ) === null || _b === void 0 ? void 0 : _b . endsWith ( ".ql" ) ) && ! ( ( _c = pack . path ) === null || _c === void 0 ? void 0 : _c . endsWith ( ".qls" ) )
? pack . path
: undefined ,
apply : ( ( _d = pack . path ) === null || _d === void 0 ? void 0 : _d . endsWith ( ".qls" ) ) ? pack . path : undefined ,
} ;
2021-06-03 09:32:44 -07:00
}
2022-06-27 13:13:55 -07:00
exports . convertPackToQuerySuiteEntry = convertPackToQuerySuiteEntry ;
function createQuerySuiteContents ( queries , queryFilters ) {
return yaml . dump ( queries . map ( ( q ) => ( { query : q } ) ) . concat ( queryFilters ) ) ;
2021-06-03 09:32:44 -07:00
}
2022-06-27 13:13:55 -07:00
exports . createQuerySuiteContents = createQuerySuiteContents ;
2022-11-14 13:54:35 -08:00
async function runFinalize ( outputDir , threadsFlag , memoryFlag , config , logger ) {
2022-02-28 15:16:05 +00:00
try {
2022-06-13 22:34:44 +00:00
await ( 0 , del _1 . default ) ( outputDir , { force : true } ) ;
2022-02-28 15:16:05 +00:00
}
catch ( error ) {
if ( ( error === null || error === void 0 ? void 0 : error . code ) !== "ENOENT" ) {
throw error ;
}
}
await fs . promises . mkdir ( outputDir , { recursive : true } ) ;
2022-11-14 13:54:35 -08:00
const timings = await finalizeDatabaseCreation ( config , threadsFlag , memoryFlag , logger ) ;
2022-07-12 10:43:23 +00:00
const codeql = await ( 0 , codeql _1 . getCodeQL ) ( config . codeQLCmd ) ;
// WARNING: This does not _really_ end tracing, as the tracer will restore its
// critical environment variables and it'll still be active for all processes
// launched from this build step.
// However, it will stop tracing for all steps past the codeql-action/analyze
// step.
if ( await util . codeQlVersionAbove ( codeql , codeql _1 . CODEQL _VERSION _NEW _TRACING ) ) {
// Delete variables as specified by the end-tracing script
2022-11-14 13:54:35 -08:00
await ( 0 , tracer _config _1 . endTracingForCluster ) ( config ) ;
2022-07-12 10:43:23 +00:00
}
else {
// Delete the tracer config env var to avoid tracing ourselves
delete process . env [ sharedEnv . ODASA _TRACER _CONFIGURATION ] ;
}
2022-08-24 11:59:11 +01:00
return timings ;
2020-08-25 16:19:15 +01:00
}
2021-06-28 10:07:51 +01:00
exports . runFinalize = runFinalize ;
2021-05-24 17:26:13 +01:00
async function runCleanup ( config , cleanupLevel , logger ) {
2021-06-09 11:16:22 +01:00
logger . startGroup ( "Cleaning up databases" ) ;
2021-05-24 17:26:13 +01:00
for ( const language of config . languages ) {
2021-09-10 13:53:13 -07:00
const codeql = await ( 0 , codeql _1 . getCodeQL ) ( config . codeQLCmd ) ;
2021-05-24 17:26:13 +01:00
const databasePath = util . getCodeQLDatabasePath ( config , language ) ;
await codeql . databaseCleanup ( databasePath , cleanupLevel ) ;
}
2021-06-09 11:16:22 +01:00
logger . endGroup ( ) ;
2021-05-24 17:26:13 +01:00
}
exports . runCleanup = runCleanup ;
2021-04-16 14:52:39 -07:00
async function injectLinesOfCode ( sarifFile , language , locPromise ) {
2021-07-21 10:27:42 +01:00
var _a ;
2021-04-16 14:52:39 -07:00
const lineCounts = await locPromise ;
if ( language in lineCounts ) {
const sarif = JSON . parse ( fs . readFileSync ( sarifFile , "utf8" ) ) ;
if ( Array . isArray ( sarif . runs ) ) {
for ( const run of sarif . runs ) {
run . properties = run . properties || { } ;
run . properties . metricResults = run . properties . metricResults || [ ] ;
2021-07-21 10:27:42 +01:00
for ( const metric of run . properties . metricResults ) {
2021-08-26 13:46:22 +01:00
// Baseline is inserted when matching rule has tag lines-of-code
2021-07-21 10:27:42 +01:00
if ( metric . rule && metric . rule . toolComponent ) {
const matchingRule = run . tool . extensions [ metric . rule . toolComponent . index ] . rules [ metric . rule . index ] ;
if ( ( _a = matchingRule . properties . tags ) === null || _a === void 0 ? void 0 : _a . includes ( "lines-of-code" ) ) {
metric . baseline = lineCounts [ language ] ;
}
}
}
2021-04-16 14:52:39 -07:00
}
}
fs . writeFileSync ( sarifFile , JSON . stringify ( sarif ) ) ;
}
}
2021-05-13 17:56:27 +00:00
function printLinesOfCodeSummary ( logger , language , lineCounts ) {
if ( language in lineCounts ) {
2021-06-09 13:19:49 -07:00
logger . info ( ` Counted a baseline of ${ lineCounts [ language ] } lines of code for ${ language } . ` ) ;
2021-05-13 17:56:27 +00:00
}
}
2022-06-27 13:13:55 -07:00
// exported for testing
function validateQueryFilters ( queryFilters ) {
if ( ! queryFilters ) {
return [ ] ;
}
2022-08-23 09:25:59 -07:00
if ( ! Array . isArray ( queryFilters ) ) {
throw new Error ( ` Query filters must be an array of "include" or "exclude" entries. Found ${ typeof queryFilters } ` ) ;
}
2022-06-27 13:13:55 -07:00
const errors = [ ] ;
for ( const qf of queryFilters ) {
const keys = Object . keys ( qf ) ;
if ( keys . length !== 1 ) {
errors . push ( ` Query filter must have exactly one key: ${ JSON . stringify ( qf ) } ` ) ;
}
if ( ! [ "exclude" , "include" ] . includes ( keys [ 0 ] ) ) {
errors . push ( ` Only "include" or "exclude" filters are allowed: \n ${ JSON . stringify ( qf ) } ` ) ;
}
}
if ( errors . length ) {
throw new Error ( ` Invalid query filter. \n ${ errors . join ( "\n" ) } ` ) ;
}
return queryFilters ;
}
exports . validateQueryFilters = validateQueryFilters ;
2020-08-25 16:19:15 +01:00
//# sourceMappingURL=analyze.js.map