Run the `scanners` Scanner objects on the `codebase` Codebase. Return True on success or False otherwise. Use multiprocessing with `processes` number of processes defaulting to single process. Disable multiprocessing with processes 0 or -1. Disable threading is processes is -1.
(
codebase,
scanners,
processes=1,
timeout=DEFAULT_TIMEOUT,
with_timing=False,
progress_manager=None,
echo_func=echo_stderr,
)
| 1252 | |
| 1253 | |
| 1254 | def scan_codebase( |
| 1255 | codebase, |
| 1256 | scanners, |
| 1257 | processes=1, |
| 1258 | timeout=DEFAULT_TIMEOUT, |
| 1259 | with_timing=False, |
| 1260 | progress_manager=None, |
| 1261 | echo_func=echo_stderr, |
| 1262 | ): |
| 1263 | """ |
| 1264 | Run the `scanners` Scanner objects on the `codebase` Codebase. Return True |
| 1265 | on success or False otherwise. |
| 1266 | |
| 1267 | Use multiprocessing with `processes` number of processes defaulting to |
| 1268 | single process. Disable multiprocessing with processes 0 or -1. Disable |
| 1269 | threading is processes is -1. |
| 1270 | |
| 1271 | Run each scanner function for up to `timeout` seconds and fail it otherwise. |
| 1272 | |
| 1273 | If `with_timing` is True, each Resource is updated with per-scanner |
| 1274 | execution time (as a float in seconds). This is added to the `scan_timings` |
| 1275 | mapping of each Resource as {scanner.name: execution time}. |
| 1276 | |
| 1277 | Provide optional progress feedback in the UI using the ``progress_manager`` |
| 1278 | callable that accepts an iterable of tuple of (location, path, scan_errors, |
| 1279 | scan_result) as argument. |
| 1280 | """ |
| 1281 | |
| 1282 | # NOTE: we never scan directories |
| 1283 | resources = ((r.location, r.path) for r in codebase.walk() if r.is_file) |
| 1284 | |
| 1285 | use_threading = processes >= 0 |
| 1286 | runner = partial( |
| 1287 | scan_resource, |
| 1288 | scanners=scanners, |
| 1289 | timeout=timeout, |
| 1290 | with_timing=with_timing, |
| 1291 | with_threading=use_threading |
| 1292 | ) |
| 1293 | |
| 1294 | if TRACE: |
| 1295 | logger_debug('scan_codebase: scanners:', ', '.join(s.name for s in scanners)) |
| 1296 | |
| 1297 | get_resource = codebase.get_resource |
| 1298 | |
| 1299 | success = True |
| 1300 | pool = None |
| 1301 | scans = None |
| 1302 | try: |
| 1303 | if processes >= 1: |
| 1304 | # maxtasksperchild helps with recycling processes in case of leaks |
| 1305 | pool = get_pool(processes=processes, maxtasksperchild=1000) |
| 1306 | # Using chunksize is documented as much more efficient in the Python |
| 1307 | # doc. Yet "1" still provides a better and more progressive |
| 1308 | # feedback. With imap_unordered, results are returned as soon as |
| 1309 | # ready and out of order so we never know exactly what is processing |
| 1310 | # until completed. |
| 1311 | scans = pool.imap_unordered(runner, resources, chunksize=1) |
no test coverage detected