D7159: packaging: stage installed files for Inno
indygreg (Gregory Szorc)
phabricator at mercurial-scm.org
Sat Nov 9 00:05:09 UTC 2019
Closed by commit rHGd2ea31a2546d: packaging: stage installed files for Inno (authored by indygreg).
This revision was automatically updated to reflect the committed changes.
This revision was not accepted when it landed; it landed in state "Needs Review".
REPOSITORY
rHG Mercurial
CHANGES SINCE LAST UPDATE
https://phab.mercurial-scm.org/D7159?vs=17380&id=17811
CHANGES SINCE LAST ACTION
https://phab.mercurial-scm.org/D7159/new/
REVISION DETAIL
https://phab.mercurial-scm.org/D7159
AFFECTED FILES
contrib/packaging/hgpackaging/inno.py
contrib/packaging/hgpackaging/py2exe.py
contrib/packaging/hgpackaging/util.py
contrib/packaging/inno/mercurial.iss
CHANGE DETAILS
diff --git a/contrib/packaging/inno/mercurial.iss b/contrib/packaging/inno/mercurial.iss
--- a/contrib/packaging/inno/mercurial.iss
+++ b/contrib/packaging/inno/mercurial.iss
@@ -33,8 +33,8 @@
AppVerName=Mercurial {#VERSION}
OutputBaseFilename=Mercurial-{#VERSION}
#endif
-InfoAfterFile=contrib/win32/postinstall.txt
-LicenseFile=COPYING
+InfoAfterFile=../postinstall.txt
+LicenseFile=Copying.txt
ShowLanguageDialog=yes
AppPublisher=Matt Mackall and others
AppPublisherURL=https://mercurial-scm.org/
@@ -43,49 +43,23 @@
{{ 'AppID={{4B95A5F1-EF59-4B08-BED8-C891C46121B3}' }}
AppContact=mercurial at mercurial-scm.org
DefaultDirName={pf}\Mercurial
-SourceDir=..\..
+SourceDir=stage
VersionInfoDescription=Mercurial distributed SCM (version {#VERSION})
VersionInfoCopyright=Copyright 2005-2019 Matt Mackall and others
VersionInfoCompany=Matt Mackall and others
InternalCompressLevel=max
SolidCompression=true
-SetupIconFile=contrib\win32\mercurial.ico
+SetupIconFile=../mercurial.ico
AllowNoIcons=true
DefaultGroupName=Mercurial
PrivilegesRequired=none
ChangesEnvironment=true
[Files]
-Source: contrib\mercurial.el; DestDir: {app}/Contrib
-Source: contrib\vim\*.*; DestDir: {app}/Contrib/Vim
-Source: contrib\zsh_completion; DestDir: {app}/Contrib
-Source: contrib\bash_completion; DestDir: {app}/Contrib
-Source: contrib\tcsh_completion; DestDir: {app}/Contrib
-Source: contrib\tcsh_completion_build.sh; DestDir: {app}/Contrib
-Source: contrib\hgk; DestDir: {app}/Contrib; DestName: hgk.tcl
-Source: contrib\xml.rnc; DestDir: {app}/Contrib
-Source: contrib\mercurial.el; DestDir: {app}/Contrib
-Source: contrib\mq.el; DestDir: {app}/Contrib
-Source: contrib\hgweb.fcgi; DestDir: {app}/Contrib
-Source: contrib\hgweb.wsgi; DestDir: {app}/Contrib
-Source: contrib\win32\ReadMe.html; DestDir: {app}; Flags: isreadme
-Source: contrib\win32\postinstall.txt; DestDir: {app}; DestName: ReleaseNotes.txt
-Source: dist\hg.exe; DestDir: {app}; AfterInstall: Touch('{app}\hg.exe.local')
-Source: dist\lib\*.dll; Destdir: {app}\lib
-Source: dist\lib\*.pyd; Destdir: {app}\lib
-Source: dist\python*.dll; Destdir: {app}; Flags: skipifsourcedoesntexist
-Source: dist\msvc*.dll; DestDir: {app}; Flags: skipifsourcedoesntexist
-Source: dist\Microsoft.VC*.CRT.manifest; DestDir: {app}; Flags: skipifsourcedoesntexist
-Source: dist\lib\library.zip; DestDir: {app}\lib
-Source: doc\*.html; DestDir: {app}\Docs
-Source: doc\style.css; DestDir: {app}\Docs
-Source: mercurial\help\*.txt; DestDir: {app}\help
-Source: mercurial\help\internals\*.txt; DestDir: {app}\help\internals
-Source: mercurial\default.d\*.rc; DestDir: {app}\default.d
-Source: mercurial\locale\*.*; DestDir: {app}\locale; Flags: recursesubdirs createallsubdirs skipifsourcedoesntexist
-Source: mercurial\templates\*.*; DestDir: {app}\Templates; Flags: recursesubdirs createallsubdirs
-Source: CONTRIBUTORS; DestDir: {app}; DestName: Contributors.txt
-Source: COPYING; DestDir: {app}; DestName: Copying.txt
+{% for entry in package_files -%}
+Source: {{ entry.source }}; DestDir: {{ entry.dest_dir }}
+{%- if entry.metadata %}; {{ entry.metadata }}{% endif %}
+{% endfor %}
[INI]
Filename: {app}\Mercurial.url; Section: InternetShortcut; Key: URL; String: https://mercurial-scm.org/
diff --git a/contrib/packaging/hgpackaging/util.py b/contrib/packaging/hgpackaging/util.py
--- a/contrib/packaging/hgpackaging/util.py
+++ b/contrib/packaging/hgpackaging/util.py
@@ -9,8 +9,10 @@
import distutils.version
import getpass
+import glob
import os
import pathlib
+import shutil
import subprocess
import tarfile
import zipfile
@@ -164,3 +166,47 @@
'version': version,
'py3': version >= distutils.version.LooseVersion('3'),
}
+
+
+def process_install_rules(
+ rules: list, source_dir: pathlib.Path, dest_dir: pathlib.Path
+):
+ for source, dest in rules:
+ if '*' in source:
+ if not dest.endswith('/'):
+ raise ValueError('destination must end in / when globbing')
+
+ # We strip off the source path component before the first glob
+ # character to construct the relative install path.
+ prefix_end_index = source[: source.index('*')].rindex('/')
+ relative_prefix = source_dir / source[0:prefix_end_index]
+
+ for res in glob.glob(str(source_dir / source), recursive=True):
+ source_path = pathlib.Path(res)
+
+ if source_path.is_dir():
+ continue
+
+ rel_path = source_path.relative_to(relative_prefix)
+
+ dest_path = dest_dir / dest[:-1] / rel_path
+
+ dest_path.parent.mkdir(parents=True, exist_ok=True)
+ print('copying %s to %s' % (source_path, dest_path))
+ shutil.copy(source_path, dest_path)
+
+ # Simple file case.
+ else:
+ source_path = pathlib.Path(source)
+
+ if dest.endswith('/'):
+ dest_path = pathlib.Path(dest) / source_path.name
+ else:
+ dest_path = pathlib.Path(dest)
+
+ full_source_path = source_dir / source_path
+ full_dest_path = dest_dir / dest_path
+
+ full_dest_path.parent.mkdir(parents=True, exist_ok=True)
+ shutil.copy(full_source_path, full_dest_path)
+ print('copying %s to %s' % (full_source_path, full_dest_path))
diff --git a/contrib/packaging/hgpackaging/py2exe.py b/contrib/packaging/hgpackaging/py2exe.py
--- a/contrib/packaging/hgpackaging/py2exe.py
+++ b/contrib/packaging/hgpackaging/py2exe.py
@@ -15,10 +15,43 @@
from .util import (
extract_tar_to_directory,
extract_zip_to_directory,
+ process_install_rules,
python_exe_info,
)
+STAGING_RULES = [
+ ('contrib/bash_completion', 'Contrib/'),
+ ('contrib/hgk', 'Contrib/hgk.tcl'),
+ ('contrib/hgweb.fcgi', 'Contrib/'),
+ ('contrib/hgweb.wsgi', '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/'),
+ ('dist/hg.exe', './'),
+ ('dist/lib/*.dll', 'lib/'),
+ ('dist/lib/*.pyd', 'lib/'),
+ ('dist/lib/library.zip', 'lib/'),
+ ('dist/Microsoft.VC*.CRT.manifest', './'),
+ ('dist/msvc*.dll', './'),
+ ('dist/python*.dll', './'),
+ ('doc/*.html', 'Docs/'),
+ ('doc/style.css', 'Docs/'),
+ ('mercurial/help/**/*.txt', 'help/'),
+ ('mercurial/default.d/*.rc', 'default.d/'),
+ ('mercurial/locale/**/*', 'locale/'),
+ ('mercurial/templates/**/*', 'Templates/'),
+ ('CONTRIBUTORS', 'Contributors.txt'),
+ ('COPYING', 'Copying.txt'),
+]
+
+
def build_py2exe(
source_dir: pathlib.Path,
build_dir: pathlib.Path,
@@ -169,3 +202,12 @@
env=env,
check=True,
)
+
+
+def stage_install(source_dir: pathlib.Path, staging_dir: pathlib.Path):
+ """Copy all files to be installed to a directory.
+
+ This allows packaging to simply walk a directory tree to find source
+ files.
+ """
+ process_install_rules(STAGING_RULES, source_dir, staging_dir)
diff --git a/contrib/packaging/hgpackaging/inno.py b/contrib/packaging/hgpackaging/inno.py
--- a/contrib/packaging/hgpackaging/inno.py
+++ b/contrib/packaging/hgpackaging/inno.py
@@ -14,7 +14,10 @@
import jinja2
-from .py2exe import build_py2exe
+from .py2exe import (
+ build_py2exe,
+ stage_install,
+)
from .util import find_vc_runtime_files
EXTRA_PACKAGES = {
@@ -24,6 +27,11 @@
'win32ctypes',
}
+PACKAGE_FILES_METADATA = {
+ 'ReadMe.html': 'Flags: isreadme',
+ 'hg.exe': "AfterInstall: Touch('{app}\\hg.exe.local')",
+}
+
def build(
source_dir: pathlib.Path,
@@ -47,6 +55,7 @@
arch = 'x64' if vc_x64 else 'x86'
inno_source_dir = source_dir / 'contrib' / 'packaging' / 'inno'
inno_build_dir = build_dir / ('inno-%s' % arch)
+ staging_dir = inno_build_dir / 'stage'
requirements_txt = (
source_dir / 'contrib' / 'packaging' / 'inno' / 'requirements.txt'
@@ -63,6 +72,15 @@
extra_packages=EXTRA_PACKAGES,
)
+ # 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)
+
# 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'):
@@ -70,11 +88,34 @@
else:
basename = f.name
- dest_path = source_dir / 'dist' / basename
+ dest_path = staging_dir / basename
print('copying %s to %s' % (f, dest_path))
shutil.copyfile(f, dest_path)
+ # 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),
+ }
+ )
+
print('creating installer')
# Install Inno files by rendering a template.
@@ -93,11 +134,17 @@
% (e.name, e.lineno, e.message,)
)
- content = template.render()
+ content = template.render(package_files=package_files)
with (inno_build_dir / 'mercurial.iss').open('w', encoding='utf-8') as fh:
fh.write(content)
+ # Copy additional files used by Inno.
+ for p in ('mercurial.ico', 'postinstall.txt'):
+ shutil.copyfile(
+ source_dir / 'contrib' / 'win32' / p, inno_build_dir / p
+ )
+
args = [str(iscc_exe)]
if vc_x64:
To: indygreg, #hg-reviewers
Cc: mercurial-devel
More information about the Mercurial-devel
mailing list