This is generic functionality. We'll need it for WIX.
As part of the port, we expose the full version and return
the data as a dict.
hg-reviewers |
This is generic functionality. We'll need it for WIX.
As part of the port, we expose the full version and return
the data as a dict.
Automatic diff as part of commit; lint not applicable. |
Automatic diff as part of commit; unit tests not applicable. |
Path | Packages | |||
---|---|---|---|---|
M | contrib/packaging/hgpackaging/inno.py (19 lines) | |||
M | contrib/packaging/hgpackaging/util.py (25 lines) |
Status | Author | Revision | |
---|---|---|---|
Closed | indygreg | ||
Closed | indygreg | D6100 wix: remove pywin32 | |
Closed | indygreg | ||
Closed | indygreg | D6098 wix: restore COPYING.rtf | |
Closed | indygreg | ||
Closed | indygreg | ||
Closed | indygreg | D6095 wix: remove hg.cmd | |
Closed | indygreg | ||
Closed | indygreg | ||
Closed | indygreg | ||
Closed | indygreg | ||
Closed | indygreg | ||
Closed | indygreg | ||
Closed | indygreg | ||
Closed | indygreg | ||
Closed | indygreg | ||
Closed | indygreg | ||
Closed | indygreg | ||
Closed | indygreg |
from .downloads import ( | from .downloads import ( | ||||
download_entry, | download_entry, | ||||
) | ) | ||||
from .util import ( | from .util import ( | ||||
extract_tar_to_directory, | extract_tar_to_directory, | ||||
extract_zip_to_directory, | extract_zip_to_directory, | ||||
find_vc_runtime_files, | find_vc_runtime_files, | ||||
python_exe_info, | |||||
) | ) | ||||
PRINT_PYTHON_INFO = ''' | |||||
import platform, sys; print("%s:%d" % (platform.architecture()[0], sys.version_info[0])) | |||||
'''.strip() | |||||
def build(source_dir: pathlib.Path, build_dir: pathlib.Path, | def build(source_dir: pathlib.Path, build_dir: pathlib.Path, | ||||
python_exe: pathlib.Path, iscc_exe: pathlib.Path, | python_exe: pathlib.Path, iscc_exe: pathlib.Path, | ||||
version=None): | version=None): | ||||
"""Build the Inno installer. | """Build the Inno installer. | ||||
Build files will be placed in ``build_dir``. | Build files will be placed in ``build_dir``. | ||||
py2exe's setup.py doesn't use setuptools. It doesn't have modern logic | py2exe's setup.py doesn't use setuptools. It doesn't have modern logic | ||||
for finding the Python 2.7 toolchain. So, we require the environment | for finding the Python 2.7 toolchain. So, we require the environment | ||||
to already be configured with an active toolchain. | to already be configured with an active toolchain. | ||||
""" | """ | ||||
if not iscc_exe.exists(): | if not iscc_exe.exists(): | ||||
raise Exception('%s does not exist' % iscc_exe) | raise Exception('%s does not exist' % iscc_exe) | ||||
if 'VCINSTALLDIR' not in os.environ: | if 'VCINSTALLDIR' not in os.environ: | ||||
raise Exception('not running from a Visual C++ build environment; ' | raise Exception('not running from a Visual C++ build environment; ' | ||||
'execute the "Visual C++ <version> Command Prompt" ' | 'execute the "Visual C++ <version> Command Prompt" ' | ||||
'application shortcut or a vcsvarsall.bat file') | 'application shortcut or a vcsvarsall.bat file') | ||||
# Identity x86/x64 and validate the environment matches the Python | # Identity x86/x64 and validate the environment matches the Python | ||||
# architecture. | # architecture. | ||||
vc_x64 = r'\x64' in os.environ['LIB'] | vc_x64 = r'\x64' in os.environ['LIB'] | ||||
res = subprocess.run( | py_info = python_exe_info(python_exe) | ||||
[str(python_exe), '-c', PRINT_PYTHON_INFO], | |||||
capture_output=True, check=True) | |||||
py_arch, py_version = res.stdout.decode('utf-8').split(':') | |||||
py_version = int(py_version) | |||||
if vc_x64: | if vc_x64: | ||||
if py_arch != '64bit': | if py_info['arch'] != '64bit': | ||||
raise Exception('architecture mismatch: Visual C++ environment ' | raise Exception('architecture mismatch: Visual C++ environment ' | ||||
'is configured for 64-bit but Python is 32-bit') | 'is configured for 64-bit but Python is 32-bit') | ||||
else: | else: | ||||
if py_arch != '32bit': | if py_info['arch'] != '32bit': | ||||
raise Exception('architecture mismatch: Visual C++ environment ' | raise Exception('architecture mismatch: Visual C++ environment ' | ||||
'is configured for 32-bit but Python is 64-bit') | 'is configured for 32-bit but Python is 64-bit') | ||||
if py_version != 2: | if py_info['py3']: | ||||
raise Exception('Only Python 2 is currently supported') | raise Exception('Only Python 2 is currently supported') | ||||
build_dir.mkdir(exist_ok=True) | build_dir.mkdir(exist_ok=True) | ||||
gettext_pkg, gettext_entry = download_entry('gettext', build_dir) | gettext_pkg, gettext_entry = download_entry('gettext', build_dir) | ||||
gettext_dep_pkg = download_entry('gettext-dep', build_dir)[0] | gettext_dep_pkg = download_entry('gettext-dep', build_dir)[0] | ||||
virtualenv_pkg, virtualenv_entry = download_entry('virtualenv', build_dir) | virtualenv_pkg, virtualenv_entry = download_entry('virtualenv', build_dir) | ||||
py2exe_pkg, py2exe_entry = download_entry('py2exe', build_dir) | py2exe_pkg, py2exe_entry = download_entry('py2exe', build_dir) |
# util.py - Common packaging utility code. | # util.py - Common packaging utility code. | ||||
# | # | ||||
# Copyright 2019 Gregory Szorc <gregory.szorc@gmail.com> | # Copyright 2019 Gregory Szorc <gregory.szorc@gmail.com> | ||||
# | # | ||||
# This software may be used and distributed according to the terms of the | # This software may be used and distributed according to the terms of the | ||||
# GNU General Public License version 2 or any later version. | # GNU General Public License version 2 or any later version. | ||||
# no-check-code because Python 3 native. | # no-check-code because Python 3 native. | ||||
import distutils.version | |||||
import os | import os | ||||
import pathlib | import pathlib | ||||
import subprocess | |||||
import tarfile | import tarfile | ||||
import zipfile | import zipfile | ||||
def extract_tar_to_directory(source: pathlib.Path, dest: pathlib.Path): | def extract_tar_to_directory(source: pathlib.Path, dest: pathlib.Path): | ||||
with tarfile.open(source, 'r') as tf: | with tarfile.open(source, 'r') as tf: | ||||
tf.extractall(dest) | tf.extractall(dest) | ||||
d = winsxs / version | d = winsxs / version | ||||
return [ | return [ | ||||
d / 'msvcm90.dll', | d / 'msvcm90.dll', | ||||
d / 'msvcp90.dll', | d / 'msvcp90.dll', | ||||
d / 'msvcr90.dll', | d / 'msvcr90.dll', | ||||
winsxs / 'Manifests' / ('%s.manifest' % version), | winsxs / 'Manifests' / ('%s.manifest' % version), | ||||
] | ] | ||||
PRINT_PYTHON_INFO = ''' | |||||
import platform; print("%s:%s" % (platform.architecture()[0], platform.python_version())) | |||||
'''.strip() | |||||
def python_exe_info(python_exe: pathlib.Path): | |||||
"""Obtain information about a Python executable.""" | |||||
res = subprocess.run( | |||||
[str(python_exe), '-c', PRINT_PYTHON_INFO], | |||||
capture_output=True, check=True) | |||||
arch, version = res.stdout.decode('utf-8').split(':') | |||||
version = distutils.version.LooseVersion(version) | |||||
return { | |||||
'arch': arch, | |||||
'version': version, | |||||
'py3': version >= distutils.version.LooseVersion('3'), | |||||
} |