2020-08-11 12:43:27 +01:00
"use strict" ;
var _ _importStar = ( this && this . _ _importStar ) || function ( mod ) {
if ( mod && mod . _ _esModule ) return mod ;
var result = { } ;
if ( mod != null ) for ( var k in mod ) if ( Object . hasOwnProperty . call ( mod , k ) ) result [ k ] = mod [ k ] ;
result [ "default" ] = mod ;
return result ;
} ;
Object . defineProperty ( exports , "__esModule" , { value : true } ) ;
2020-08-25 16:19:15 +01:00
const fs = _ _importStar ( require ( "fs" ) ) ;
const os = _ _importStar ( require ( "os" ) ) ;
2020-08-11 12:43:27 +01:00
const path = _ _importStar ( require ( "path" ) ) ;
2020-10-01 11:03:30 +01:00
const commander _1 = require ( "commander" ) ;
2021-05-20 15:20:32 -07:00
const actions _util _1 = require ( "./actions-util" ) ;
2020-08-25 16:19:15 +01:00
const analyze _1 = require ( "./analyze" ) ;
const autobuild _1 = require ( "./autobuild" ) ;
const codeql _1 = require ( "./codeql" ) ;
2020-08-27 14:04:09 +01:00
const config _utils _1 = require ( "./config-utils" ) ;
2020-08-25 16:19:15 +01:00
const init _1 = require ( "./init" ) ;
const languages _1 = require ( "./languages" ) ;
2020-08-11 12:43:27 +01:00
const logging _1 = require ( "./logging" ) ;
const repository _1 = require ( "./repository" ) ;
const upload _lib = _ _importStar ( require ( "./upload-lib" ) ) ;
2020-09-01 14:13:10 +01:00
const util _1 = require ( "./util" ) ;
2021-05-31 09:35:13 -07:00
// eslint-disable-next-line import/no-commonjs
const pkg = require ( "../package.json" ) ;
2020-08-11 12:43:27 +01:00
const program = new commander _1 . Command ( ) ;
2021-05-31 11:14:03 -07:00
program . version ( pkg . version ) . hook ( "preAction" , ( ) => {
actions _util _1 . setMode ( actions _util _1 . Mode . runner ) ;
} ) ;
2020-08-25 16:19:15 +01:00
function getTempDir ( userInput ) {
2020-09-14 10:44:43 +01:00
const tempDir = path . join ( userInput || process . cwd ( ) , "codeql-runner" ) ;
2020-08-25 16:19:15 +01:00
if ( ! fs . existsSync ( tempDir ) ) {
fs . mkdirSync ( tempDir , { recursive : true } ) ;
}
return tempDir ;
}
2020-08-27 13:39:07 +01:00
function getToolsDir ( userInput ) {
2020-09-14 10:44:43 +01:00
const toolsDir = userInput || path . join ( os . homedir ( ) , "codeql-runner-tools" ) ;
2020-08-25 16:19:15 +01:00
if ( ! fs . existsSync ( toolsDir ) ) {
fs . mkdirSync ( toolsDir , { recursive : true } ) ;
}
return toolsDir ;
}
2020-09-14 10:44:43 +01:00
const codeqlEnvJsonFilename = "codeql-env.json" ;
2020-08-28 17:22:26 +01:00
// Imports the environment from codeqlEnvJsonFilename if not already present
function importTracerEnvironment ( config ) {
2020-09-14 10:44:43 +01:00
if ( ! ( "ODASA_TRACER_CONFIGURATION" in process . env ) ) {
2020-08-28 17:22:26 +01:00
const jsonEnvFile = path . join ( config . tempDir , codeqlEnvJsonFilename ) ;
2020-09-14 10:44:43 +01:00
const env = JSON . parse ( fs . readFileSync ( jsonEnvFile ) . toString ( "utf-8" ) ) ;
2020-09-20 17:03:01 +08:00
for ( const key of Object . keys ( env ) ) {
process . env [ key ] = env [ key ] ;
}
2020-08-27 14:22:16 +01:00
}
}
2020-09-02 18:00:46 +01:00
// Allow the user to specify refs in full refs/heads/branch format
// or just the short branch name and prepend "refs/heads/" to it.
function parseRef ( userInput ) {
2020-09-14 10:44:43 +01:00
if ( userInput . startsWith ( "refs/" ) ) {
2020-09-02 18:00:46 +01:00
return userInput ;
}
else {
2020-09-14 10:44:43 +01:00
return ` refs/heads/ ${ userInput } ` ;
2020-09-02 18:00:46 +01:00
}
}
2020-09-07 13:36:47 +01:00
// Parses the --trace-process-name arg from process.argv, or returns undefined
function parseTraceProcessName ( ) {
for ( let i = 0 ; i < process . argv . length - 1 ; i ++ ) {
2020-09-14 10:44:43 +01:00
if ( process . argv [ i ] === "--trace-process-name" ) {
2020-09-07 13:36:47 +01:00
return process . argv [ i + 1 ] ;
}
}
return undefined ;
}
// Parses the --trace-process-level arg from process.argv, or returns undefined
function parseTraceProcessLevel ( ) {
for ( let i = 0 ; i < process . argv . length - 1 ; i ++ ) {
2020-09-14 10:44:43 +01:00
if ( process . argv [ i ] === "--trace-process-level" ) {
2020-09-07 13:36:47 +01:00
const v = parseInt ( process . argv [ i + 1 ] , 10 ) ;
return isNaN ( v ) ? undefined : v ;
}
}
return undefined ;
}
2020-08-25 16:19:15 +01:00
program
2020-09-14 10:44:43 +01:00
. command ( "init" )
. description ( "Initializes CodeQL" )
. requiredOption ( "--repository <repository>" , "Repository name. (Required)" )
. requiredOption ( "--github-url <url>" , "URL of GitHub instance. (Required)" )
2021-02-12 14:31:38 -08:00
. option ( "--github-auth <auth>" , "GitHub Apps token or personal access token. This option is insecure and deprecated, please use `--github-auth-stdin` instead." )
. option ( "--github-auth-stdin" , "Read GitHub Apps token or personal access token from stdin." )
2020-09-14 10:44:43 +01:00
. option ( "--languages <languages>" , "Comma-separated list of languages to analyze. Otherwise detects and analyzes all supported languages from the repo." )
. option ( "--queries <queries>" , "Comma-separated list of additional queries to run. This overrides the same setting in a configuration file." )
. option ( "--config-file <file>" , "Path to config file." )
. option ( "--codeql-path <path>" , "Path to a copy of the CodeQL CLI executable to use. Otherwise downloads a copy." )
. option ( "--temp-dir <dir>" , 'Directory to use for temporary files. Default is "./codeql-runner".' )
. option ( "--tools-dir <dir>" , "Directory to use for CodeQL tools and other files to store between runs. Default is a subdirectory of the home directory." )
. option ( "--checkout-path <path>" , "Checkout path. Default is the current working directory." )
. option ( "--debug" , "Print more verbose output" , false )
2021-04-16 11:54:18 -07:00
. option ( "--trace-process-name <string>" , "(Advanced, windows-only) Inject a windows tracer of this process into a process with the given process name." )
. option ( "--trace-process-level <number>" , "(Advanced, windows-only) Inject a windows tracer of this process into a parent process <number> levels up." )
2020-08-25 16:19:15 +01:00
. action ( async ( cmd ) => {
2020-08-27 14:26:44 +01:00
const logger = logging _1 . getRunnerLogger ( cmd . debug ) ;
2020-08-25 16:19:15 +01:00
try {
const tempDir = getTempDir ( cmd . tempDir ) ;
2020-08-27 13:39:07 +01:00
const toolsDir = getToolsDir ( cmd . toolsDir ) ;
2020-08-25 16:19:15 +01:00
// Wipe the temp dir
2020-08-27 16:45:41 +01:00
logger . info ( ` Cleaning temp directory ${ tempDir } ` ) ;
2020-08-25 16:19:15 +01:00
fs . rmdirSync ( tempDir , { recursive : true } ) ;
fs . mkdirSync ( tempDir , { recursive : true } ) ;
2021-02-12 14:31:38 -08:00
const auth = await util _1 . getGitHubAuth ( logger , cmd . githubAuth , cmd . githubAuthStdin ) ;
2020-11-24 11:20:13 +00:00
const apiDetails = {
2021-02-12 14:31:38 -08:00
auth ,
2021-02-17 10:04:02 +00:00
externalRepoAuth : auth ,
2021-02-28 01:55:55 -05:00
url : util _1 . parseGitHubUrl ( cmd . githubUrl ) ,
2020-11-24 11:20:13 +00:00
} ;
2020-11-30 16:33:38 +00:00
const gitHubVersion = await util _1 . getGitHubVersion ( apiDetails ) ;
2021-05-20 15:20:32 -07:00
util _1 . checkGitHubVersionInRange ( gitHubVersion , logger , actions _util _1 . Mode . runner ) ;
2020-08-25 16:19:15 +01:00
let codeql ;
if ( cmd . codeqlPath !== undefined ) {
codeql = codeql _1 . getCodeQL ( cmd . codeqlPath ) ;
}
else {
2021-05-20 15:20:32 -07:00
codeql = ( await init _1 . initCodeQL ( undefined , apiDetails , tempDir , toolsDir , gitHubVersion . type , logger ) ) . codeql ;
2020-08-25 16:19:15 +01:00
}
2021-05-17 10:35:09 +01:00
const config = await init _1 . initConfig ( cmd . languages , cmd . queries , cmd . configFile , undefined , repository _1 . parseRepositoryNwo ( cmd . repository ) , tempDir , toolsDir , codeql , cmd . checkoutPath || process . cwd ( ) , gitHubVersion , apiDetails , logger ) ;
2020-09-07 13:36:47 +01:00
const tracerConfig = await init _1 . runInit ( codeql , config ) ;
2020-08-27 16:34:09 +01:00
if ( tracerConfig === undefined ) {
return ;
}
2020-09-14 10:44:43 +01:00
if ( process . platform === "win32" ) {
2020-09-07 13:36:47 +01:00
await init _1 . injectWindowsTracer ( parseTraceProcessName ( ) , parseTraceProcessLevel ( ) , config , codeql , tracerConfig ) ;
}
2020-11-20 11:35:59 +01:00
// Always output a json file of the env that can be consumed programmatically
2020-08-28 17:22:26 +01:00
const jsonEnvFile = path . join ( config . tempDir , codeqlEnvJsonFilename ) ;
fs . writeFileSync ( jsonEnvFile , JSON . stringify ( tracerConfig . env ) ) ;
2020-09-14 10:44:43 +01:00
if ( process . platform === "win32" ) {
const batEnvFile = path . join ( config . tempDir , "codeql-env.bat" ) ;
2020-08-27 16:34:09 +01:00
const batEnvFileContents = Object . entries ( tracerConfig . env )
. map ( ( [ key , value ] ) => ` Set ${ key } = ${ value } ` )
2020-09-14 10:44:43 +01:00
. join ( "\n" ) ;
2020-08-27 16:34:09 +01:00
fs . writeFileSync ( batEnvFile , batEnvFileContents ) ;
2020-09-14 10:44:43 +01:00
const powershellEnvFile = path . join ( config . tempDir , "codeql-env.sh" ) ;
2020-08-27 16:34:09 +01:00
const powershellEnvFileContents = Object . entries ( tracerConfig . env )
. map ( ( [ key , value ] ) => ` $ env: ${ key } =" ${ value } " ` )
2020-09-14 10:44:43 +01:00
. join ( "\n" ) ;
2020-08-27 16:34:09 +01:00
fs . writeFileSync ( powershellEnvFile , powershellEnvFileContents ) ;
2020-09-02 19:58:03 +01:00
logger . info ( ` \n CodeQL environment output to " ${ jsonEnvFile } ", " ${ batEnvFile } " and " ${ powershellEnvFile } ". ` +
2020-11-13 15:04:54 +00:00
` Please export these variables to future processes so that CodeQL can monitor the build. ` +
2020-09-02 19:58:03 +01:00
` If using cmd/batch run "call ${ batEnvFile } " ` +
2020-08-27 16:34:09 +01:00
` or if using PowerShell run "cat ${ powershellEnvFile } | Invoke-Expression". ` ) ;
}
else {
// Assume that anything that's not windows is using a unix-style shell
2020-09-14 10:44:43 +01:00
const shEnvFile = path . join ( config . tempDir , "codeql-env.sh" ) ;
2020-08-28 17:22:26 +01:00
const shEnvFileContents = Object . entries ( tracerConfig . env )
2020-08-27 16:34:09 +01:00
// Some vars contain ${LIB} that we do not want to be expanded when executing this script
2021-05-05 19:57:44 +02:00
. map ( ( [ key , value ] ) => ` export ${ key } =' ${ value . replace ( /'/g , "'\"'\"'" ) } ' ` )
2020-09-14 10:44:43 +01:00
. join ( "\n" ) ;
2020-08-28 17:22:26 +01:00
fs . writeFileSync ( shEnvFile , shEnvFileContents ) ;
logger . info ( ` \n CodeQL environment output to " ${ jsonEnvFile } " and " ${ shEnvFile } ". ` +
2020-11-13 15:04:54 +00:00
` Please export these variables to future processes so that CodeQL can monitor the build, ` +
2020-08-28 17:22:26 +01:00
` for example by running ". ${ shEnvFile } ". ` ) ;
2020-08-26 13:20:46 +01:00
}
2020-08-25 16:19:15 +01:00
}
catch ( e ) {
2020-09-14 10:44:43 +01:00
logger . error ( "Init failed" ) ;
2020-08-25 16:19:15 +01:00
logger . error ( e ) ;
process . exitCode = 1 ;
}
} ) ;
program
2020-09-14 10:44:43 +01:00
. command ( "autobuild" )
. description ( "Attempts to automatically build code" )
. option ( "--language <language>" , "The language to build. Otherwise will detect the dominant compiled language." )
. option ( "--temp-dir <dir>" , 'Directory to use for temporary files. Default is "./codeql-runner".' )
. option ( "--debug" , "Print more verbose output" , false )
2020-08-25 16:19:15 +01:00
. action ( async ( cmd ) => {
2020-08-27 14:26:44 +01:00
const logger = logging _1 . getRunnerLogger ( cmd . debug ) ;
2020-08-25 16:19:15 +01:00
try {
2020-08-27 14:04:09 +01:00
const config = await config _utils _1 . getConfig ( getTempDir ( cmd . tempDir ) , logger ) ;
2020-08-28 09:43:25 +01:00
if ( config === undefined ) {
throw new Error ( "Config file could not be found at expected location. " +
"Was the 'init' command run with the same '--temp-dir' argument as this command." ) ;
}
2020-08-28 17:22:26 +01:00
importTracerEnvironment ( config ) ;
2020-08-27 14:04:09 +01:00
let language = undefined ;
if ( cmd . language !== undefined ) {
language = languages _1 . parseLanguage ( cmd . language ) ;
if ( language === undefined || ! config . languages . includes ( language ) ) {
throw new Error ( ` " ${ cmd . language } " is not a recognised language. ` +
2020-09-14 10:44:43 +01:00
` Known languages in this project are ${ config . languages . join ( ", " ) } . ` ) ;
2020-08-27 14:04:09 +01:00
}
}
else {
language = autobuild _1 . determineAutobuildLanguage ( config , logger ) ;
}
if ( language !== undefined ) {
await autobuild _1 . runAutobuild ( language , config , logger ) ;
2020-08-25 16:19:15 +01:00
}
}
catch ( e ) {
2020-09-14 10:44:43 +01:00
logger . error ( "Autobuild failed" ) ;
2020-08-25 16:19:15 +01:00
logger . error ( e ) ;
process . exitCode = 1 ;
}
} ) ;
program
2020-09-14 10:44:43 +01:00
. command ( "analyze" )
. description ( "Finishes extracting code and runs CodeQL queries" )
. requiredOption ( "--repository <repository>" , "Repository name. (Required)" )
. requiredOption ( "--commit <commit>" , "SHA of commit that was analyzed. (Required)" )
. requiredOption ( "--ref <ref>" , "Name of ref that was analyzed. (Required)" )
. requiredOption ( "--github-url <url>" , "URL of GitHub instance. (Required)" )
2021-02-12 14:31:38 -08:00
. option ( "--github-auth <auth>" , "GitHub Apps token or personal access token. This option is insecure and deprecated, please use `--github-auth-stdin` instead." )
. option ( "--github-auth-stdin" , "Read GitHub Apps token or personal access token from stdin." )
2020-09-14 10:44:43 +01:00
. option ( "--checkout-path <path>" , "Checkout path. Default is the current working directory." )
. option ( "--no-upload" , "Do not upload results after analysis." )
. option ( "--output-dir <dir>" , "Directory to output SARIF files to. Default is in the temp directory." )
. option ( "--ram <ram>" , "Amount of memory to use when running queries. Default is to use all available memory." )
. option ( "--no-add-snippets" , "Specify whether to include code snippets in the sarif output." )
. option ( "--threads <threads>" , "Number of threads to use when running queries. " +
"Default is to use all available cores." )
. option ( "--temp-dir <dir>" , 'Directory to use for temporary files. Default is "./codeql-runner".' )
2021-04-29 14:59:36 +02:00
. option ( "--category <category>" , "String used by Code Scanning for matching the analyses." )
2020-09-14 10:44:43 +01:00
. option ( "--debug" , "Print more verbose output" , false )
2020-08-25 16:19:15 +01:00
. action ( async ( cmd ) => {
2020-08-27 14:26:44 +01:00
const logger = logging _1 . getRunnerLogger ( cmd . debug ) ;
2020-08-25 16:19:15 +01:00
try {
2020-08-27 14:04:09 +01:00
const config = await config _utils _1 . getConfig ( getTempDir ( cmd . tempDir ) , logger ) ;
2020-08-28 09:43:25 +01:00
if ( config === undefined ) {
throw new Error ( "Config file could not be found at expected location. " +
"Was the 'init' command run with the same '--temp-dir' argument as this command." ) ;
}
2021-02-12 14:31:38 -08:00
const auth = await util _1 . getGitHubAuth ( logger , cmd . githubAuth , cmd . githubAuthStdin ) ;
2020-11-24 11:20:13 +00:00
const apiDetails = {
2021-02-12 14:31:38 -08:00
auth ,
2021-02-28 01:55:55 -05:00
url : util _1 . parseGitHubUrl ( cmd . githubUrl ) ,
2020-11-24 11:20:13 +00:00
} ;
2021-03-16 13:14:17 +00:00
const outputDir = cmd . outputDir || path . join ( config . tempDir , "codeql-sarif" ) ;
2021-05-03 19:58:30 +02:00
await analyze _1 . runAnalyze ( outputDir , util _1 . getMemoryFlag ( cmd . ram ) , util _1 . getAddSnippetsFlag ( cmd . addSnippets ) , util _1 . getThreadsFlag ( cmd . threads , logger ) , cmd . category , config , logger ) ;
2020-11-27 12:23:06 +00:00
if ( ! cmd . upload ) {
logger . info ( "Not uploading results" ) ;
return ;
}
2021-04-29 14:59:36 +02:00
await upload _lib . uploadFromRunner ( outputDir , repository _1 . parseRepositoryNwo ( cmd . repository ) , cmd . commit , parseRef ( cmd . ref ) , cmd . category , cmd . checkoutPath || process . cwd ( ) , config . gitHubVersion , apiDetails , logger ) ;
2020-08-25 16:19:15 +01:00
}
catch ( e ) {
2020-09-14 10:44:43 +01:00
logger . error ( "Analyze failed" ) ;
2020-08-25 16:19:15 +01:00
logger . error ( e ) ;
process . exitCode = 1 ;
}
} ) ;
2020-08-11 12:43:27 +01:00
program
2020-09-14 10:44:43 +01:00
. command ( "upload" )
. description ( "Uploads a SARIF file, or all SARIF files from a directory, to code scanning" )
. requiredOption ( "--sarif-file <file>" , "SARIF file to upload, or a directory containing multiple SARIF files. (Required)" )
. requiredOption ( "--repository <repository>" , "Repository name. (Required)" )
. requiredOption ( "--commit <commit>" , "SHA of commit that was analyzed. (Required)" )
. requiredOption ( "--ref <ref>" , "Name of ref that was analyzed. (Required)" )
. requiredOption ( "--github-url <url>" , "URL of GitHub instance. (Required)" )
2021-02-12 14:31:38 -08:00
. option ( "--github-auth <auth>" , "GitHub Apps token or personal access token. This option is insecure and deprecated, please use `--github-auth-stdin` instead." )
. option ( "--github-auth-stdin" , "Read GitHub Apps token or personal access token from stdin." )
2020-09-14 10:44:43 +01:00
. option ( "--checkout-path <path>" , "Checkout path. Default is the current working directory." )
2021-04-29 14:59:36 +02:00
. option ( "--category <category>" , "String used by Code Scanning for matching the analyses." )
2020-09-14 10:44:43 +01:00
. option ( "--debug" , "Print more verbose output" , false )
2020-08-11 12:43:27 +01:00
. action ( async ( cmd ) => {
2020-08-27 14:26:44 +01:00
const logger = logging _1 . getRunnerLogger ( cmd . debug ) ;
2021-02-12 14:31:38 -08:00
const auth = await util _1 . getGitHubAuth ( logger , cmd . githubAuth , cmd . githubAuthStdin ) ;
2020-11-24 11:20:13 +00:00
const apiDetails = {
2021-02-12 14:31:38 -08:00
auth ,
2021-02-28 01:55:55 -05:00
url : util _1 . parseGitHubUrl ( cmd . githubUrl ) ,
2020-11-24 11:20:13 +00:00
} ;
2020-08-11 12:43:27 +01:00
try {
2021-01-06 11:06:01 +00:00
const gitHubVersion = await util _1 . getGitHubVersion ( apiDetails ) ;
2021-04-29 14:59:36 +02:00
await upload _lib . uploadFromRunner ( cmd . sarifFile , repository _1 . parseRepositoryNwo ( cmd . repository ) , cmd . commit , parseRef ( cmd . ref ) , cmd . category , cmd . checkoutPath || process . cwd ( ) , gitHubVersion , apiDetails , logger ) ;
2020-08-11 12:43:27 +01:00
}
catch ( e ) {
2020-09-14 10:44:43 +01:00
logger . error ( "Upload failed" ) ;
2020-08-11 12:43:27 +01:00
logger . error ( e ) ;
2020-08-12 18:00:01 +01:00
process . exitCode = 1 ;
2020-08-11 12:43:27 +01:00
}
} ) ;
program . parse ( process . argv ) ;
2020-08-24 14:21:03 +01:00
//# sourceMappingURL=runner.js.map