11import * as child_process from "child_process" ;
22import * as path from "path" ;
33import * as os from "os" ;
4+ import * as fs from "fs" ;
45
56function invoke (
67 invocation : string [ ] ,
@@ -28,65 +29,68 @@ type Args = {
2829 tests : string [ ] ;
2930 flags : string [ ] ;
3031 env : string [ ] ;
31- build : boolean ;
32- testing_level : number ;
32+ codeql : string ;
33+ all : boolean ;
3334} ;
3435
3536function parseArgs ( args : Args , argv : string ) {
36- argv . split ( / (?< ! \\ ) / ) . forEach ( ( arg ) => {
37- if ( arg === "--no-build" ) {
38- args . build = false ;
39- } else if ( arg . startsWith ( "-" ) ) {
40- args . flags . push ( arg ) ;
41- } else if ( / ^ [ A - Z _ ] [ A - Z _ 0 - 9 ] * = .* $ / . test ( arg ) ) {
42- args . env . push ( arg ) ;
43- } else if ( / ^ \+ + $ / . test ( arg ) ) {
44- args . testing_level = Math . max ( args . testing_level , arg . length ) ;
45- } else if ( arg !== "" ) {
46- args . tests . push ( arg ) ;
47- }
48- } ) ;
37+ argv . split ( / (?< ! \\ ) / )
38+ . map ( ( arg ) => arg . replace ( "\\ " , " " ) )
39+ . forEach ( ( arg ) => {
40+ if ( arg . startsWith ( "--codeql=" ) ) {
41+ args . codeql = arg . split ( "=" ) [ 1 ] ;
42+ } else if ( arg === "+" || arg === "--all-checks" ) {
43+ args . all = true ;
44+ } else if ( arg . startsWith ( "-" ) ) {
45+ args . flags . push ( arg ) ;
46+ } else if ( / ^ [ A - Z _ ] [ A - Z _ 0 - 9 ] * = .* $ / . test ( arg ) ) {
47+ args . env . push ( arg ) ;
48+ } else if ( arg !== "" ) {
49+ args . tests . push ( arg ) ;
50+ }
51+ } ) ;
4952}
5053
5154function codeqlTestRun ( argv : string [ ] ) : number {
52- const [ language , extra_args , ...plus ] = argv ;
53- let codeql = process . env [ "SEMMLE_CODE" ]
54- ? path . join (
55- process . env [ "SEMMLE_CODE" ] ,
56- "target" ,
57- "intree" ,
58- `codeql-${ language } ` ,
59- "codeql" ,
60- )
61- : "codeql" ;
55+ const semmle_code = process . env [ "SEMMLE_CODE" ] ;
56+ const [ language , base_args , all_args , extra_args ] = argv ;
6257 const ram_per_thread = process . platform === "linux" ? 3000 : 2048 ;
6358 const cpus = os . cpus ( ) . length ;
6459 let args : Args = {
6560 tests : [ ] ,
6661 flags : [ `--ram=${ ram_per_thread * cpus } ` , `-j${ cpus } ` ] ,
6762 env : [ ] ,
68- build : true ,
69- testing_level : 0 ,
63+ codeql : semmle_code ? " build" : "host" ,
64+ all : false ,
7065 } ;
66+ parseArgs ( args , base_args ) ;
7167 parseArgs ( args , extra_args ) ;
72- for ( let i = 0 ; i < Math . min ( plus . length , args . testing_level ) ; i ++ ) {
73- parseArgs ( args , plus [ i ] ) ;
68+ if ( args . all ) {
69+ parseArgs ( args , all_args ) ;
70+ }
71+ if ( ! semmle_code && ( args . codeql === "build" || args . codeql === "built" ) ) {
72+ console . error (
73+ "Using `--codeql=build` or `--codeql=built` requires working with the internal repository" ,
74+ ) ;
75+ return 1 ;
7476 }
7577 if ( args . tests . length === 0 ) {
7678 args . tests . push ( "." ) ;
7779 }
78- if ( args . build && process . env [ "SEMMLE_CODE" ] ) {
79- // If SEMMLE_CODE is set, we are in the semmle-code repo, so we build the codeql binary.
80- // Otherwise, we use codeql from PATH.
80+ if ( args . codeql === "build" ) {
8181 if (
8282 invoke ( [ "python3" , "build" , `target/intree/codeql-${ language } ` ] , {
83- cwd : process . env [ "SEMMLE_CODE" ] ,
83+ cwd : semmle_code ,
8484 } ) !== 0
8585 ) {
8686 return 1 ;
8787 }
8888 }
89- process . env [ "CODEQL_CONFIG_FILE" ] ||= "." ; // disable the default implicit config file, but keep an explicit one
89+ if ( args . codeql !== "host" ) {
90+ // disable the default implicit config file, but keep an explicit one
91+ // this is the same behavior wrt to `--codeql` as the integration test runner
92+ process . env [ "CODEQL_CONFIG_FILE" ] ||= "." ;
93+ }
9094 // Set and unset environment variables
9195 args . env . forEach ( ( envVar ) => {
9296 const [ key , value ] = envVar . split ( "=" , 2 ) ;
@@ -101,6 +105,31 @@ function codeqlTestRun(argv: string[]): number {
101105 process . exit ( 1 ) ;
102106 }
103107 } ) ;
108+ let codeql ;
109+ if ( args . codeql === "built" || args . codeql === "build" ) {
110+ codeql = path . join (
111+ semmle_code ! ,
112+ "target" ,
113+ "intree" ,
114+ `codeql-${ language } ` ,
115+ "codeql" ,
116+ ) ;
117+ } else if ( args . codeql === "host" ) {
118+ codeql = "codeql" ;
119+ } else {
120+ codeql = args . codeql ;
121+ if ( fs . lstatSync ( codeql ) . isDirectory ( ) ) {
122+ codeql = path . join ( codeql , "codeql" ) ;
123+ if ( process . platform === "win32" ) {
124+ codeql += ".exe" ;
125+ }
126+ }
127+ if ( ! fs . existsSync ( codeql ) ) {
128+ console . error ( `CodeQL executable not found: ${ codeql } ` ) ;
129+ return 1 ;
130+ }
131+ }
132+
104133 return invoke ( [ codeql , "test" , "run" , ...args . flags , "--" , ...args . tests ] , {
105134 log_prefix : args . env . join ( " " ) ,
106135 } ) ;
0 commit comments