88import json
99import glob
1010import shlex
11+ import shutil
12+ import tempfile
1113from shutil import copyfile
1214
1315
1416def print_usage (exit_code = 1 ):
15- print ("Usage: makeStubs.py testDir stubDir\n " ,
17+ print ("Usage: makeStubs.py testDir stubDir [pom.xml] \n " ,
1618 "testDir: the directory containing the qltest to be stubbed.\n "
17- " Should contain an `options0` file pointing to the jars to stub, and an `options1` file pointing to `stubdir`.\n "
18- " These files should be in the same format as a normal `options` file.\n " ,
19- "stubDir: the directory to output the generated stubs to" )
19+ " Should contain an 'options' file pointing to 'stubdir'.\n "
20+ " These files should be in the same format as a normal 'options' file.\n " ,
21+ "stubDir: the directory to output the generated stubs to\n " ,
22+ "pom.xml: a 'pom.xml' file that can be used to build the project\n " ,
23+ " If the test can be extracted without a 'pom.xml', this argument can be ommitted." )
2024 exit (exit_code )
2125
2226
2327if "--help" in sys .argv or "-h" in sys .argv :
2428 print_usage (0 )
2529
26- if len (sys .argv ) != 3 :
30+ if len (sys .argv ) not in [ 3 , 4 ] :
2731 print_usage ()
2832
2933testDir = sys .argv [1 ].rstrip ("/" )
3034stubDir = sys .argv [2 ].rstrip ("/" )
3135
32-
3336def check_dir_exists (path ):
3437 if not os .path .isdir (path ):
3538 print (path , "does not exist or is not a directory" )
@@ -46,11 +49,8 @@ def check_file_exists(path):
4649check_dir_exists (stubDir )
4750
4851optionsFile = os .path .join (testDir , "options" )
49- options0File = os .path .join (testDir , "options0" )
50- options1File = os .path .join (testDir , "options1" )
5152
52- check_file_exists (options0File )
53- check_file_exists (options1File )
53+ check_file_exists (optionsFile )
5454
5555# Does it contain a .ql file and a .java file?
5656
@@ -67,12 +67,33 @@ def check_file_exists(path):
6767 exit (1 )
6868
6969
70+ workDir = tempfile .TemporaryDirectory ().name
71+
72+ print ("Created temporary directory '%s'" % workDir )
73+
7074javaQueries = os .path .abspath (os .path .dirname (sys .argv [0 ]))
71- outputBqrsFile = os .path .join (testDir , 'output.bqrs' )
72- outputJsonFile = os .path .join (testDir , 'output.json' )
75+ outputBqrsFile = os .path .join (workDir , 'output.bqrs' )
76+ outputJsonFile = os .path .join (workDir , 'output.json' )
77+
78+ # Make a database that touches all types whose methods we want to test:
79+ print ("Creating Maven project" )
80+ projectDir = os .path .join (workDir , "mavenProject" )
81+ os .makedirs (projectDir )
7382
74- dbDir = os .path .join (testDir , os .path .basename (testDir ) + ".testproj" )
83+ if len (sys .argv ) == 4 :
84+ projectTestPkgDir = os .path .join (projectDir , "src" , "main" , "java" , "test" )
85+ shutil .copytree (testDir , projectTestPkgDir , ignore = shutil .ignore_patterns ('*.testproj' ))
7586
87+ try :
88+ shutil .copyfile (sys .argv [3 ], os .path .join (projectDir , "pom.xml" ))
89+ except Exception as e :
90+ print ("Failed to read project POM %s: %s" % (sys .argv [2 ], e ), file = sys .stderr )
91+ sys .exit (1 )
92+ else :
93+ # if `pom.xml` is omitted, simply copy the test directory to `projectDir`
94+ shutil .copytree (testDir , projectDir , ignore = shutil .ignore_patterns ('*.testproj' ))
95+
96+ dbDir = os .path .join (workDir , "db" )
7697
7798def print_javac_output ():
7899 logFiles = glob .glob (os .path .join (dbDir , "log" , "javac-output*" ))
@@ -98,11 +119,9 @@ def run(cmd):
98119
99120print ("Stubbing qltest in" , testDir )
100121
101- copyfile (options0File , optionsFile )
102-
103- if run (['codeql' , 'test' , 'run' , '--keep-databases' , testDir ]):
122+ if run (['codeql' , 'database' , 'create' , '--language=java' , '--source-root=' + projectDir , dbDir ]):
104123 print_javac_output ()
105- print ("codeql test failed. Please fix up the test before proceeding." )
124+ print ("codeql database create failed. Please fix up the test before proceeding." )
106125 exit (1 )
107126
108127if not os .path .isdir (dbDir ):
@@ -143,13 +162,13 @@ def run(cmd):
143162
144163print ("Verifying stub correctness" )
145164
146- copyfile (options1File , optionsFile )
147-
148165if run (['codeql' , 'test' , 'run' , testDir ]):
149166 print_javac_output ()
150167 print ('\n Test failed. You may need to fix up the generated stubs.' )
151168 exit (1 )
152169
170+ os .rmdir (workDir )
171+
153172print ("\n Stub generation successful!" )
154173
155174exit (0 )
0 commit comments