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 argparse
import os import os
import re import re
import subprocess
import sys import sys
import tempfile
import typing import typing
from typing import List from typing import List
@ -74,12 +76,18 @@ class Requirements:
def install(self) -> None: def install(self) -> None:
"""Call pip to install the requirements.""" """Call pip to install the requirements."""
if not self.requirements: with tempfile.TemporaryDirectory() as temp_dir:
return # This is more complicated than it needs to be for the sake
ret = os.spawnl(os.P_WAIT, sys.executable, 'python', '-m', 'pip', # of Windows. Use a temporary file rather than the command line
'install', *self.requirements) # to avoid quoting issues. Use a temporary directory rather
if ret != 0: # than NamedTemporaryFile because with a NamedTemporaryFile on
sys.exit(ret) # 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: def main() -> None: