##// END OF EJS Templates
automation: drop support for Python 2.7 in Windows environment...
automation: drop support for Python 2.7 in Windows environment We stop installing Python 2.7 in the Windows environment. We remove support for building Python 2.7 wheels and installers. There is still some Python 2.7 support cleanup to perform in automation. But this removes the biggest remaining chunk of references to 2.7. Differential Revision: https://phab.mercurial-scm.org/D12263

File last commit:

r48444:be37bb8d default
r49701:d7e064d5 default
Show More
wix.py
586 lines | 18.0 KiB | text/x-python | PythonLexer
Gregory Szorc
packaging: convert files to LF...
r42118 # wix.py - WiX installer 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.
Gregory Szorc
packaging: stage files and dynamically generate WiX installer...
r44022 import collections
Augie Fackler
packaging: add command line flag to add extra vars to pyoxidizer...
r48444 import json
Gregory Szorc
packaging: convert files to LF...
r42118 import os
import pathlib
import re
Gregory Szorc
packaging: stage files and dynamically generate WiX installer...
r44022 import shutil
Gregory Szorc
packaging: convert files to LF...
r42118 import subprocess
Augie Fackler
wix: add support for additional wxs files...
r42215 import typing
Gregory Szorc
packaging: stage files and dynamically generate WiX installer...
r44022 import uuid
Gregory Szorc
wix: autogenerate wxs file for library files...
r42123 import xml.dom.minidom
Gregory Szorc
packaging: convert files to LF...
r42118
Augie Fackler
formatting: blacken the codebase...
r43346 from .downloads import download_entry
Gregory Szorc
packaging: stage files and dynamically generate WiX installer...
r44022 from .py2exe import (
build_py2exe,
stage_install,
)
Gregory Szorc
packaging: use PyOxidizer for producing WiX MSI installer...
r47981 from .pyoxidizer import (
build_docs_html,
create_pyoxidizer_install_layout,
run_pyoxidizer,
)
Gregory Szorc
packaging: convert files to LF...
r42118 from .util import (
extract_zip_to_directory,
Matt Harbison
packaging: move the version normalization function to the util module...
r44707 normalize_windows_version,
Gregory Szorc
packaging: stage files and dynamically generate WiX installer...
r44022 process_install_rules,
Gregory Szorc
packaging: convert files to LF...
r42118 sign_with_signtool,
)
EXTRA_PACKAGES = {
Matt Harbison
packaging: bundle dulwich, keyring, and pywin32-ctypes with WiX too...
r44710 'dulwich',
Gregory Szorc
packaging: convert files to LF...
r42118 'distutils',
Matt Harbison
packaging: bundle dulwich, keyring, and pywin32-ctypes with WiX too...
r44710 'keyring',
Gregory Szorc
packaging: convert files to LF...
r42118 'pygments',
Matt Harbison
packaging: bundle dulwich, keyring, and pywin32-ctypes with WiX too...
r44710 'win32ctypes',
Gregory Szorc
packaging: convert files to LF...
r42118 }
Matt Harbison
packaging: include `windows_curses` when building py2exe...
r47110 EXTRA_INCLUDES = {
'_curses',
'_curses_panel',
}
Gregory Szorc
packaging: convert files to LF...
r42118
Gregory Szorc
packaging: stage files and dynamically generate WiX installer...
r44022 EXTRA_INSTALL_RULES = [
('contrib/packaging/wix/COPYING.rtf', 'COPYING.rtf'),
Matt Harbison
packaging: rename hgrc.d to defaultrc for Windows config files next to the exe...
r44614 ('contrib/win32/mercurial.ini', 'defaultrc/mercurial.rc'),
Gregory Szorc
packaging: stage files and dynamically generate WiX installer...
r44022 ]
STAGING_REMOVE_FILES = [
# We use the RTF variant.
'copying.txt',
]
SHORTCUTS = {
# hg.1.html'
'hg.file.5d3e441c_28d9_5542_afd0_cdd4234f12d5': {
'Name': 'Mercurial Command Reference',
},
# hgignore.5.html
'hg.file.5757d8e0_f207_5e10_a2ec_3ba0a062f431': {
'Name': 'Mercurial Ignore Files',
},
# hgrc.5.html
'hg.file.92e605fd_1d1a_5dc6_9fc0_5d2998eb8f5e': {
'Name': 'Mercurial Configuration Files',
},
}
Gregory Szorc
packaging: convert files to LF...
r42118 def find_version(source_dir: pathlib.Path):
version_py = source_dir / 'mercurial' / '__version__.py'
with version_py.open('r', encoding='utf-8') as fh:
source = fh.read().strip()
m = re.search('version = b"(.*)"', source)
return m.group(1)
def ensure_vc90_merge_modules(build_dir):
x86 = (
Augie Fackler
formatting: blacken the codebase...
r43346 download_entry(
'vc9-crt-x86-msm',
build_dir,
local_name='microsoft.vcxx.crt.x86_msm.msm',
)[0],
download_entry(
'vc9-crt-x86-msm-policy',
build_dir,
local_name='policy.x.xx.microsoft.vcxx.crt.x86_msm.msm',
)[0],
Gregory Szorc
packaging: convert files to LF...
r42118 )
x64 = (
Augie Fackler
formatting: blacken the codebase...
r43346 download_entry(
'vc9-crt-x64-msm',
build_dir,
local_name='microsoft.vcxx.crt.x64_msm.msm',
)[0],
download_entry(
'vc9-crt-x64-msm-policy',
build_dir,
local_name='policy.x.xx.microsoft.vcxx.crt.x64_msm.msm',
)[0],
Gregory Szorc
packaging: convert files to LF...
r42118 )
return {
'x86': x86,
'x64': x64,
}
def run_candle(wix, cwd, wxs, source_dir, defines=None):
args = [
str(wix / 'candle.exe'),
'-nologo',
str(wxs),
'-dSourceDir=%s' % source_dir,
]
if defines:
args.extend('-d%s=%s' % define for define in sorted(defines.items()))
subprocess.run(args, cwd=str(cwd), check=True)
Gregory Szorc
packaging: stage files and dynamically generate WiX installer...
r44022 def make_files_xml(staging_dir: pathlib.Path, is_x64) -> str:
"""Create XML string listing every file to be installed."""
Gregory Szorc
wix: autogenerate wxs file for library files...
r42123
Gregory Szorc
packaging: stage files and dynamically generate WiX installer...
r44022 # We derive GUIDs from a deterministic file path identifier.
# We shoehorn the name into something that looks like a URL because
# the UUID namespaces are supposed to work that way (even though
# the input data probably is never validated).
Gregory Szorc
wix: autogenerate wxs file for library files...
r42123
doc = xml.dom.minidom.parseString(
Gregory Szorc
packaging: stage files and dynamically generate WiX installer...
r44022 '<?xml version="1.0" encoding="utf-8"?>'
'<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">'
'</Wix>'
Augie Fackler
formatting: blacken the codebase...
r43346 )
Gregory Szorc
wix: autogenerate wxs file for library files...
r42123
Gregory Szorc
packaging: stage files and dynamically generate WiX installer...
r44022 # Assemble the install layout by directory. This makes it easier to
# emit XML, since each directory has separate entities.
manifest = collections.defaultdict(dict)
for root, dirs, files in os.walk(staging_dir):
dirs.sort()
root = pathlib.Path(root)
rel_dir = root.relative_to(staging_dir)
for i in range(len(rel_dir.parts)):
parent = '/'.join(rel_dir.parts[0 : i + 1])
manifest.setdefault(parent, {})
for f in sorted(files):
full = root / f
manifest[str(rel_dir).replace('\\', '/')][full.name] = full
component_groups = collections.defaultdict(list)
# Now emit a <Fragment> for each directory.
# Each directory is composed of a <DirectoryRef> pointing to its parent
# and defines child <Directory>'s and a <Component> with all the files.
for dir_name, entries in sorted(manifest.items()):
# The directory id is derived from the path. But the root directory
# is special.
if dir_name == '.':
parent_directory_id = 'INSTALLDIR'
else:
Gregory Szorc
packaging: normalize - to _ in WiX Id values...
r46221 parent_directory_id = 'hg.dir.%s' % dir_name.replace(
'/', '.'
).replace('-', '_')
Gregory Szorc
wix: autogenerate wxs file for library files...
r42123
Gregory Szorc
packaging: stage files and dynamically generate WiX installer...
r44022 fragment = doc.createElement('Fragment')
directory_ref = doc.createElement('DirectoryRef')
directory_ref.setAttribute('Id', parent_directory_id)
# Add <Directory> entries for immediate children directories.
for possible_child in sorted(manifest.keys()):
if (
dir_name == '.'
and '/' not in possible_child
and possible_child != '.'
):
Gregory Szorc
packaging: normalize - to _ in WiX Id values...
r46221 child_directory_id = ('hg.dir.%s' % possible_child).replace(
'-', '_'
)
Gregory Szorc
packaging: stage files and dynamically generate WiX installer...
r44022 name = possible_child
else:
if not possible_child.startswith('%s/' % dir_name):
continue
name = possible_child[len(dir_name) + 1 :]
if '/' in name:
continue
child_directory_id = 'hg.dir.%s' % possible_child.replace(
'/', '.'
Gregory Szorc
packaging: normalize - to _ in WiX Id values...
r46221 ).replace('-', '_')
Gregory Szorc
packaging: stage files and dynamically generate WiX installer...
r44022
directory = doc.createElement('Directory')
directory.setAttribute('Id', child_directory_id)
directory.setAttribute('Name', name)
directory_ref.appendChild(directory)
# Add <Component>s for files in this directory.
for rel, source_path in sorted(entries.items()):
if dir_name == '.':
full_rel = rel
else:
full_rel = '%s/%s' % (dir_name, rel)
Gregory Szorc
wix: autogenerate wxs file for library files...
r42123
Gregory Szorc
packaging: stage files and dynamically generate WiX installer...
r44022 component_unique_id = (
'https://www.mercurial-scm.org/wix-installer/0/component/%s'
% full_rel
)
component_guid = uuid.uuid5(uuid.NAMESPACE_URL, component_unique_id)
component_id = 'hg.component.%s' % str(component_guid).replace(
'-', '_'
)
component = doc.createElement('Component')
component.setAttribute('Id', component_id)
component.setAttribute('Guid', str(component_guid).upper())
component.setAttribute('Win64', 'yes' if is_x64 else 'no')
# Assign this component to a top-level group.
if dir_name == '.':
component_groups['ROOT'].append(component_id)
elif '/' in dir_name:
component_groups[dir_name[0 : dir_name.index('/')]].append(
component_id
)
else:
component_groups[dir_name].append(component_id)
unique_id = (
'https://www.mercurial-scm.org/wix-installer/0/%s' % full_rel
)
file_guid = uuid.uuid5(uuid.NAMESPACE_URL, unique_id)
# IDs have length limits. So use GUID to derive them.
file_guid_normalized = str(file_guid).replace('-', '_')
file_id = 'hg.file.%s' % file_guid_normalized
Gregory Szorc
wix: autogenerate wxs file for library files...
r42123
Gregory Szorc
packaging: stage files and dynamically generate WiX installer...
r44022 file_element = doc.createElement('File')
file_element.setAttribute('Id', file_id)
file_element.setAttribute('Source', str(source_path))
file_element.setAttribute('KeyPath', 'yes')
file_element.setAttribute('ReadOnly', 'yes')
component.appendChild(file_element)
directory_ref.appendChild(component)
fragment.appendChild(directory_ref)
doc.documentElement.appendChild(fragment)
for group, component_ids in sorted(component_groups.items()):
fragment = doc.createElement('Fragment')
component_group = doc.createElement('ComponentGroup')
component_group.setAttribute('Id', 'hg.group.%s' % group)
for component_id in component_ids:
component_ref = doc.createElement('ComponentRef')
component_ref.setAttribute('Id', component_id)
component_group.appendChild(component_ref)
Gregory Szorc
wix: autogenerate wxs file for library files...
r42123
Gregory Szorc
packaging: stage files and dynamically generate WiX installer...
r44022 fragment.appendChild(component_group)
doc.documentElement.appendChild(fragment)
# Add <Shortcut> to files that have it defined.
for file_id, metadata in sorted(SHORTCUTS.items()):
els = doc.getElementsByTagName('File')
els = [el for el in els if el.getAttribute('Id') == file_id]
if not els:
raise Exception('could not find File[Id=%s]' % file_id)
for el in els:
shortcut = doc.createElement('Shortcut')
shortcut.setAttribute('Id', 'hg.shortcut.%s' % file_id)
shortcut.setAttribute('Directory', 'ProgramMenuDir')
shortcut.setAttribute('Icon', 'hgIcon.ico')
shortcut.setAttribute('IconIndex', '0')
shortcut.setAttribute('Advertise', 'yes')
for k, v in sorted(metadata.items()):
shortcut.setAttribute(k, v)
el.appendChild(shortcut)
Gregory Szorc
wix: autogenerate wxs file for library files...
r42123
return doc.toprettyxml()
Gregory Szorc
packaging: support building WiX installers with PyOxidizer...
r45274 def build_installer_py2exe(
Augie Fackler
formatting: blacken the codebase...
r43346 source_dir: pathlib.Path,
python_exe: pathlib.Path,
msi_name='mercurial',
version=None,
extra_packages_script=None,
extra_wxs: typing.Optional[typing.Dict[str, str]] = None,
extra_features: typing.Optional[typing.List[str]] = None,
Gregory Szorc
packaging: integrate signing into run_wix_packaging()...
r45272 signing_info: typing.Optional[typing.Dict[str, str]] = None,
Augie Fackler
formatting: blacken the codebase...
r43346 ):
Gregory Szorc
packaging: support building WiX installers with PyOxidizer...
r45274 """Build a WiX MSI installer using py2exe.
Gregory Szorc
packaging: convert files to LF...
r42118
``source_dir`` is the path to the Mercurial source tree to use.
``arch`` is the target architecture. either ``x86`` or ``x64``.
``python_exe`` is the path to the Python executable to use/bundle.
``version`` is the Mercurial version string. If not defined,
``mercurial/__version__.py`` will be consulted.
Augie Fackler
wix: add a hook for a prebuild script to inject extra libraries...
r42214 ``extra_packages_script`` is a command to be run to inject extra packages
into the py2exe binary. It should stage packages into the virtualenv and
print a null byte followed by a newline-separated list of packages that
should be included in the exe.
Augie Fackler
wix: add support for additional wxs files...
r42215 ``extra_wxs`` is a dict of {wxs_name: working_dir_for_wxs_build}.
Augie Fackler
wix: add functionality to inject additional Features into installer...
r42216 ``extra_features`` is a list of additional named Features to include in
the build. These must match Feature names in one of the wxs scripts.
Gregory Szorc
packaging: convert files to LF...
r42118 """
arch = 'x64' if r'\x64' in os.environ.get('LIB', '') else 'x86'
hg_build_dir = source_dir / 'build'
Matt Harbison
packaging: make the path to Win32 requirements absolute when building WiX...
r44724 requirements_txt = (
Gregory Szorc
contrib: split Windows requirements into multiple files...
r46344 source_dir / 'contrib' / 'packaging' / 'requirements-windows-py2.txt'
Matt Harbison
packaging: make the path to Win32 requirements absolute when building WiX...
r44724 )
Gregory Szorc
packaging: convert files to LF...
r42118
Augie Fackler
formatting: blacken the codebase...
r43346 build_py2exe(
source_dir,
hg_build_dir,
python_exe,
'wix',
requirements_txt,
extra_packages=EXTRA_PACKAGES,
extra_packages_script=extra_packages_script,
Matt Harbison
packaging: include `windows_curses` when building py2exe...
r47110 extra_includes=EXTRA_INCLUDES,
Augie Fackler
formatting: blacken the codebase...
r43346 )
Gregory Szorc
packaging: convert files to LF...
r42118
build_dir = hg_build_dir / ('wix-%s' % arch)
Gregory Szorc
packaging: stage files and dynamically generate WiX installer...
r44022 staging_dir = build_dir / 'stage'
Gregory Szorc
packaging: convert files to LF...
r42118
build_dir.mkdir(exist_ok=True)
Gregory Szorc
packaging: stage files and dynamically generate WiX installer...
r44022 # Purge the staging directory for every build so packaging is pristine.
if staging_dir.exists():
print('purging %s' % staging_dir)
shutil.rmtree(staging_dir)
stage_install(source_dir, staging_dir, lower_case=True)
# We also install some extra files.
process_install_rules(EXTRA_INSTALL_RULES, source_dir, staging_dir)
# And remove some files we don't want.
for f in STAGING_REMOVE_FILES:
p = staging_dir / f
if p.exists():
print('removing %s' % p)
p.unlink()
Gregory Szorc
packaging: isolate invocation of WiX to own function...
r45271 return run_wix_packaging(
source_dir,
build_dir,
staging_dir,
arch,
version=version,
Gregory Szorc
packaging: support building WiX installers with PyOxidizer...
r45274 python2=True,
msi_name=msi_name,
Gregory Szorc
packaging: add -python2 to Windows installer filenames...
r45276 suffix="-python2",
Gregory Szorc
packaging: support building WiX installers with PyOxidizer...
r45274 extra_wxs=extra_wxs,
extra_features=extra_features,
signing_info=signing_info,
)
def build_installer_pyoxidizer(
source_dir: pathlib.Path,
target_triple: str,
msi_name='mercurial',
version=None,
extra_wxs: typing.Optional[typing.Dict[str, str]] = None,
extra_features: typing.Optional[typing.List[str]] = None,
signing_info: typing.Optional[typing.Dict[str, str]] = None,
Augie Fackler
packaging: add command line flag to add extra vars to pyoxidizer...
r48444 extra_pyoxidizer_vars=None,
Gregory Szorc
packaging: support building WiX installers with PyOxidizer...
r45274 ):
"""Build a WiX MSI installer using PyOxidizer."""
hg_build_dir = source_dir / "build"
build_dir = hg_build_dir / ("wix-%s" % target_triple)
build_dir.mkdir(parents=True, exist_ok=True)
Gregory Szorc
packaging: use PyOxidizer for producing WiX MSI installer...
r47981
# Need to ensure docs HTML is built because this isn't done as part of
# `pip install Mercurial`.
build_docs_html(source_dir)
build_vars = {}
if msi_name:
build_vars["MSI_NAME"] = msi_name
if version:
build_vars["VERSION"] = version
if extra_features:
build_vars["EXTRA_MSI_FEATURES"] = ";".join(extra_features)
if signing_info:
if signing_info["cert_path"]:
build_vars["SIGNING_PFX_PATH"] = signing_info["cert_path"]
if signing_info["cert_password"]:
build_vars["SIGNING_PFX_PASSWORD"] = signing_info["cert_password"]
if signing_info["subject_name"]:
build_vars["SIGNING_SUBJECT_NAME"] = signing_info["subject_name"]
if signing_info["timestamp_url"]:
build_vars["TIME_STAMP_SERVER_URL"] = signing_info["timestamp_url"]
Augie Fackler
packaging: add command line flag to add extra vars to pyoxidizer...
r48444 if extra_pyoxidizer_vars:
build_vars.update(json.loads(extra_pyoxidizer_vars))
Gregory Szorc
packaging: use PyOxidizer for producing WiX MSI installer...
r47981 if extra_wxs:
raise Exception(
"support for extra .wxs files has been temporarily dropped"
)
out_dir = run_pyoxidizer(
source_dir,
build_dir,
target_triple,
build_vars=build_vars,
target="msi",
Gregory Szorc
packaging: rename run_pyoxidizer()...
r47979 )
Gregory Szorc
packaging: support building WiX installers with PyOxidizer...
r45274
Gregory Szorc
packaging: use PyOxidizer for producing WiX MSI installer...
r47981 msi_dir = out_dir / "msi"
msi_files = [f for f in os.listdir(msi_dir) if f.endswith(".msi")]
Gregory Szorc
packaging: support building WiX installers with PyOxidizer...
r45274
Gregory Szorc
packaging: use PyOxidizer for producing WiX MSI installer...
r47981 if len(msi_files) != 1:
raise Exception("expected exactly 1 .msi file; got %d" % len(msi_files))
msi_filename = msi_files[0]
Gregory Szorc
packaging: support building WiX installers with PyOxidizer...
r45274
Gregory Szorc
packaging: use PyOxidizer for producing WiX MSI installer...
r47981 msi_path = msi_dir / msi_filename
dist_path = source_dir / "dist" / msi_filename
dist_path.parent.mkdir(parents=True, exist_ok=True)
shutil.copyfile(msi_path, dist_path)
return {
"msi_path": dist_path,
}
Gregory Szorc
packaging: isolate invocation of WiX to own function...
r45271
def run_wix_packaging(
source_dir: pathlib.Path,
build_dir: pathlib.Path,
staging_dir: pathlib.Path,
arch: str,
version: str,
Gregory Szorc
packaging: support building WiX installers with PyOxidizer...
r45274 python2: bool,
Gregory Szorc
packaging: isolate invocation of WiX to own function...
r45271 msi_name: typing.Optional[str] = "mercurial",
Gregory Szorc
packaging: add -python2 to Windows installer filenames...
r45276 suffix: str = "",
Gregory Szorc
packaging: isolate invocation of WiX to own function...
r45271 extra_wxs: typing.Optional[typing.Dict[str, str]] = None,
extra_features: typing.Optional[typing.List[str]] = None,
Gregory Szorc
packaging: integrate signing into run_wix_packaging()...
r45272 signing_info: typing.Optional[typing.Dict[str, str]] = None,
Gregory Szorc
packaging: isolate invocation of WiX to own function...
r45271 ):
Gregory Szorc
packaging: integrate signing into run_wix_packaging()...
r45272 """Invokes WiX to package up a built Mercurial.
``signing_info`` is a dict defining properties to facilitate signing the
installer. Recognized keys include ``name``, ``subject_name``,
``cert_path``, ``cert_password``, and ``timestamp_url``. If populated,
we will sign both the hg.exe and the .msi using the signing credentials
specified.
"""
Gregory Szorc
packaging: move version derivation to run_wix_packaging()...
r45273
orig_version = version or find_version(source_dir)
version = normalize_windows_version(orig_version)
print('using version string: %s' % version)
if version != orig_version:
print('(normalized from: %s)' % orig_version)
Gregory Szorc
packaging: integrate signing into run_wix_packaging()...
r45272 if signing_info:
sign_with_signtool(
staging_dir / "hg.exe",
"%s %s" % (signing_info["name"], version),
subject_name=signing_info["subject_name"],
cert_path=signing_info["cert_path"],
cert_password=signing_info["cert_password"],
timestamp_url=signing_info["timestamp_url"],
)
Gregory Szorc
packaging: isolate invocation of WiX to own function...
r45271
wix_dir = source_dir / 'contrib' / 'packaging' / 'wix'
wix_pkg, wix_entry = download_entry('wix', build_dir)
wix_path = build_dir / ('wix-%s' % wix_entry['version'])
Gregory Szorc
packaging: convert files to LF...
r42118
if not wix_path.exists():
extract_zip_to_directory(wix_pkg, wix_path)
Gregory Szorc
packaging: support building WiX installers with PyOxidizer...
r45274 if python2:
ensure_vc90_merge_modules(build_dir)
Gregory Szorc
packaging: convert files to LF...
r42118
source_build_rel = pathlib.Path(os.path.relpath(source_dir, build_dir))
defines = {'Platform': arch}
Gregory Szorc
packaging: stage files and dynamically generate WiX installer...
r44022 # Derive a .wxs file with the staged files.
manifest_wxs = build_dir / 'stage.wxs'
with manifest_wxs.open('w', encoding='utf-8') as fh:
fh.write(make_files_xml(staging_dir, is_x64=arch == 'x64'))
run_candle(wix_path, build_dir, manifest_wxs, staging_dir, defines=defines)
Gregory Szorc
packaging: convert files to LF...
r42118
Augie Fackler
wix: add support for additional wxs files...
r42215 for source, rel_path in sorted((extra_wxs or {}).items()):
run_candle(wix_path, build_dir, source, rel_path, defines=defines)
Gregory Szorc
wix: introduce variable to hold path to wix packaging directory...
r42122 source = wix_dir / 'mercurial.wxs'
Gregory Szorc
packaging: convert files to LF...
r42118 defines['Version'] = version
defines['Comments'] = 'Installs Mercurial version %s' % version
Gregory Szorc
packaging: support building WiX installers with PyOxidizer...
r45274
if python2:
defines["PythonVersion"] = "2"
defines['VCRedistSrcDir'] = str(build_dir)
else:
defines["PythonVersion"] = "3"
if (staging_dir / "lib").exists():
defines["MercurialHasLib"] = "1"
Augie Fackler
wix: add functionality to inject additional Features into installer...
r42216 if extra_features:
assert all(';' not in f for f in extra_features)
defines['MercurialExtraFeatures'] = ';'.join(extra_features)
Gregory Szorc
packaging: convert files to LF...
r42118
run_candle(wix_path, build_dir, source, source_build_rel, defines=defines)
Augie Fackler
formatting: blacken the codebase...
r43346 msi_path = (
Gregory Szorc
packaging: add -python2 to Windows installer filenames...
r45276 source_dir
/ 'dist'
/ ('%s-%s-%s%s.msi' % (msi_name, orig_version, arch, suffix))
Augie Fackler
formatting: blacken the codebase...
r43346 )
Gregory Szorc
packaging: convert files to LF...
r42118
args = [
str(wix_path / 'light.exe'),
'-nologo',
Augie Fackler
formatting: blacken the codebase...
r43346 '-ext',
'WixUIExtension',
Gregory Szorc
packaging: convert files to LF...
r42118 '-sw1076',
'-spdb',
Augie Fackler
formatting: blacken the codebase...
r43346 '-o',
str(msi_path),
Gregory Szorc
packaging: convert files to LF...
r42118 ]
Augie Fackler
wix: add support for additional wxs files...
r42215 for source, rel_path in sorted((extra_wxs or {}).items()):
assert source.endswith('.wxs')
source = os.path.basename(source)
args.append(str(build_dir / ('%s.wixobj' % source[:-4])))
Augie Fackler
formatting: blacken the codebase...
r43346 args.extend(
Augie Fackler
formating: upgrade to black 20.8b1...
r46554 [
str(build_dir / 'stage.wixobj'),
str(build_dir / 'mercurial.wixobj'),
]
Augie Fackler
formatting: blacken the codebase...
r43346 )
Gregory Szorc
packaging: convert files to LF...
r42118
subprocess.run(args, cwd=str(source_dir), check=True)
print('%s created' % msi_path)
Gregory Szorc
packaging: integrate signing into run_wix_packaging()...
r45272 if signing_info:
sign_with_signtool(
msi_path,
"%s %s" % (signing_info["name"], version),
subject_name=signing_info["subject_name"],
cert_path=signing_info["cert_path"],
cert_password=signing_info["cert_password"],
timestamp_url=signing_info["timestamp_url"],
)
Gregory Szorc
packaging: convert files to LF...
r42118 return {
'msi_path': msi_path,
}