Use a method to invoke pip that works on Windows

Passing arguments on the command line apparently didn't work due to quoting
issues. Use a temporary file instead.

Signed-off-by: Gilles Peskine <Gilles.Peskine@arm.com>
This commit is contained in:
Gilles Peskine 2021-11-18 18:18:35 +01:00
parent 6d253cc4fc
commit c31780f62f

View file

@ -20,7 +20,9 @@
import argparse
import os
import re
import subprocess
import sys
import tempfile
import typing
from typing import List
@ -74,12 +76,18 @@ class Requirements:
def install(self) -> None:
"""Call pip to install the requirements."""
if not self.requirements:
return
ret = os.spawnl(os.P_WAIT, sys.executable, 'python', '-m', 'pip',
'install', *self.requirements)
if ret != 0:
sys.exit(ret)
with tempfile.TemporaryDirectory() as temp_dir:
# This is more complicated than it needs to be for the sake
# of Windows. Use a temporary file rather than the command line
# to avoid quoting issues. Use a temporary directory rather
# than NamedTemporaryFile because with a NamedTemporaryFile on
# Windows, the subprocess can't open the file because this process
# has an exclusive lock on it.
req_file_name = os.path.join(temp_dir, 'requirements.txt')
with open(req_file_name, 'w') as req_file:
self.write(req_file)
subprocess.check_call([sys.executable, '-m', 'pip',
'install', '-r', req_file_name])
def main() -> None: