1515from pathlib import Path
1616from typing import Any , Literal , Union
1717
18- import git
1918from rich import print
2019from rich .panel import Panel
2120from rich .progress import Progress
@@ -123,9 +122,15 @@ def run_analysis(
123122 render_variables [to_replace ] = v
124123 elif isinstance (v , Path ):
125124 render_variables [to_replace ] = str (v .resolve ())
125+ elif isinstance (v , list ):
126+ render_variables [to_replace ] = v
126127 else :
127128 raise NotImplementedError (k , v )
128129
130+ # Make temporary directory available to command
131+ temp_dir = tempfile .TemporaryDirectory ()
132+ render_variables ["{tempdir}" ] = temp_dir .name
133+
129134 with Progress () as progress :
130135 progress .add_task (
131136 f"[b][{ self .name } ][/b] analyzing: [i]{ project_dir .name } [/i]" ,
@@ -165,7 +170,7 @@ def save_results(self, project_dir: Path, output_dir: Path, extra: dict) -> None
165170
166171 """
167172 output_dir .mkdir (exist_ok = True , parents = True )
168- json .dump (extra , (output_dir / "cstools_output.json" ).open ("w" ))
173+ json .dump (extra , (output_dir / "cstools_output.json" ).open ("w" ), indent = 4 )
169174
170175 missing_files = []
171176 for path_from_root , required in self .output_files :
@@ -175,7 +180,7 @@ def save_results(self, project_dir: Path, output_dir: Path, extra: dict) -> None
175180 filepath = project_dir / parent_dir / filename
176181 if filepath .is_file ():
177182 if not filepath == output_dir / filename :
178- shutil . copy2 ( filepath , output_dir / filename )
183+ filepath . rename ( output_dir / filename )
179184 else :
180185 if required :
181186 missing_files .append (filename )
@@ -184,7 +189,7 @@ def save_results(self, project_dir: Path, output_dir: Path, extra: dict) -> None
184189 if filepaths :
185190 for filepath in filepaths :
186191 if not filepath == output_dir / filename :
187- shutil . copy2 ( filepath , output_dir / filepath .name )
192+ filepath . rename ( output_dir / filepath .name )
188193 else :
189194 if required :
190195 missing_files .append (filename )
@@ -218,25 +223,7 @@ def analyze_files(
218223 )
219224 return
220225
221- # Create temporary directory for the project
222- temp_dir = tempfile .TemporaryDirectory ()
223- temp_path = Path (temp_dir .name )
224-
225- # Copy files into the temporary directory
226- if testing :
227- random .seed (os .environ .get ("CONSTANT_RANDOM" , os .urandom (16 )))
228- files = random .sample (dataset .files , k = 2 )
229- else :
230- files = dataset .files
231-
232- for file in files :
233- file .save (temp_path )
234-
235- # Run analysis
236- self .run_analysis (dataset .lang , temp_path , result_path )
237-
238- # Clear temporary directory
239- temp_dir .cleanup ()
226+ self .run_analysis (dataset .lang , dataset .directory , result_path )
240227
241228 def analyze_repos (
242229 self , dataset : GitRepoDataset , overwrite : bool = False , testing : bool = False
@@ -252,8 +239,8 @@ def analyze_repos(
252239 testing: If True, run analysis on a sample of two small random repositories for testing purposes.
253240
254241 """
255- base_result_path = self .output_dir / dataset .full_name
256- base_result_path .mkdir (exist_ok = True , parents = True )
242+ result_path = self .output_dir / dataset .full_name
243+ result_path .mkdir (exist_ok = True , parents = True )
257244
258245 if testing :
259246 random .seed (os .environ .get ("CONSTANT_RANDOM" , os .urandom (16 )))
@@ -263,27 +250,22 @@ def analyze_repos(
263250 repos = dataset .repos
264251
265252 for repo in repos :
266- result_path = base_result_path / repo .name
267- if result_path .is_dir ():
268- if list (result_path .iterdir ()) and not overwrite :
253+ repo_result_path = result_path / repo .name
254+ if repo_result_path .is_dir ():
255+ if list (repo_result_path .iterdir ()) and not overwrite :
269256 print (f"Results already exist for { repo .name } , skipping..." )
270257 print ("Please use --overwrite to analyze again" )
258+ continue
271259
272- # Create temporary directory for the project
273- temp_dir = tempfile .TemporaryDirectory ()
274- repo_path = Path (temp_dir .name )
260+ repo_source_path = dataset .directory / repo .name
275261
276- # Clone and checkout to the vulnerable commit
277- try :
278- repo .save (repo_path )
279- except git .GitCommandError :
280- continue
262+ if repo_source_path .is_dir ():
263+ shutil .rmtree (repo_source_path )
281264
282- # Run analysis
283- self . run_analysis ( dataset . lang , repo_path , result_path )
265+ repo_source_path . mkdir ()
266+ repo . save ( repo_source_path )
284267
285- # Clear temporary directory
286- temp_dir .cleanup ()
268+ self .run_analysis (dataset .lang , repo_source_path , repo_result_path )
287269
288270 @property
289271 def supported_dataset_full_names (self ) -> list [str ]:
@@ -399,28 +381,13 @@ def analyze_files(
399381 )
400382 return
401383
402- # Create temporary directory for the project
403- temp_dir = tempfile .TemporaryDirectory ()
404- temp_path = Path (temp_dir .name )
405-
406- # Copy files into the temporary directory
407- if testing :
408- random .seed (os .environ .get ("CONSTANT_RANDOM" , os .urandom (16 )))
409- prebuilt_files = random .sample (dataset .list_prebuilt_files (), k = 2 )
410- else :
411- prebuilt_files = dataset .list_prebuilt_files ()
412-
413- for prebuilt_file in prebuilt_files :
414- shutil .copy2 (prebuilt_file , temp_path / prebuilt_file .name )
415-
416- # Run analysis
417384 self .run_analysis (
418- dataset .lang , dataset .directory , result_path , artifacts = temp_path
385+ dataset .lang ,
386+ dataset .directory ,
387+ result_path ,
388+ artifacts = dataset .artefacts_arg ,
419389 )
420390
421- # Clear temporary directory
422- temp_dir .cleanup ()
423-
424391
425392class PrebuiltBuildlessSAST (PrebuiltSAST , BuildlessSAST ):
426393 """Represent a SAST tool that can analyze both source code and pre-built artifacts."""
0 commit comments