##// END OF EJS Templates
packaging: process Inno Setup files with Jinja2...
packaging: process Inno Setup files with Jinja2 I want to make the Inno Setup files dynamically generated. This will enable us to do things like automatically derive the set of files to be packaged instead of having to manually keep lists of files in sync across installers. As the first step towards this, we process the Inno Setup files with Jinja2. As part of this conversion, we had to escape syntax in mercurial.iss that conflicts with Jinja2. I also took the opportunity to include modpath.iss via Jinja2 instead of using Inno's preprocessor. This keeps the Python code a bit simpler. Differential Revision: https://phab.mercurial-scm.org/D7158

File last commit:

r43824:cf5eaf24 default
r43915:7bd88d0d default
Show More
inno.py
112 lines | 2.9 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
Augie Fackler
formatting: blacken the codebase...
r43346 from .py2exe import build_py2exe
from .util import find_vc_runtime_files
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',
}
Augie Fackler
formatting: blacken the codebase...
r43346 def build(
source_dir: pathlib.Path,
build_dir: pathlib.Path,
python_exe: pathlib.Path,
iscc_exe: pathlib.Path,
version=None,
):
Gregory Szorc
packaging: move Inno Setup core logic into a module...
r42077 """Build the Inno installer.
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'
inno_source_dir = source_dir / 'contrib' / 'packaging' / 'inno'
inno_build_dir = build_dir / ('inno-%s' % arch)
Gregory Szorc
packaging: move Inno Setup core logic into a module...
r42077
Augie Fackler
formatting: blacken the codebase...
r43346 requirements_txt = (
source_dir / 'contrib' / 'packaging' / 'inno' / 'requirements.txt'
)
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: don't use temporary directory...
r42079 # hg.exe depends on VC9 runtime DLLs. Copy those into place.
for f in find_vc_runtime_files(vc_x64):
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: don't use temporary directory...
r42079 dest_path = source_dir / 'dist' / 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: 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'
% (e.name, e.lineno, e.message,)
)
content = template.render()
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: 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: don't use temporary directory...
r42079 if vc_x64:
args.append('/dARCH=x64')
Gregory Szorc
packaging: move Inno Setup core logic into a module...
r42077
Gregory Szorc
packaging: don't use temporary directory...
r42079 if version:
args.append('/dVERSION=%s' % 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)