Runs Python command inside venv and returns termination code. Args: args: List of args or string command. path: Path of venv directory. recreate: If false we do not run ` -m venv ` if a
(args, path, recreate=True, clean=False)
| 3524 | |
| 3525 | |
| 3526 | def venv_run(args, path, recreate=True, clean=False): |
| 3527 | ''' |
| 3528 | Runs Python command inside venv and returns termination code. |
| 3529 | |
| 3530 | Args: |
| 3531 | args: |
| 3532 | List of args or string command. |
| 3533 | path: |
| 3534 | Path of venv directory. |
| 3535 | recreate: |
| 3536 | If false we do not run `<sys.executable> -m venv <path>` if <path> |
| 3537 | already exists. This avoids a delay in the common case where <path> |
| 3538 | is already set up, but fails if <path> exists but does not contain |
| 3539 | a valid venv. |
| 3540 | clean: |
| 3541 | If true we first delete <path>. |
| 3542 | ''' |
| 3543 | if clean: |
| 3544 | log(f'Removing any existing venv {path}.') |
| 3545 | assert path.startswith('venv-') |
| 3546 | shutil.rmtree(path, ignore_errors=1) |
| 3547 | if recreate or not os.path.isdir(path): |
| 3548 | run(f'{sys.executable} -m venv {path}') |
| 3549 | |
| 3550 | if isinstance(args, str): |
| 3551 | args_string = args |
| 3552 | elif platform.system() == 'Windows': |
| 3553 | # shlex not reliable on Windows so we use Use crude quoting with "...". |
| 3554 | args_string = '' |
| 3555 | for i, arg in enumerate(args): |
| 3556 | assert '"' not in arg |
| 3557 | if i: |
| 3558 | args_string += ' ' |
| 3559 | args_string += f'"{arg}"' |
| 3560 | else: |
| 3561 | args_string = shlex.join(args) |
| 3562 | |
| 3563 | if platform.system() == 'Windows': |
| 3564 | command = f'{path}\\Scripts\\activate && python {args_string}' |
| 3565 | else: |
| 3566 | command = f'. {path}/bin/activate && python {args_string}' |
| 3567 | e = run(command, check=0) |
| 3568 | return e |
| 3569 | |
| 3570 | |
| 3571 | if __name__ == '__main__': |