diff --git a/setup.py b/setup.py index d5469bb26..484a31a79 100644 --- a/setup.py +++ b/setup.py @@ -54,12 +54,16 @@ install_requires = [ 'zope.interface', ] +# Load minimal pywin32 version from the Windows installer builder +windows_installer = os.path.join(here, 'windows-installer', 'construct.py') +pywin32_version_search = re.search(r'PYWIN32_VERSION = (\d+)', read_file(windows_installer)) +pywin32_req = 'pywin32>={0}'.format(pywin32_version_search.group(1)) + # Add pywin32 on Windows platforms to handle low-level system calls. # This dependency needs to be added using environment markers to avoid its installation on Linux. # However environment markers are supported only with setuptools >= 36.2. # So this dependency is not added for old Linux distributions with old setuptools, # in order to allow these systems to build certbot from sources. -pywin32_req = 'pywin32>=225' if StrictVersion(setuptools_version) >= StrictVersion('36.2'): install_requires.append(pywin32_req + " ; sys_platform == 'win32'") elif 'bdist_wheel' in sys.argv[1:]: diff --git a/tools/strip_hashes.py b/tools/strip_hashes.py index 988e72eb8..12d7c0d30 100755 --- a/tools/strip_hashes.py +++ b/tools/strip_hashes.py @@ -30,7 +30,6 @@ def main(*paths): Hashes are removed from returned entries. """ - deps = [] if paths: for path in paths: diff --git a/windows-installer/construct.py b/windows-installer/construct.py index 7fd3039f9..63961c52a 100644 --- a/windows-installer/construct.py +++ b/windows-installer/construct.py @@ -1,15 +1,17 @@ #!/usr/bin/env python3 +import contextlib import ctypes import struct import subprocess import os import sys import shutil +import tempfile import time - PYTHON_VERSION = (3, 7, 4) PYTHON_BITNESS = 32 +PYWIN32_VERSION = 225 def main(): @@ -42,9 +44,10 @@ def _compile_wheels(repo_path, build_path, venv_python): # certbot_packages.extend([name for name in os.listdir(repo_path) if name.startswith('certbot-dns-')]) wheels_project = [os.path.join(repo_path, package) for package in certbot_packages] - command = [venv_python, '-m', 'pip', 'wheel', '-w', wheels_path] - command.extend(wheels_project) - subprocess.check_call(command) + with _prepare_constraints(repo_path) as constraints_file_path: + command = [venv_python, '-m', 'pip', 'wheel', '-w', wheels_path, '--constraint', constraints_file_path] + command.extend(wheels_project) + subprocess.check_call(command) def _prepare_build_tools(venv_path, venv_python, repo_path): @@ -55,6 +58,23 @@ def _prepare_build_tools(venv_path, venv_python, repo_path): subprocess.check_call([venv_python, os.path.join(repo_path, 'tools', 'pip_install.py'), 'wheel', 'pynsist']) +@contextlib.contextmanager +def _prepare_constraints(repo_path): + requirements = os.path.join(repo_path, 'letsencrypt-auto-source', 'pieces', 'dependency-requirements.txt') + constraints = subprocess.check_output( + [sys.executable, os.path.join(repo_path, 'tools', 'strip_hashes.py'), requirements], + universal_newlines=True) + workdir = tempfile.mkdtemp() + try: + constraints_file_path = os.path.join(workdir, 'constraints.txt') + with open(constraints_file_path, 'a') as file_h: + file_h.write(constraints) + file_h.write('pywin32=={0}'.format(PYWIN32_VERSION)) + yield constraints_file_path + finally: + shutil.rmtree(workdir) + + def _copy_assets(build_path, repo_path): print('Copy assets') if os.path.exists(build_path):