##// END OF EJS Templates
procutil: avoid `+= None` when writing to full std{err,out} descriptor on py3...
procutil: avoid `+= None` when writing to full std{err,out} descriptor on py3 The write function returns `None` if there was no room to write the given data[1]. I don't like that this is effectively an infinite loop if there's never any progress emptying the underlying buffer, but we're no worse off than before, and it fixes random stacktrace popups seen in the py3 build of TortoiseHg. [1] https://docs.python.org/3/library/io.html#io.RawIOBase.write Differential Revision: https://phab.mercurial-scm.org/D12555

File last commit:

r49845:8d7eaff9 default
r49958:90e56488 stable
Show More
pyoxidizer.py
175 lines | 5.1 KiB | text/x-python | PythonLexer
Gregory Szorc
packaging: support building Inno installer with PyOxidizer...
r45270 # pyoxidizer.py - Packaging support for PyOxidizer
#
# Copyright 2020 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
import sys
Gregory Szorc
packaging: use PyOxidizer for producing WiX MSI installer...
r47981 import typing
Gregory Szorc
packaging: support building Inno installer with PyOxidizer...
r45270
from .downloads import download_entry
from .util import (
extract_zip_to_directory,
process_install_rules,
find_vc_runtime_dll,
)
STAGING_RULES_WINDOWS = [
('contrib/bash_completion', 'contrib/'),
('contrib/hgk', 'contrib/hgk.tcl'),
('contrib/hgweb.fcgi', 'contrib/'),
('contrib/hgweb.wsgi', 'contrib/'),
('contrib/logo-droplets.svg', 'contrib/'),
('contrib/mercurial.el', 'contrib/'),
('contrib/mq.el', 'contrib/'),
('contrib/tcsh_completion', 'contrib/'),
('contrib/tcsh_completion_build.sh', 'contrib/'),
('contrib/vim/*', 'contrib/vim/'),
('contrib/win32/postinstall.txt', 'ReleaseNotes.txt'),
('contrib/win32/ReadMe.html', 'ReadMe.html'),
('contrib/xml.rnc', 'contrib/'),
('contrib/zsh_completion', 'contrib/'),
('doc/*.html', 'doc/'),
('doc/style.css', 'doc/'),
('COPYING', 'Copying.txt'),
]
STAGING_RULES_APP = [
Gregory Szorc
pyoxidizer: produce working Python 3 Windows installers (issue6366)...
r46277 ('lib/mercurial/helptext/**/*.txt', 'helptext/'),
('lib/mercurial/defaultrc/*.rc', 'defaultrc/'),
('lib/mercurial/locale/**/*', 'locale/'),
('lib/mercurial/templates/**/*', 'templates/'),
Gregory Szorc
packaging: support building Inno installer with PyOxidizer...
r45270 ]
STAGING_EXCLUDES_WINDOWS = [
"doc/hg-ssh.8.html",
]
Gregory Szorc
packaging: move documentation HTML building to own function...
r47978 def build_docs_html(source_dir: pathlib.Path):
"""Ensures HTML documentation is built.
This will fail if docutils isn't available.
(The HTML docs aren't built as part of `pip install` so we need to build them
out of band.)
"""
subprocess.run(
[sys.executable, str(source_dir / "setup.py"), "build_doc", "--html"],
cwd=str(source_dir),
check=True,
)
Gregory Szorc
packaging: extract invocation of pyoxidizer to own function...
r47980 def run_pyoxidizer(
Gregory Szorc
packaging: use PyOxidizer for producing WiX MSI installer...
r47981 source_dir: pathlib.Path,
build_dir: pathlib.Path,
target_triple: str,
build_vars: typing.Optional[typing.Dict[str, str]] = None,
target: typing.Optional[str] = None,
Gregory Szorc
packaging: extract invocation of pyoxidizer to own function...
r47980 ) -> pathlib.Path:
"""Run `pyoxidizer` in an environment with access to build dependencies.
Gregory Szorc
packaging: support building Inno installer with PyOxidizer...
r45270
Gregory Szorc
packaging: extract invocation of pyoxidizer to own function...
r47980 Returns the output directory that pyoxidizer would have used for build
artifacts. Actual build artifacts are likely in a sub-directory with the
name of the pyoxidizer build target that was built.
Gregory Szorc
packaging: support building Inno installer with PyOxidizer...
r45270 """
Gregory Szorc
packaging: use PyOxidizer for producing WiX MSI installer...
r47981 build_vars = build_vars or {}
Gregory Szorc
packaging: support building Inno installer with PyOxidizer...
r45270 # We need to make gettext binaries available for compiling i18n files.
gettext_pkg, gettext_entry = download_entry('gettext', build_dir)
gettext_dep_pkg = download_entry('gettext-dep', build_dir)[0]
gettext_root = build_dir / ('gettext-win-%s' % gettext_entry['version'])
if not gettext_root.exists():
extract_zip_to_directory(gettext_pkg, gettext_root)
extract_zip_to_directory(gettext_dep_pkg, gettext_root)
env = dict(os.environ)
env["PATH"] = "%s%s%s" % (
env["PATH"],
os.pathsep,
str(gettext_root / "bin"),
)
args = [
"pyoxidizer",
"build",
"--path",
str(source_dir / "rust" / "hgcli"),
"--release",
"--target-triple",
target_triple,
]
Gregory Szorc
packaging: use PyOxidizer for producing WiX MSI installer...
r47981 for k, v in sorted(build_vars.items()):
args.extend(["--var", k, v])
if target:
args.append(target)
Gregory Szorc
packaging: support building Inno installer with PyOxidizer...
r45270 subprocess.run(args, env=env, check=True)
Gregory Szorc
packaging: extract invocation of pyoxidizer to own function...
r47980 return source_dir / "build" / "pyoxidizer" / target_triple / "release"
def create_pyoxidizer_install_layout(
source_dir: pathlib.Path,
build_dir: pathlib.Path,
out_dir: pathlib.Path,
target_triple: str,
):
"""Build Mercurial with PyOxidizer and copy additional files into place.
After successful completion, ``out_dir`` contains files constituting a
Mercurial install.
"""
run_pyoxidizer(source_dir, build_dir, target_triple)
Gregory Szorc
packaging: support building Inno installer with PyOxidizer...
r45270 build_dir = (
Gregory Szorc
packaging: reference proper output directory...
r48696 source_dir / "build" / "pyoxidizer" / target_triple / "release" / "app"
Gregory Szorc
packaging: support building Inno installer with PyOxidizer...
r45270 )
if out_dir.exists():
print("purging %s" % out_dir)
shutil.rmtree(out_dir)
# Now assemble all the files from PyOxidizer into the staging directory.
shutil.copytree(build_dir, out_dir)
Gregory Szorc
pyoxidizer: produce working Python 3 Windows installers (issue6366)...
r46277 # Move some of those files around. We can get rid of this once Mercurial
# is taught to use the importlib APIs for reading resources.
Gregory Szorc
packaging: support building Inno installer with PyOxidizer...
r45270 process_install_rules(STAGING_RULES_APP, build_dir, out_dir)
Gregory Szorc
packaging: move documentation HTML building to own function...
r47978 build_docs_html(source_dir)
Gregory Szorc
packaging: support building Inno installer with PyOxidizer...
r45270
if "windows" in target_triple:
process_install_rules(STAGING_RULES_WINDOWS, source_dir, out_dir)
# Write out a default editor.rc file to configure notepad as the
# default editor.
Augie Fackler
pyoxidizer: make sure defaultrc directory exists before trying to write to it...
r46534 os.makedirs(out_dir / "defaultrc", exist_ok=True)
Gregory Szorc
packaging: support building Inno installer with PyOxidizer...
r45270 with (out_dir / "defaultrc" / "editor.rc").open(
"w", encoding="utf-8"
) as fh:
fh.write("[ui]\neditor = notepad\n")
for f in STAGING_EXCLUDES_WINDOWS:
p = out_dir / f
if p.exists():
print("removing %s" % p)
p.unlink()
# Add vcruntimeXXX.dll next to executable.
vc_runtime_dll = find_vc_runtime_dll(x64="x86_64" in target_triple)
shutil.copy(vc_runtime_dll, out_dir / vc_runtime_dll.name)