From dd4d333c28173523cd675ec3847de84487ef1035 Mon Sep 17 00:00:00 2001 From: Kian Date: Sat, 27 Apr 2024 09:36:07 -0700 Subject: [PATCH] Fix build errors --- sync/sync-etc | 4 +- vendor/venv-update | 116 +++++++++++++++++++++++++-------------------- 2 files changed, 66 insertions(+), 54 deletions(-) diff --git a/sync/sync-etc b/sync/sync-etc index 3986cff..319aa77 100755 --- a/sync/sync-etc +++ b/sync/sync-etc @@ -1,12 +1,12 @@ #!/usr/bin/env python3 - import argparse import logging import os import shutil import time from pathlib import Path -from subprocess import CalledProcessError, check_call +from subprocess import CalledProcessError +from subprocess import check_call def get_cache_dir() -> Path: diff --git a/vendor/venv-update b/vendor/venv-update index 5bfde27..fe93f36 100755 --- a/vendor/venv-update +++ b/vendor/venv-update @@ -71,7 +71,7 @@ from subprocess import CalledProcessError # To fix this we just delete the environment variable. os.environ.pop('__PYVENV_LAUNCHER__', None) -__version__ = '3.2.4' +__version__ = '4.0.0' DEFAULT_VIRTUALENV_PATH = 'venv' DEFAULT_OPTION_VALUES = { 'venv=': (DEFAULT_VIRTUALENV_PATH,), @@ -208,13 +208,11 @@ def exec_scratch_virtualenv(args): if not exists(scratch.python): run(('virtualenv', scratch.venv)) - if not exists(join(scratch.src, 'virtualenv.py')): + if not exists(join(scratch.src, 'virtualenv')): scratch_python = venv_python(scratch.venv) # TODO: do we allow user-defined override of which version of virtualenv to install? - # https://github.com/Yelp/venv-update/issues/231 virtualenv 20+ is not supported. tmp = scratch.src + '.tmp' - run((scratch_python, '-m', 'pip.__main__', 'install', 'virtualenv<20', '--target', tmp)) - + run((scratch_python, '-m', 'pip.__main__', 'install', 'virtualenv>=20.0.8', '--target', tmp)) from os import rename rename(tmp, scratch.src) @@ -235,91 +233,104 @@ def get_original_path(venv_path): # TODO-TEST: a unit test return check_output(('sh', '-c', '. %s; printf "$VIRTUAL_ENV"' % venv_executable(venv_path, 'activate'))) -def has_system_site_packages(interpreter): - # TODO: unit-test - system_site_packages = check_output(( - interpreter, - '-c', - # stolen directly from virtualenv's site.py - """\ -import site, os.path -print( - 0 - if os.path.exists( - os.path.join(os.path.dirname(site.__file__), 'no-global-site-packages.txt') - ) else - 1 -)""" - )) - system_site_packages = int(system_site_packages) - assert system_site_packages in (0, 1) - return bool(system_site_packages) - - def get_python_version(interpreter): if not exists(interpreter): return None - cmd = (interpreter, '-c', 'import sys; print(sys.version)') - return check_output(cmd) + cmd = (interpreter, '-c', 'import sys; print(".".join(str(p) for p in sys.version_info))') + return check_output(cmd).strip() -def invalid_virtualenv_reason(venv_path, source_python, destination_python, options): +def invalid_virtualenv_reason(venv_path, source_python, destination_python, virtualenv_system_site_packages): try: orig_path = get_original_path(venv_path) except CalledProcessError: return 'could not inspect metadata' if not samefile(orig_path, venv_path): return 'virtualenv moved {} -> {}'.format(timid_relpath(orig_path), timid_relpath(venv_path)) - elif has_system_site_packages(destination_python) != options.system_site_packages: - return 'system-site-packages changed, to %s' % options.system_site_packages + pyvenv_cfg_path = join(venv_path, 'pyvenv.cfg') + + if not exists(pyvenv_cfg_path): + return 'virtualenv created with virtualenv<20' + + # Avoid using pathlib.Path which doesn't exist in python2 and + # hack around configparser's inability to handle sectionless config + # files: https://bugs.python.org/issue22253 + from configparser import ConfigParser + pyvenv_cfg = ConfigParser() + with open(pyvenv_cfg_path, 'r') as f: + pyvenv_cfg.read_string('[root]\n' + f.read()) + if pyvenv_cfg.getboolean( + 'root', + 'include-system-site-packages', + fallback=False + ) != virtualenv_system_site_packages: + return 'system-site-packages changed, to %s' % virtualenv_system_site_packages if source_python is None: return - destination_version = get_python_version(destination_python) + + destination_version = pyvenv_cfg.get('root', 'version_info', fallback=None) source_version = get_python_version(source_python) if source_version != destination_version: return 'python version changed {} -> {}'.format(destination_version, source_version) + base_executable = pyvenv_cfg.get('root', 'base-executable', fallback=None) + base_executable_version = get_python_version(base_executable) + if base_executable_version != destination_version: + return 'base executable python version changed {} -> {}'.format(destination_version, base_executable_version) + def ensure_virtualenv(args, return_values): """Ensure we have a valid virtualenv.""" - def adjust_options(options, args): - # TODO-TEST: proper error message with no arguments - venv_path = return_values.venv_path = args[0] - if venv_path == DEFAULT_VIRTUALENV_PATH or options.prompt == '': + from sys import argv + argv[:] = ('virtualenv',) + args + info(colorize(argv)) + + import virtualenv + + run_virtualenv = True + filtered_args = [a for a in args if not a.startswith('-')] + if filtered_args: + venv_path = return_values.venv_path = filtered_args[0] if filtered_args else None + if venv_path == DEFAULT_VIRTUALENV_PATH: from os.path import abspath, basename, dirname - options.prompt = '(%s)' % basename(dirname(abspath(venv_path))) - # end of option munging. + args = ('--prompt=({})'.format(basename(dirname(abspath(venv_path)))),) + args + # Validate existing virtualenv if there is one # there are two python interpreters involved here: # 1) the interpreter we're instructing virtualenv to copy - if options.python is None: + python_options_arg = [a for a in args if a.startswith('-p') or a.startswith('--python')] + if not python_options_arg: source_python = None else: - source_python = virtualenv.resolve_interpreter(options.python) + virtualenv_session = virtualenv.session_via_cli(args) + source_python = virtualenv_session._interpreter.executable # 2) the interpreter virtualenv will create destination_python = venv_python(venv_path) if exists(destination_python): - reason = invalid_virtualenv_reason(venv_path, source_python, destination_python, options) + # Check if --system-site-packages is a passed-in option + dummy_session = virtualenv.session_via_cli(args) + virtualenv_system_site_packages = dummy_session.creator.enable_system_site_package + + reason = invalid_virtualenv_reason( + venv_path, + source_python, + destination_python, + virtualenv_system_site_packages + ) if reason: info('Removing invalidated virtualenv. (%s)' % reason) run(('rm', '-rf', venv_path)) else: info('Keeping valid virtualenv from previous run.') - raise SystemExit(0) # looks good! we're done here. + run_virtualenv = False # looks good! we're done here. - # this is actually a documented extension point: - # http://virtualenv.readthedocs.org/en/latest/reference.html#adjust_options - import virtualenv - virtualenv.adjust_options = adjust_options + if run_virtualenv: + raise_on_failure(lambda: virtualenv.cli_run(args), ignore_return=True) - from sys import argv - argv[:] = ('virtualenv',) + args - info(colorize(argv)) - raise_on_failure(virtualenv.main) # There might not be a venv_path if doing something like "venv= --version" # and not actually asking virtualenv to make a venv. if return_values.venv_path is not None: @@ -436,11 +447,11 @@ def pip_faster(venv_path, pip_command, install, bootstrap_deps): run(pip_command + install) -def raise_on_failure(mainfunc): +def raise_on_failure(mainfunc, ignore_return=False): """raise if and only if mainfunc fails""" try: errors = mainfunc() - if errors: + if not ignore_return and errors: exit(errors) except CalledProcessError as error: exit(error.returncode) @@ -463,3 +474,4 @@ def main(): if __name__ == '__main__': exit(main()) +