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.
| Lint Skipped |
| Unit Tests Skipped |
| Path | Packages | |||
|---|---|---|---|---|
| M | contrib/packaging/hgpackaging/inno.py (19 lines) | |||
| M | contrib/packaging/hgpackaging/util.py (25 lines) |
| Commit | Parents | Author | Summary | Date |
|---|---|---|---|---|
| Gregory Szorc | Mar 7 2019, 1:49 PM |
| 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'), | |||||
| } | |||||