contrib/packaging/hgpackaging/util.py
changeset 41952 b83de9150c1c
parent 41921 4371f543efda
child 42090 9c07d345fd6d
--- a/contrib/packaging/hgpackaging/util.py	Wed Mar 13 10:51:40 2019 -0700
+++ b/contrib/packaging/hgpackaging/util.py	Thu Mar 14 18:14:33 2019 -0700
@@ -1,157 +1,157 @@
-# util.py - Common packaging utility code.
-#
-# 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.
-
-import distutils.version
-import getpass
-import os
-import pathlib
-import subprocess
-import tarfile
-import zipfile
-
-
-def extract_tar_to_directory(source: pathlib.Path, dest: pathlib.Path):
-    with tarfile.open(source, 'r') as tf:
-        tf.extractall(dest)
-
-
-def extract_zip_to_directory(source: pathlib.Path, dest: pathlib.Path):
-    with zipfile.ZipFile(source, 'r') as zf:
-        zf.extractall(dest)
-
-
-def find_vc_runtime_files(x64=False):
-    """Finds Visual C++ Runtime DLLs to include in distribution."""
-    winsxs = pathlib.Path(os.environ['SYSTEMROOT']) / 'WinSxS'
-
-    prefix = 'amd64' if x64 else 'x86'
-
-    candidates = sorted(p for p in os.listdir(winsxs)
-                  if p.lower().startswith('%s_microsoft.vc90.crt_' % prefix))
-
-    for p in candidates:
-        print('found candidate VC runtime: %s' % p)
-
-    # Take the newest version.
-    version = candidates[-1]
-
-    d = winsxs / version
-
-    return [
-        d / 'msvcm90.dll',
-        d / 'msvcp90.dll',
-        d / 'msvcr90.dll',
-        winsxs / 'Manifests' / ('%s.manifest' % version),
-    ]
-
-
-def windows_10_sdk_info():
-    """Resolves information about the Windows 10 SDK."""
-
-    base = pathlib.Path(os.environ['ProgramFiles(x86)']) / 'Windows Kits' / '10'
-
-    if not base.is_dir():
-        raise Exception('unable to find Windows 10 SDK at %s' % base)
-
-    # Find the latest version.
-    bin_base = base / 'bin'
-
-    versions = [v for v in os.listdir(bin_base) if v.startswith('10.')]
-    version = sorted(versions, reverse=True)[0]
-
-    bin_version = bin_base / version
-
-    return {
-        'root': base,
-        'version': version,
-        'bin_root': bin_version,
-        'bin_x86': bin_version / 'x86',
-        'bin_x64': bin_version / 'x64'
-    }
-
-
-def find_signtool():
-    """Find signtool.exe from the Windows SDK."""
-    sdk = windows_10_sdk_info()
-
-    for key in ('bin_x64', 'bin_x86'):
-        p = sdk[key] / 'signtool.exe'
-
-        if p.exists():
-            return p
-
-    raise Exception('could not find signtool.exe in Windows 10 SDK')
-
-
-def sign_with_signtool(file_path, description, subject_name=None,
-                       cert_path=None, cert_password=None,
-                       timestamp_url=None):
-    """Digitally sign a file with signtool.exe.
-
-    ``file_path`` is file to sign.
-    ``description`` is text that goes in the signature.
-
-    The signing certificate can be specified by ``cert_path`` or
-    ``subject_name``. These correspond to the ``/f`` and ``/n`` arguments
-    to signtool.exe, respectively.
-
-    The certificate password can be specified via ``cert_password``. If
-    not provided, you will be prompted for the password.
-
-    ``timestamp_url`` is the URL of a RFC 3161 timestamp server (``/tr``
-    argument to signtool.exe).
-    """
-    if cert_path and subject_name:
-        raise ValueError('cannot specify both cert_path and subject_name')
-
-    while cert_path and not cert_password:
-        cert_password = getpass.getpass('password for %s: ' % cert_path)
-
-    args = [
-        str(find_signtool()), 'sign',
-        '/v',
-        '/fd', 'sha256',
-        '/d', description,
-    ]
-
-    if cert_path:
-        args.extend(['/f', str(cert_path), '/p', cert_password])
-    elif subject_name:
-        args.extend(['/n', subject_name])
-
-    if timestamp_url:
-        args.extend(['/tr', timestamp_url, '/td', 'sha256'])
-
-    args.append(str(file_path))
-
-    print('signing %s' % file_path)
-    subprocess.run(args, check=True)
-
-
-PRINT_PYTHON_INFO = '''
-import platform; print("%s:%s" % (platform.architecture()[0], platform.python_version()))
-'''.strip()
-
-
-def python_exe_info(python_exe: pathlib.Path):
-    """Obtain information about a Python executable."""
-
-    res = subprocess.run(
-        [str(python_exe), '-c', PRINT_PYTHON_INFO],
-        capture_output=True, check=True)
-
-    arch, version = res.stdout.decode('utf-8').split(':')
-
-    version = distutils.version.LooseVersion(version)
-
-    return {
-        'arch': arch,
-        'version': version,
-        'py3': version >= distutils.version.LooseVersion('3'),
-    }
+# util.py - Common packaging utility code.
+#
+# 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.
+
+import distutils.version
+import getpass
+import os
+import pathlib
+import subprocess
+import tarfile
+import zipfile
+
+
+def extract_tar_to_directory(source: pathlib.Path, dest: pathlib.Path):
+    with tarfile.open(source, 'r') as tf:
+        tf.extractall(dest)
+
+
+def extract_zip_to_directory(source: pathlib.Path, dest: pathlib.Path):
+    with zipfile.ZipFile(source, 'r') as zf:
+        zf.extractall(dest)
+
+
+def find_vc_runtime_files(x64=False):
+    """Finds Visual C++ Runtime DLLs to include in distribution."""
+    winsxs = pathlib.Path(os.environ['SYSTEMROOT']) / 'WinSxS'
+
+    prefix = 'amd64' if x64 else 'x86'
+
+    candidates = sorted(p for p in os.listdir(winsxs)
+                  if p.lower().startswith('%s_microsoft.vc90.crt_' % prefix))
+
+    for p in candidates:
+        print('found candidate VC runtime: %s' % p)
+
+    # Take the newest version.
+    version = candidates[-1]
+
+    d = winsxs / version
+
+    return [
+        d / 'msvcm90.dll',
+        d / 'msvcp90.dll',
+        d / 'msvcr90.dll',
+        winsxs / 'Manifests' / ('%s.manifest' % version),
+    ]
+
+
+def windows_10_sdk_info():
+    """Resolves information about the Windows 10 SDK."""
+
+    base = pathlib.Path(os.environ['ProgramFiles(x86)']) / 'Windows Kits' / '10'
+
+    if not base.is_dir():
+        raise Exception('unable to find Windows 10 SDK at %s' % base)
+
+    # Find the latest version.
+    bin_base = base / 'bin'
+
+    versions = [v for v in os.listdir(bin_base) if v.startswith('10.')]
+    version = sorted(versions, reverse=True)[0]
+
+    bin_version = bin_base / version
+
+    return {
+        'root': base,
+        'version': version,
+        'bin_root': bin_version,
+        'bin_x86': bin_version / 'x86',
+        'bin_x64': bin_version / 'x64'
+    }
+
+
+def find_signtool():
+    """Find signtool.exe from the Windows SDK."""
+    sdk = windows_10_sdk_info()
+
+    for key in ('bin_x64', 'bin_x86'):
+        p = sdk[key] / 'signtool.exe'
+
+        if p.exists():
+            return p
+
+    raise Exception('could not find signtool.exe in Windows 10 SDK')
+
+
+def sign_with_signtool(file_path, description, subject_name=None,
+                       cert_path=None, cert_password=None,
+                       timestamp_url=None):
+    """Digitally sign a file with signtool.exe.
+
+    ``file_path`` is file to sign.
+    ``description`` is text that goes in the signature.
+
+    The signing certificate can be specified by ``cert_path`` or
+    ``subject_name``. These correspond to the ``/f`` and ``/n`` arguments
+    to signtool.exe, respectively.
+
+    The certificate password can be specified via ``cert_password``. If
+    not provided, you will be prompted for the password.
+
+    ``timestamp_url`` is the URL of a RFC 3161 timestamp server (``/tr``
+    argument to signtool.exe).
+    """
+    if cert_path and subject_name:
+        raise ValueError('cannot specify both cert_path and subject_name')
+
+    while cert_path and not cert_password:
+        cert_password = getpass.getpass('password for %s: ' % cert_path)
+
+    args = [
+        str(find_signtool()), 'sign',
+        '/v',
+        '/fd', 'sha256',
+        '/d', description,
+    ]
+
+    if cert_path:
+        args.extend(['/f', str(cert_path), '/p', cert_password])
+    elif subject_name:
+        args.extend(['/n', subject_name])
+
+    if timestamp_url:
+        args.extend(['/tr', timestamp_url, '/td', 'sha256'])
+
+    args.append(str(file_path))
+
+    print('signing %s' % file_path)
+    subprocess.run(args, check=True)
+
+
+PRINT_PYTHON_INFO = '''
+import platform; print("%s:%s" % (platform.architecture()[0], platform.python_version()))
+'''.strip()
+
+
+def python_exe_info(python_exe: pathlib.Path):
+    """Obtain information about a Python executable."""
+
+    res = subprocess.run(
+        [str(python_exe), '-c', PRINT_PYTHON_INFO],
+        capture_output=True, check=True)
+
+    arch, version = res.stdout.decode('utf-8').split(':')
+
+    version = distutils.version.LooseVersion(version)
+
+    return {
+        'arch': arch,
+        'version': version,
+        'py3': version >= distutils.version.LooseVersion('3'),
+    }