##// END OF EJS Templates
copies: extract value comparison in the python copy tracing...
copies: extract value comparison in the python copy tracing This mirror what we did in the Rust code. This is useful to prepare rework for this comparison logic that we will need to handle more advanced chaining cases (when merges are chained). Differential Revision: https://phab.mercurial-scm.org/D9590

File last commit:

r46554:89a2afe3 default
r46776:3a0c4133 default
Show More
inno.py
236 lines | 6.2 KiB | text/x-python | PythonLexer
Gregory Szorc
packaging: move Inno Setup core logic into a module...
r42077 # inno.py - Inno Setup functionality.
#
# Copyright 2019 Gregory Szorc <gregory.szorc@gmail.com>
#
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
# no-check-code because Python 3 native.
import os
import pathlib
import shutil
import subprocess
Gregory Szorc
packaging: process Inno Setup files with Jinja2...
r43915 import jinja2
Gregory Szorc
packaging: stage installed files for Inno...
r43916 from .py2exe import (
build_py2exe,
stage_install,
)
Gregory Szorc
packaging: support building Inno installer with PyOxidizer...
r45270 from .pyoxidizer import run_pyoxidizer
Gregory Szorc
packaging: always pass VERSION into Inno invocation...
r43918 from .util import (
Gregory Szorc
packaging: support building Inno installer with PyOxidizer...
r45270 find_legacy_vc_runtime_files,
Matt Harbison
packaging: set the FileVersion field in the Inno installer executable...
r44708 normalize_windows_version,
Matt Harbison
packaging: bundle the default mercurial.ini template with Inno also...
r44709 process_install_rules,
Gregory Szorc
packaging: always pass VERSION into Inno invocation...
r43918 read_version_py,
)
Gregory Szorc
packaging: move Inno Setup core logic into a module...
r42077
Gregory Szorc
setup: configure py2exe config via environment variables...
r42082 EXTRA_PACKAGES = {
'dulwich',
'keyring',
'pygments',
'win32ctypes',
}
Matt Harbison
packaging: bundle the default mercurial.ini template with Inno also...
r44709 EXTRA_INSTALL_RULES = [
('contrib/win32/mercurial.ini', 'defaultrc/mercurial.rc'),
]
Gregory Szorc
packaging: stage installed files for Inno...
r43916 PACKAGE_FILES_METADATA = {
'ReadMe.html': 'Flags: isreadme',
}
Gregory Szorc
setup: configure py2exe config via environment variables...
r42082
Gregory Szorc
packaging: support building Inno installer with PyOxidizer...
r45270 def build_with_py2exe(
Augie Fackler
formatting: blacken the codebase...
r43346 source_dir: pathlib.Path,
build_dir: pathlib.Path,
python_exe: pathlib.Path,
iscc_exe: pathlib.Path,
version=None,
):
Gregory Szorc
packaging: support building Inno installer with PyOxidizer...
r45270 """Build the Inno installer using py2exe.
Gregory Szorc
packaging: move Inno Setup core logic into a module...
r42077
Build files will be placed in ``build_dir``.
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
to already be configured with an active toolchain.
"""
if not iscc_exe.exists():
raise Exception('%s does not exist' % iscc_exe)
Gregory Szorc
packaging: extract py2exe functionality to own module...
r42081 vc_x64 = r'\x64' in os.environ.get('LIB', '')
Gregory Szorc
packaging: install and run Inno files in a build directory...
r43914 arch = 'x64' if vc_x64 else 'x86'
Gregory Szorc
packaging: split Inno installer building from Mercurial building...
r45269 inno_build_dir = build_dir / ('inno-py2exe-%s' % arch)
Gregory Szorc
packaging: stage installed files for Inno...
r43916 staging_dir = inno_build_dir / 'stage'
Gregory Szorc
packaging: move Inno Setup core logic into a module...
r42077
Augie Fackler
formatting: blacken the codebase...
r43346 requirements_txt = (
Gregory Szorc
contrib: split Windows requirements into multiple files...
r46344 source_dir / 'contrib' / 'packaging' / 'requirements-windows-py2.txt'
Augie Fackler
formatting: blacken the codebase...
r43346 )
Gregory Szorc
packaging: move Inno Setup core logic into a module...
r42077
Gregory Szorc
packaging: install and run Inno files in a build directory...
r43914 inno_build_dir.mkdir(parents=True, exist_ok=True)
Augie Fackler
formatting: blacken the codebase...
r43346 build_py2exe(
source_dir,
build_dir,
python_exe,
'inno',
requirements_txt,
extra_packages=EXTRA_PACKAGES,
)
Gregory Szorc
packaging: move Inno Setup core logic into a module...
r42077
Gregory Szorc
packaging: stage installed files for Inno...
r43916 # Purge the staging directory for every build so packaging is
# pristine.
if staging_dir.exists():
print('purging %s' % staging_dir)
shutil.rmtree(staging_dir)
# Now assemble all the packaged files into the staging directory.
stage_install(source_dir, staging_dir)
Matt Harbison
packaging: bundle the default mercurial.ini template with Inno also...
r44709 # We also install some extra files.
process_install_rules(EXTRA_INSTALL_RULES, source_dir, staging_dir)
Gregory Szorc
packaging: don't use temporary directory...
r42079 # hg.exe depends on VC9 runtime DLLs. Copy those into place.
Gregory Szorc
packaging: support building Inno installer with PyOxidizer...
r45270 for f in find_legacy_vc_runtime_files(vc_x64):
Gregory Szorc
packaging: don't use temporary directory...
r42079 if f.name.endswith('.manifest'):
basename = 'Microsoft.VC90.CRT.manifest'
else:
basename = f.name
Gregory Szorc
packaging: move Inno Setup core logic into a module...
r42077
Gregory Szorc
packaging: stage installed files for Inno...
r43916 dest_path = staging_dir / basename
Gregory Szorc
packaging: move Inno Setup core logic into a module...
r42077
Gregory Szorc
packaging: don't use temporary directory...
r42079 print('copying %s to %s' % (f, dest_path))
shutil.copyfile(f, dest_path)
Gregory Szorc
packaging: move Inno Setup core logic into a module...
r42077
Gregory Szorc
packaging: split Inno installer building from Mercurial building...
r45269 build_installer(
source_dir,
inno_build_dir,
staging_dir,
iscc_exe,
version,
arch="x64" if vc_x64 else None,
Gregory Szorc
packaging: add -python2 to Windows installer filenames...
r45276 suffix="-python2",
Gregory Szorc
packaging: split Inno installer building from Mercurial building...
r45269 )
Gregory Szorc
packaging: support building Inno installer with PyOxidizer...
r45270 def build_with_pyoxidizer(
source_dir: pathlib.Path,
build_dir: pathlib.Path,
target_triple: str,
iscc_exe: pathlib.Path,
version=None,
):
"""Build the Inno installer using PyOxidizer."""
if not iscc_exe.exists():
raise Exception("%s does not exist" % iscc_exe)
inno_build_dir = build_dir / ("inno-pyoxidizer-%s" % target_triple)
staging_dir = inno_build_dir / "stage"
inno_build_dir.mkdir(parents=True, exist_ok=True)
run_pyoxidizer(source_dir, inno_build_dir, staging_dir, target_triple)
process_install_rules(EXTRA_INSTALL_RULES, source_dir, staging_dir)
build_installer(
source_dir,
inno_build_dir,
staging_dir,
iscc_exe,
version,
arch="x64" if "x86_64" in target_triple else None,
)
Gregory Szorc
packaging: split Inno installer building from Mercurial building...
r45269 def build_installer(
source_dir: pathlib.Path,
inno_build_dir: pathlib.Path,
staging_dir: pathlib.Path,
iscc_exe: pathlib.Path,
version,
arch=None,
Gregory Szorc
packaging: add -python2 to Windows installer filenames...
r45276 suffix="",
Gregory Szorc
packaging: split Inno installer building from Mercurial building...
r45269 ):
"""Build an Inno installer from staged Mercurial files.
This function is agnostic about how to build Mercurial. It just
cares that Mercurial files are in ``staging_dir``.
"""
inno_source_dir = source_dir / "contrib" / "packaging" / "inno"
Gregory Szorc
packaging: stage installed files for Inno...
r43916 # The final package layout is simply a mirror of the staging directory.
package_files = []
for root, dirs, files in os.walk(staging_dir):
dirs.sort()
root = pathlib.Path(root)
for f in sorted(files):
full = root / f
rel = full.relative_to(staging_dir)
if str(rel.parent) == '.':
dest_dir = '{app}'
else:
dest_dir = '{app}\\%s' % rel.parent
package_files.append(
{
'source': rel,
'dest_dir': dest_dir,
'metadata': PACKAGE_FILES_METADATA.get(str(rel), None),
}
)
Gregory Szorc
packaging: don't use temporary directory...
r42079 print('creating installer')
Gregory Szorc
packaging: process Inno Setup files with Jinja2...
r43915 # Install Inno files by rendering a template.
jinja_env = jinja2.Environment(
loader=jinja2.FileSystemLoader(str(inno_source_dir)),
# Need to change these to prevent conflict with Inno Setup.
comment_start_string='{##',
comment_end_string='##}',
)
try:
template = jinja_env.get_template('mercurial.iss')
except jinja2.TemplateSyntaxError as e:
raise Exception(
'template syntax error at %s:%d: %s'
Augie Fackler
formating: upgrade to black 20.8b1...
r46554 % (
e.name,
e.lineno,
e.message,
)
Gregory Szorc
packaging: process Inno Setup files with Jinja2...
r43915 )
Gregory Szorc
packaging: stage installed files for Inno...
r43916 content = template.render(package_files=package_files)
Gregory Szorc
packaging: process Inno Setup files with Jinja2...
r43915
with (inno_build_dir / 'mercurial.iss').open('w', encoding='utf-8') as fh:
fh.write(content)
Gregory Szorc
packaging: install and run Inno files in a build directory...
r43914
Gregory Szorc
packaging: stage installed files for Inno...
r43916 # Copy additional files used by Inno.
for p in ('mercurial.ico', 'postinstall.txt'):
shutil.copyfile(
source_dir / 'contrib' / 'win32' / p, inno_build_dir / p
)
Gregory Szorc
packaging: don't use temporary directory...
r42079 args = [str(iscc_exe)]
Gregory Szorc
packaging: move Inno Setup core logic into a module...
r42077
Gregory Szorc
packaging: split Inno installer building from Mercurial building...
r45269 if arch:
args.append('/dARCH=%s' % arch)
Gregory Szorc
packaging: add -python2 to Windows installer filenames...
r45276 args.append('/dSUFFIX=-%s%s' % (arch, suffix))
else:
args.append('/dSUFFIX=-x86%s' % suffix)
Gregory Szorc
packaging: move Inno Setup core logic into a module...
r42077
Gregory Szorc
packaging: always pass VERSION into Inno invocation...
r43918 if not version:
version = read_version_py(source_dir)
args.append('/dVERSION=%s' % version)
Matt Harbison
packaging: set the FileVersion field in the Inno installer executable...
r44708 args.append('/dQUAD_VERSION=%s' % normalize_windows_version(version))
Gregory Szorc
packaging: move Inno Setup core logic into a module...
r42077
Gregory Szorc
packaging: don't use temporary directory...
r42079 args.append('/Odist')
Gregory Szorc
packaging: install and run Inno files in a build directory...
r43914 args.append(str(inno_build_dir / 'mercurial.iss'))
Gregory Szorc
packaging: move Inno Setup core logic into a module...
r42077
Gregory Szorc
packaging: don't use temporary directory...
r42079 subprocess.run(args, cwd=str(source_dir), check=True)