contrib/packaging/hgpackaging/util.py
author Matt Harbison <matt_harbison@yahoo.com>
Mon, 24 Feb 2025 12:14:15 -0500
changeset 53011 d333e14477f1
parent 48848 17d5e25b8e78
permissions -rw-r--r--
packaging: adapt `__version__.py` parsing for `setuptools_scm` output The file is now generated by `setuptools_scm`, which stores values as strings with strong quotes. This avoids the following failure at the end of the Inno installer build: <snip> creating installer Traceback (most recent call last): File "c:\Users\Matt\projects\mercurial\mercurial-devel\contrib\packaging\packaging.py", line 70, in <module> run() File "c:\Users\Matt\projects\mercurial\mercurial-devel\contrib\packaging\packaging.py", line 62, in run cli.main() File "c:\Users\Matt\projects\mercurial\mercurial-devel\contrib\packaging\hgpackaging\cli.py", line 154, in main args.func(**kwargs) File "c:\Users\Matt\projects\mercurial\mercurial-devel\contrib\packaging\hgpackaging\cli.py", line 35, in build_inno inno.build_with_pyoxidizer( File "c:\Users\Matt\projects\mercurial\mercurial-devel\contrib\packaging\hgpackaging\inno.py", line 55, in build_with_pyoxidizer build_installer( File "c:\Users\Matt\projects\mercurial\mercurial-devel\contrib\packaging\hgpackaging\inno.py", line 146, in build_installer version = read_version_py(source_dir) File "c:\Users\Matt\projects\mercurial\mercurial-devel\contrib\packaging\hgpackaging\util.py", line 188, in read_version_py raise Exception('could not parse %s' % p) Exception: could not parse c:\Users\Matt\projects\mercurial\mercurial-devel\mercurial\__version__.py Note that non-tagged builds end up with complex version strings, and include characters that WiX rejects. That's probably fine- we don't do nightly or other non-tagged builds for installers. Also note that while the Inno installer is capable of using this version string as part of the installer, the WiX installer is not for some reason. That installer needs to be built with `--version VERSION` to inject the version into the installer metadata and the filename.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
41952
b83de9150c1c packaging: convert files to LF
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41921
diff changeset
     1
# util.py - Common packaging utility code.
b83de9150c1c packaging: convert files to LF
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41921
diff changeset
     2
#
b83de9150c1c packaging: convert files to LF
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41921
diff changeset
     3
# Copyright 2019 Gregory Szorc <gregory.szorc@gmail.com>
b83de9150c1c packaging: convert files to LF
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41921
diff changeset
     4
#
b83de9150c1c packaging: convert files to LF
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41921
diff changeset
     5
# This software may be used and distributed according to the terms of the
b83de9150c1c packaging: convert files to LF
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41921
diff changeset
     6
# GNU General Public License version 2 or any later version.
b83de9150c1c packaging: convert files to LF
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41921
diff changeset
     7
b83de9150c1c packaging: convert files to LF
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41921
diff changeset
     8
# no-check-code because Python 3 native.
b83de9150c1c packaging: convert files to LF
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41921
diff changeset
     9
43516
d053d3f10b6a packaging: stage installed files for Inno
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43076
diff changeset
    10
import glob
41952
b83de9150c1c packaging: convert files to LF
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41921
diff changeset
    11
import os
b83de9150c1c packaging: convert files to LF
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41921
diff changeset
    12
import pathlib
43518
7c9f63a5cb14 packaging: always pass VERSION into Inno invocation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43516
diff changeset
    13
import re
43516
d053d3f10b6a packaging: stage installed files for Inno
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43076
diff changeset
    14
import shutil
41952
b83de9150c1c packaging: convert files to LF
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41921
diff changeset
    15
import subprocess
b83de9150c1c packaging: convert files to LF
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41921
diff changeset
    16
import zipfile
b83de9150c1c packaging: convert files to LF
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41921
diff changeset
    17
b83de9150c1c packaging: convert files to LF
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41921
diff changeset
    18
b83de9150c1c packaging: convert files to LF
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41921
diff changeset
    19
def extract_zip_to_directory(source: pathlib.Path, dest: pathlib.Path):
b83de9150c1c packaging: convert files to LF
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41921
diff changeset
    20
    with zipfile.ZipFile(source, 'r') as zf:
b83de9150c1c packaging: convert files to LF
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41921
diff changeset
    21
        zf.extractall(dest)
b83de9150c1c packaging: convert files to LF
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41921
diff changeset
    22
b83de9150c1c packaging: convert files to LF
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41921
diff changeset
    23
44763
94f4f2ec7dee packaging: support building Inno installer with PyOxidizer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 44220
diff changeset
    24
def find_vc_runtime_dll(x64=False):
94f4f2ec7dee packaging: support building Inno installer with PyOxidizer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 44220
diff changeset
    25
    """Finds Visual C++ Runtime DLL to include in distribution."""
94f4f2ec7dee packaging: support building Inno installer with PyOxidizer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 44220
diff changeset
    26
    # We invoke vswhere to find the latest Visual Studio install.
94f4f2ec7dee packaging: support building Inno installer with PyOxidizer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 44220
diff changeset
    27
    vswhere = (
94f4f2ec7dee packaging: support building Inno installer with PyOxidizer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 44220
diff changeset
    28
        pathlib.Path(os.environ["ProgramFiles(x86)"])
94f4f2ec7dee packaging: support building Inno installer with PyOxidizer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 44220
diff changeset
    29
        / "Microsoft Visual Studio"
94f4f2ec7dee packaging: support building Inno installer with PyOxidizer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 44220
diff changeset
    30
        / "Installer"
94f4f2ec7dee packaging: support building Inno installer with PyOxidizer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 44220
diff changeset
    31
        / "vswhere.exe"
94f4f2ec7dee packaging: support building Inno installer with PyOxidizer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 44220
diff changeset
    32
    )
94f4f2ec7dee packaging: support building Inno installer with PyOxidizer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 44220
diff changeset
    33
94f4f2ec7dee packaging: support building Inno installer with PyOxidizer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 44220
diff changeset
    34
    if not vswhere.exists():
94f4f2ec7dee packaging: support building Inno installer with PyOxidizer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 44220
diff changeset
    35
        raise Exception(
94f4f2ec7dee packaging: support building Inno installer with PyOxidizer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 44220
diff changeset
    36
            "could not find vswhere.exe: %s does not exist" % vswhere
94f4f2ec7dee packaging: support building Inno installer with PyOxidizer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 44220
diff changeset
    37
        )
94f4f2ec7dee packaging: support building Inno installer with PyOxidizer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 44220
diff changeset
    38
94f4f2ec7dee packaging: support building Inno installer with PyOxidizer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 44220
diff changeset
    39
    args = [
94f4f2ec7dee packaging: support building Inno installer with PyOxidizer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 44220
diff changeset
    40
        str(vswhere),
94f4f2ec7dee packaging: support building Inno installer with PyOxidizer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 44220
diff changeset
    41
        # -products * is necessary to return results from Build Tools
94f4f2ec7dee packaging: support building Inno installer with PyOxidizer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 44220
diff changeset
    42
        # (as opposed to full IDE installs).
94f4f2ec7dee packaging: support building Inno installer with PyOxidizer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 44220
diff changeset
    43
        "-products",
94f4f2ec7dee packaging: support building Inno installer with PyOxidizer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 44220
diff changeset
    44
        "*",
94f4f2ec7dee packaging: support building Inno installer with PyOxidizer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 44220
diff changeset
    45
        "-requires",
94f4f2ec7dee packaging: support building Inno installer with PyOxidizer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 44220
diff changeset
    46
        "Microsoft.VisualCpp.Redist.14.Latest",
94f4f2ec7dee packaging: support building Inno installer with PyOxidizer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 44220
diff changeset
    47
        "-latest",
94f4f2ec7dee packaging: support building Inno installer with PyOxidizer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 44220
diff changeset
    48
        "-property",
94f4f2ec7dee packaging: support building Inno installer with PyOxidizer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 44220
diff changeset
    49
        "installationPath",
94f4f2ec7dee packaging: support building Inno installer with PyOxidizer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 44220
diff changeset
    50
    ]
94f4f2ec7dee packaging: support building Inno installer with PyOxidizer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 44220
diff changeset
    51
94f4f2ec7dee packaging: support building Inno installer with PyOxidizer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 44220
diff changeset
    52
    vs_install_path = pathlib.Path(
94f4f2ec7dee packaging: support building Inno installer with PyOxidizer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 44220
diff changeset
    53
        os.fsdecode(subprocess.check_output(args).strip())
94f4f2ec7dee packaging: support building Inno installer with PyOxidizer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 44220
diff changeset
    54
    )
94f4f2ec7dee packaging: support building Inno installer with PyOxidizer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 44220
diff changeset
    55
94f4f2ec7dee packaging: support building Inno installer with PyOxidizer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 44220
diff changeset
    56
    # This just gets us a path like
94f4f2ec7dee packaging: support building Inno installer with PyOxidizer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 44220
diff changeset
    57
    # C:\Program Files (x86)\Microsoft Visual Studio\2019\Community
94f4f2ec7dee packaging: support building Inno installer with PyOxidizer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 44220
diff changeset
    58
    # Actually vcruntime140.dll is under a path like:
94f4f2ec7dee packaging: support building Inno installer with PyOxidizer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 44220
diff changeset
    59
    # VC\Redist\MSVC\<version>\<arch>\Microsoft.VC14<X>.CRT\vcruntime140.dll.
94f4f2ec7dee packaging: support building Inno installer with PyOxidizer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 44220
diff changeset
    60
94f4f2ec7dee packaging: support building Inno installer with PyOxidizer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 44220
diff changeset
    61
    arch = "x64" if x64 else "x86"
94f4f2ec7dee packaging: support building Inno installer with PyOxidizer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 44220
diff changeset
    62
94f4f2ec7dee packaging: support building Inno installer with PyOxidizer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 44220
diff changeset
    63
    search_glob = (
94f4f2ec7dee packaging: support building Inno installer with PyOxidizer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 44220
diff changeset
    64
        r"%s\VC\Redist\MSVC\*\%s\Microsoft.VC14*.CRT\vcruntime140.dll"
94f4f2ec7dee packaging: support building Inno installer with PyOxidizer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 44220
diff changeset
    65
        % (vs_install_path, arch)
94f4f2ec7dee packaging: support building Inno installer with PyOxidizer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 44220
diff changeset
    66
    )
94f4f2ec7dee packaging: support building Inno installer with PyOxidizer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 44220
diff changeset
    67
94f4f2ec7dee packaging: support building Inno installer with PyOxidizer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 44220
diff changeset
    68
    candidates = glob.glob(search_glob, recursive=True)
94f4f2ec7dee packaging: support building Inno installer with PyOxidizer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 44220
diff changeset
    69
94f4f2ec7dee packaging: support building Inno installer with PyOxidizer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 44220
diff changeset
    70
    for candidate in reversed(candidates):
94f4f2ec7dee packaging: support building Inno installer with PyOxidizer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 44220
diff changeset
    71
        return pathlib.Path(candidate)
94f4f2ec7dee packaging: support building Inno installer with PyOxidizer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 44220
diff changeset
    72
94f4f2ec7dee packaging: support building Inno installer with PyOxidizer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 44220
diff changeset
    73
    raise Exception("could not find vcruntime140.dll")
94f4f2ec7dee packaging: support building Inno installer with PyOxidizer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 44220
diff changeset
    74
94f4f2ec7dee packaging: support building Inno installer with PyOxidizer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 44220
diff changeset
    75
44220
a70108a3d7cc packaging: move the version normalization function to the util module
Matt Harbison <matt_harbison@yahoo.com>
parents: 43518
diff changeset
    76
def normalize_windows_version(version):
a70108a3d7cc packaging: move the version normalization function to the util module
Matt Harbison <matt_harbison@yahoo.com>
parents: 43518
diff changeset
    77
    """Normalize Mercurial version string so WiX/Inno accepts it.
a70108a3d7cc packaging: move the version normalization function to the util module
Matt Harbison <matt_harbison@yahoo.com>
parents: 43518
diff changeset
    78
a70108a3d7cc packaging: move the version normalization function to the util module
Matt Harbison <matt_harbison@yahoo.com>
parents: 43518
diff changeset
    79
    Version strings have to be numeric ``A.B.C[.D]`` to conform with MSI's
a70108a3d7cc packaging: move the version normalization function to the util module
Matt Harbison <matt_harbison@yahoo.com>
parents: 43518
diff changeset
    80
    requirements.
a70108a3d7cc packaging: move the version normalization function to the util module
Matt Harbison <matt_harbison@yahoo.com>
parents: 43518
diff changeset
    81
a70108a3d7cc packaging: move the version normalization function to the util module
Matt Harbison <matt_harbison@yahoo.com>
parents: 43518
diff changeset
    82
    We normalize RC version or the commit count to a 4th version component.
a70108a3d7cc packaging: move the version normalization function to the util module
Matt Harbison <matt_harbison@yahoo.com>
parents: 43518
diff changeset
    83
    We store this in the 4th component because ``A.B.C`` releases do occur
a70108a3d7cc packaging: move the version normalization function to the util module
Matt Harbison <matt_harbison@yahoo.com>
parents: 43518
diff changeset
    84
    and we want an e.g. ``5.3rc0`` version to be semantically less than a
a70108a3d7cc packaging: move the version normalization function to the util module
Matt Harbison <matt_harbison@yahoo.com>
parents: 43518
diff changeset
    85
    ``5.3.1rc2`` version. This requires always reserving the 3rd version
a70108a3d7cc packaging: move the version normalization function to the util module
Matt Harbison <matt_harbison@yahoo.com>
parents: 43518
diff changeset
    86
    component for the point release and the ``X.YrcN`` release is always
a70108a3d7cc packaging: move the version normalization function to the util module
Matt Harbison <matt_harbison@yahoo.com>
parents: 43518
diff changeset
    87
    point release 0.
a70108a3d7cc packaging: move the version normalization function to the util module
Matt Harbison <matt_harbison@yahoo.com>
parents: 43518
diff changeset
    88
a70108a3d7cc packaging: move the version normalization function to the util module
Matt Harbison <matt_harbison@yahoo.com>
parents: 43518
diff changeset
    89
    In the case of an RC and presence of ``+`` suffix data, we can't use both
a70108a3d7cc packaging: move the version normalization function to the util module
Matt Harbison <matt_harbison@yahoo.com>
parents: 43518
diff changeset
    90
    because the version format is limited to 4 components. We choose to use
a70108a3d7cc packaging: move the version normalization function to the util module
Matt Harbison <matt_harbison@yahoo.com>
parents: 43518
diff changeset
    91
    RC and throw away the commit count in the suffix. This means we could
a70108a3d7cc packaging: move the version normalization function to the util module
Matt Harbison <matt_harbison@yahoo.com>
parents: 43518
diff changeset
    92
    produce multiple installers with the same normalized version string.
a70108a3d7cc packaging: move the version normalization function to the util module
Matt Harbison <matt_harbison@yahoo.com>
parents: 43518
diff changeset
    93
a70108a3d7cc packaging: move the version normalization function to the util module
Matt Harbison <matt_harbison@yahoo.com>
parents: 43518
diff changeset
    94
    >>> normalize_windows_version("5.3")
a70108a3d7cc packaging: move the version normalization function to the util module
Matt Harbison <matt_harbison@yahoo.com>
parents: 43518
diff changeset
    95
    '5.3.0'
a70108a3d7cc packaging: move the version normalization function to the util module
Matt Harbison <matt_harbison@yahoo.com>
parents: 43518
diff changeset
    96
a70108a3d7cc packaging: move the version normalization function to the util module
Matt Harbison <matt_harbison@yahoo.com>
parents: 43518
diff changeset
    97
    >>> normalize_windows_version("5.3rc0")
a70108a3d7cc packaging: move the version normalization function to the util module
Matt Harbison <matt_harbison@yahoo.com>
parents: 43518
diff changeset
    98
    '5.3.0.0'
a70108a3d7cc packaging: move the version normalization function to the util module
Matt Harbison <matt_harbison@yahoo.com>
parents: 43518
diff changeset
    99
a70108a3d7cc packaging: move the version normalization function to the util module
Matt Harbison <matt_harbison@yahoo.com>
parents: 43518
diff changeset
   100
    >>> normalize_windows_version("5.3rc1")
a70108a3d7cc packaging: move the version normalization function to the util module
Matt Harbison <matt_harbison@yahoo.com>
parents: 43518
diff changeset
   101
    '5.3.0.1'
a70108a3d7cc packaging: move the version normalization function to the util module
Matt Harbison <matt_harbison@yahoo.com>
parents: 43518
diff changeset
   102
46524
e3f23814bac7 windows: fix parsing of version number to match format from D9955
Martin von Zweigbergk <martinvonz@google.com>
parents: 44763
diff changeset
   103
    >>> normalize_windows_version("5.3rc1+hg2.abcdef")
44220
a70108a3d7cc packaging: move the version normalization function to the util module
Matt Harbison <matt_harbison@yahoo.com>
parents: 43518
diff changeset
   104
    '5.3.0.1'
a70108a3d7cc packaging: move the version normalization function to the util module
Matt Harbison <matt_harbison@yahoo.com>
parents: 43518
diff changeset
   105
46524
e3f23814bac7 windows: fix parsing of version number to match format from D9955
Martin von Zweigbergk <martinvonz@google.com>
parents: 44763
diff changeset
   106
    >>> normalize_windows_version("5.3+hg2.abcdef")
44220
a70108a3d7cc packaging: move the version normalization function to the util module
Matt Harbison <matt_harbison@yahoo.com>
parents: 43518
diff changeset
   107
    '5.3.0.2'
a70108a3d7cc packaging: move the version normalization function to the util module
Matt Harbison <matt_harbison@yahoo.com>
parents: 43518
diff changeset
   108
    """
a70108a3d7cc packaging: move the version normalization function to the util module
Matt Harbison <matt_harbison@yahoo.com>
parents: 43518
diff changeset
   109
    if '+' in version:
a70108a3d7cc packaging: move the version normalization function to the util module
Matt Harbison <matt_harbison@yahoo.com>
parents: 43518
diff changeset
   110
        version, extra = version.split('+', 1)
a70108a3d7cc packaging: move the version normalization function to the util module
Matt Harbison <matt_harbison@yahoo.com>
parents: 43518
diff changeset
   111
    else:
a70108a3d7cc packaging: move the version normalization function to the util module
Matt Harbison <matt_harbison@yahoo.com>
parents: 43518
diff changeset
   112
        extra = None
a70108a3d7cc packaging: move the version normalization function to the util module
Matt Harbison <matt_harbison@yahoo.com>
parents: 43518
diff changeset
   113
a70108a3d7cc packaging: move the version normalization function to the util module
Matt Harbison <matt_harbison@yahoo.com>
parents: 43518
diff changeset
   114
    # 4.9rc0
a70108a3d7cc packaging: move the version normalization function to the util module
Matt Harbison <matt_harbison@yahoo.com>
parents: 43518
diff changeset
   115
    if version[:-1].endswith('rc'):
a70108a3d7cc packaging: move the version normalization function to the util module
Matt Harbison <matt_harbison@yahoo.com>
parents: 43518
diff changeset
   116
        rc = int(version[-1:])
a70108a3d7cc packaging: move the version normalization function to the util module
Matt Harbison <matt_harbison@yahoo.com>
parents: 43518
diff changeset
   117
        version = version[:-3]
a70108a3d7cc packaging: move the version normalization function to the util module
Matt Harbison <matt_harbison@yahoo.com>
parents: 43518
diff changeset
   118
    else:
a70108a3d7cc packaging: move the version normalization function to the util module
Matt Harbison <matt_harbison@yahoo.com>
parents: 43518
diff changeset
   119
        rc = None
a70108a3d7cc packaging: move the version normalization function to the util module
Matt Harbison <matt_harbison@yahoo.com>
parents: 43518
diff changeset
   120
a70108a3d7cc packaging: move the version normalization function to the util module
Matt Harbison <matt_harbison@yahoo.com>
parents: 43518
diff changeset
   121
    # Ensure we have at least X.Y version components.
a70108a3d7cc packaging: move the version normalization function to the util module
Matt Harbison <matt_harbison@yahoo.com>
parents: 43518
diff changeset
   122
    versions = [int(v) for v in version.split('.')]
a70108a3d7cc packaging: move the version normalization function to the util module
Matt Harbison <matt_harbison@yahoo.com>
parents: 43518
diff changeset
   123
    while len(versions) < 3:
a70108a3d7cc packaging: move the version normalization function to the util module
Matt Harbison <matt_harbison@yahoo.com>
parents: 43518
diff changeset
   124
        versions.append(0)
a70108a3d7cc packaging: move the version normalization function to the util module
Matt Harbison <matt_harbison@yahoo.com>
parents: 43518
diff changeset
   125
a70108a3d7cc packaging: move the version normalization function to the util module
Matt Harbison <matt_harbison@yahoo.com>
parents: 43518
diff changeset
   126
    if len(versions) < 4:
a70108a3d7cc packaging: move the version normalization function to the util module
Matt Harbison <matt_harbison@yahoo.com>
parents: 43518
diff changeset
   127
        if rc is not None:
a70108a3d7cc packaging: move the version normalization function to the util module
Matt Harbison <matt_harbison@yahoo.com>
parents: 43518
diff changeset
   128
            versions.append(rc)
a70108a3d7cc packaging: move the version normalization function to the util module
Matt Harbison <matt_harbison@yahoo.com>
parents: 43518
diff changeset
   129
        elif extra:
46524
e3f23814bac7 windows: fix parsing of version number to match format from D9955
Martin von Zweigbergk <martinvonz@google.com>
parents: 44763
diff changeset
   130
            # hg<commit count>.<hash>+<date>
e3f23814bac7 windows: fix parsing of version number to match format from D9955
Martin von Zweigbergk <martinvonz@google.com>
parents: 44763
diff changeset
   131
            versions.append(int(extra.split('.')[0][2:]))
44220
a70108a3d7cc packaging: move the version normalization function to the util module
Matt Harbison <matt_harbison@yahoo.com>
parents: 43518
diff changeset
   132
a70108a3d7cc packaging: move the version normalization function to the util module
Matt Harbison <matt_harbison@yahoo.com>
parents: 43518
diff changeset
   133
    return '.'.join('%d' % x for x in versions[0:4])
a70108a3d7cc packaging: move the version normalization function to the util module
Matt Harbison <matt_harbison@yahoo.com>
parents: 43518
diff changeset
   134
a70108a3d7cc packaging: move the version normalization function to the util module
Matt Harbison <matt_harbison@yahoo.com>
parents: 43518
diff changeset
   135
43516
d053d3f10b6a packaging: stage installed files for Inno
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43076
diff changeset
   136
def process_install_rules(
d053d3f10b6a packaging: stage installed files for Inno
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43076
diff changeset
   137
    rules: list, source_dir: pathlib.Path, dest_dir: pathlib.Path
d053d3f10b6a packaging: stage installed files for Inno
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43076
diff changeset
   138
):
d053d3f10b6a packaging: stage installed files for Inno
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43076
diff changeset
   139
    for source, dest in rules:
d053d3f10b6a packaging: stage installed files for Inno
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43076
diff changeset
   140
        if '*' in source:
d053d3f10b6a packaging: stage installed files for Inno
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43076
diff changeset
   141
            if not dest.endswith('/'):
d053d3f10b6a packaging: stage installed files for Inno
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43076
diff changeset
   142
                raise ValueError('destination must end in / when globbing')
d053d3f10b6a packaging: stage installed files for Inno
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43076
diff changeset
   143
d053d3f10b6a packaging: stage installed files for Inno
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43076
diff changeset
   144
            # We strip off the source path component before the first glob
d053d3f10b6a packaging: stage installed files for Inno
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43076
diff changeset
   145
            # character to construct the relative install path.
d053d3f10b6a packaging: stage installed files for Inno
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43076
diff changeset
   146
            prefix_end_index = source[: source.index('*')].rindex('/')
d053d3f10b6a packaging: stage installed files for Inno
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43076
diff changeset
   147
            relative_prefix = source_dir / source[0:prefix_end_index]
d053d3f10b6a packaging: stage installed files for Inno
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43076
diff changeset
   148
d053d3f10b6a packaging: stage installed files for Inno
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43076
diff changeset
   149
            for res in glob.glob(str(source_dir / source), recursive=True):
d053d3f10b6a packaging: stage installed files for Inno
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43076
diff changeset
   150
                source_path = pathlib.Path(res)
d053d3f10b6a packaging: stage installed files for Inno
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43076
diff changeset
   151
d053d3f10b6a packaging: stage installed files for Inno
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43076
diff changeset
   152
                if source_path.is_dir():
d053d3f10b6a packaging: stage installed files for Inno
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43076
diff changeset
   153
                    continue
d053d3f10b6a packaging: stage installed files for Inno
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43076
diff changeset
   154
d053d3f10b6a packaging: stage installed files for Inno
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43076
diff changeset
   155
                rel_path = source_path.relative_to(relative_prefix)
d053d3f10b6a packaging: stage installed files for Inno
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43076
diff changeset
   156
d053d3f10b6a packaging: stage installed files for Inno
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43076
diff changeset
   157
                dest_path = dest_dir / dest[:-1] / rel_path
d053d3f10b6a packaging: stage installed files for Inno
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43076
diff changeset
   158
d053d3f10b6a packaging: stage installed files for Inno
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43076
diff changeset
   159
                dest_path.parent.mkdir(parents=True, exist_ok=True)
d053d3f10b6a packaging: stage installed files for Inno
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43076
diff changeset
   160
                print('copying %s to %s' % (source_path, dest_path))
d053d3f10b6a packaging: stage installed files for Inno
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43076
diff changeset
   161
                shutil.copy(source_path, dest_path)
d053d3f10b6a packaging: stage installed files for Inno
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43076
diff changeset
   162
d053d3f10b6a packaging: stage installed files for Inno
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43076
diff changeset
   163
        # Simple file case.
d053d3f10b6a packaging: stage installed files for Inno
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43076
diff changeset
   164
        else:
d053d3f10b6a packaging: stage installed files for Inno
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43076
diff changeset
   165
            source_path = pathlib.Path(source)
d053d3f10b6a packaging: stage installed files for Inno
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43076
diff changeset
   166
d053d3f10b6a packaging: stage installed files for Inno
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43076
diff changeset
   167
            if dest.endswith('/'):
d053d3f10b6a packaging: stage installed files for Inno
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43076
diff changeset
   168
                dest_path = pathlib.Path(dest) / source_path.name
d053d3f10b6a packaging: stage installed files for Inno
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43076
diff changeset
   169
            else:
d053d3f10b6a packaging: stage installed files for Inno
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43076
diff changeset
   170
                dest_path = pathlib.Path(dest)
d053d3f10b6a packaging: stage installed files for Inno
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43076
diff changeset
   171
d053d3f10b6a packaging: stage installed files for Inno
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43076
diff changeset
   172
            full_source_path = source_dir / source_path
d053d3f10b6a packaging: stage installed files for Inno
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43076
diff changeset
   173
            full_dest_path = dest_dir / dest_path
d053d3f10b6a packaging: stage installed files for Inno
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43076
diff changeset
   174
d053d3f10b6a packaging: stage installed files for Inno
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43076
diff changeset
   175
            full_dest_path.parent.mkdir(parents=True, exist_ok=True)
d053d3f10b6a packaging: stage installed files for Inno
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43076
diff changeset
   176
            shutil.copy(full_source_path, full_dest_path)
d053d3f10b6a packaging: stage installed files for Inno
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43076
diff changeset
   177
            print('copying %s to %s' % (full_source_path, full_dest_path))
43518
7c9f63a5cb14 packaging: always pass VERSION into Inno invocation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43516
diff changeset
   178
7c9f63a5cb14 packaging: always pass VERSION into Inno invocation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43516
diff changeset
   179
7c9f63a5cb14 packaging: always pass VERSION into Inno invocation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43516
diff changeset
   180
def read_version_py(source_dir):
7c9f63a5cb14 packaging: always pass VERSION into Inno invocation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43516
diff changeset
   181
    """Read the mercurial/__version__.py file to resolve the version string."""
7c9f63a5cb14 packaging: always pass VERSION into Inno invocation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43516
diff changeset
   182
    p = source_dir / 'mercurial' / '__version__.py'
7c9f63a5cb14 packaging: always pass VERSION into Inno invocation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43516
diff changeset
   183
7c9f63a5cb14 packaging: always pass VERSION into Inno invocation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43516
diff changeset
   184
    with p.open('r', encoding='utf-8') as fh:
53011
d333e14477f1 packaging: adapt `__version__.py` parsing for `setuptools_scm` output
Matt Harbison <matt_harbison@yahoo.com>
parents: 48848
diff changeset
   185
        m = re.search("version = '([^']+)'", fh.read(), re.MULTILINE)
43518
7c9f63a5cb14 packaging: always pass VERSION into Inno invocation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43516
diff changeset
   186
7c9f63a5cb14 packaging: always pass VERSION into Inno invocation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43516
diff changeset
   187
        if not m:
7c9f63a5cb14 packaging: always pass VERSION into Inno invocation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43516
diff changeset
   188
            raise Exception('could not parse %s' % p)
7c9f63a5cb14 packaging: always pass VERSION into Inno invocation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43516
diff changeset
   189
7c9f63a5cb14 packaging: always pass VERSION into Inno invocation
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43516
diff changeset
   190
        return m.group(1)