changeset 42047:715d3220ac4f

wix: add a hook for a prebuild script to inject extra libraries I need this to build packages for Google so we can bundle some extensions in the installed image. My assumption is that this is most interesting for the .msi images so I only wired it up there. I'm not thrilled with the interface this provides, but it was an easy way to retain debug messages on Windows while also having enough structure to know what lines are actually module names for py2exe. Still pending on my end: I need to bundle a couple of config files, and at least one data file. I'm open to advice on how to do those things, and how to do this better. Differential Revision: https://phab.mercurial-scm.org/D6164
author Augie Fackler <augie@google.com>
date Wed, 20 Mar 2019 13:18:37 -0400
parents 4ee906aa7b60
children 978b03d5f66e
files contrib/packaging/hgpackaging/py2exe.py contrib/packaging/hgpackaging/wix.py contrib/packaging/wix/build.py
diffstat 3 files changed, 29 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/contrib/packaging/hgpackaging/py2exe.py	Wed Mar 27 18:26:54 2019 +0100
+++ b/contrib/packaging/hgpackaging/py2exe.py	Wed Mar 20 13:18:37 2019 -0400
@@ -25,7 +25,8 @@
                  python_exe: pathlib.Path, build_name: str,
                  venv_requirements_txt: pathlib.Path,
                  extra_packages=None, extra_excludes=None,
-                 extra_dll_excludes=None):
+                 extra_dll_excludes=None,
+                 extra_packages_script=None):
     """Build Mercurial with py2exe.
 
     Build files will be placed in ``build_dir``.
@@ -105,6 +106,16 @@
     env['DISTUTILS_USE_SDK'] = '1'
     env['MSSdk'] = '1'
 
+    if extra_packages_script:
+        more_packages = set(subprocess.check_output(
+            extra_packages_script,
+            cwd=build_dir).split(b'\0')[-1].strip().decode('utf-8').splitlines())
+        if more_packages:
+            if not extra_packages:
+                extra_packages = more_packages
+            else:
+                extra_packages |= more_packages
+
     if extra_packages:
         env['HG_PY2EXE_EXTRA_PACKAGES'] = ' '.join(sorted(extra_packages))
     if extra_excludes:
--- a/contrib/packaging/hgpackaging/wix.py	Wed Mar 27 18:26:54 2019 +0100
+++ b/contrib/packaging/hgpackaging/wix.py	Wed Mar 20 13:18:37 2019 -0400
@@ -177,7 +177,8 @@
 
 
 def build_installer(source_dir: pathlib.Path, python_exe: pathlib.Path,
-                    msi_name='mercurial', version=None, post_build_fn=None):
+                    msi_name='mercurial', version=None, post_build_fn=None,
+                    extra_packages_script=None):
     """Build a WiX MSI installer.
 
     ``source_dir`` is the path to the Mercurial source tree to use.
@@ -189,6 +190,10 @@
     Mercurial but before invoking WiX. It can be used to e.g. facilitate
     signing. It is passed the paths to the Mercurial source, build, and
     dist directories and the resolved Mercurial version.
+    ``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.
     """
     arch = 'x64' if r'\x64' in os.environ.get('LIB', '') else 'x86'
 
@@ -200,7 +205,8 @@
 
     build_py2exe(source_dir, hg_build_dir,
                  python_exe, 'wix', requirements_txt,
-                 extra_packages=EXTRA_PACKAGES)
+                 extra_packages=EXTRA_PACKAGES,
+                 extra_packages_script=extra_packages_script)
 
     version = version or normalize_version(find_version(source_dir))
     print('using version string: %s' % version)
@@ -280,7 +286,7 @@
 def build_signed_installer(source_dir: pathlib.Path, python_exe: pathlib.Path,
                            name: str, version=None, subject_name=None,
                            cert_path=None, cert_password=None,
-                           timestamp_url=None):
+                           timestamp_url=None, extra_packages_script=None):
     """Build an installer with signed executables."""
 
     post_build_fn = make_post_build_signing_fn(
@@ -292,7 +298,8 @@
 
     info = build_installer(source_dir, python_exe=python_exe,
                            msi_name=name.lower(), version=version,
-                           post_build_fn=post_build_fn)
+                           post_build_fn=post_build_fn,
+                           extra_packages_script=extra_packages_script)
 
     description = '%s %s' % (name, version)
 
--- a/contrib/packaging/wix/build.py	Wed Mar 27 18:26:54 2019 +0100
+++ b/contrib/packaging/wix/build.py	Wed Mar 20 13:18:37 2019 -0400
@@ -34,6 +34,9 @@
                         help='URL of timestamp server to use for signing')
     parser.add_argument('--version',
                         help='Version string to use')
+    parser.add_argument('--extra-packages-script',
+                        help=('Script to execute to include extra packages in '
+                              'py2exe binary.'))
 
     args = parser.parse_args()
 
@@ -54,6 +57,9 @@
         'version': args.version,
     }
 
+    if args.extra_packages_script:
+        kwargs['extra_packages_script'] = args.extra_packages_script
+
     if args.sign_sn or args.sign_cert:
         fn = build_signed_installer
         kwargs['name'] = args.name