From c31780f62f8d0369dc4294a5ff1d815c24f8aa82 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Thu, 18 Nov 2021 18:18:35 +0100 Subject: [PATCH] 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 --- scripts/min_requirements.py | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/scripts/min_requirements.py b/scripts/min_requirements.py index 3b156a36a..ef6c42bf6 100755 --- a/scripts/min_requirements.py +++ b/scripts/min_requirements.py @@ -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: