#!/usr/bin/env python3 -B
"""
Script for collecting distribution archives needed for doing a release.

This collects "sdist" and "wheel" archives, the latter for a number of
Python versions (see below).
"""

import fnmatch
import os
import shutil
import subprocess
import sys

from _common_definitions import (
    DIST_DIR,
    PY_VERSIONS,
    TOP_DIR,
    setup_variant,
    system_report,
    variants,
)

WHEEL_BUILD_FAILURE_IS_ERROR = True


def files_matching(pattern, dirname):
    return fnmatch.filter(os.listdir(dirname), pattern)


_detected_versions = None


def is_usable_release(ver):
    path = os.path.join("/Library/Frameworks/Python.framework/Versions", ver)

    if not os.path.exists(path):
        return False

    output = subprocess.check_output([f"{path}/bin/python3", "--version"]).decode()
    if "a" in output.strip():
        # Alpha release
        return False

    return True


def detect_pyversions():
    global _detected_versions
    if _detected_versions is not None:
        return _detected_versions

    result = []
    for ver in PY_VERSIONS:
        if is_usable_release(ver):
            result.append(ver)

    _detected_versions = result
    return _detected_versions


def main():
    if os.path.exists(DIST_DIR):
        shutil.rmtree(DIST_DIR)
    os.mkdir(DIST_DIR)

    # Information about this build:
    system_report(os.path.join(TOP_DIR, "build-info.txt"), detect_pyversions())

    # Collect the list of subprojects to build
    names = ["pyobjc", "pyobjc-core"]
    for nm in sorted(os.listdir(TOP_DIR)):
        if nm.startswith("pyobjc-framework-"):
            names.append(nm)

    failed = []
    for nm in names:
        # Collect sdist archive with most recent python version.
        status = subprocess.call(
            [
                f"python{detect_pyversions()[-1]}",
                "setup.py",
                "sdist",
                f"--dist-dir={DIST_DIR}",
            ],
            cwd=os.path.join(TOP_DIR, nm),
        )
        if status != 0:
            if WHEEL_BUILD_FAILURE_IS_ERROR:
                raise RuntimeError(f"Building wheel for {nm} failed")

            else:
                print(f"WARNING: Building wheel for {nm} failed")
                failed.append((nm, "sdist", ""))

        for ver in detect_pyversions():
            for variant in variants(ver):
                if ver == "3.8":
                    pass
                elif any(variant.endswith(x) for x in ("-x86_64", "-arm64")):
                    # Don't create single architecture wheels for anything other than
                    # Python 3.8 (where the universal2 build is only for macOS 11 or later)
                    continue
                setup_variant(ver, variant)
                status = subprocess.call(
                    [
                        f"python{ver}",
                        "setup.py",
                        "build_ext",
                        "-j",
                        str(os.cpu_count()),
                        "bdist_wheel",
                        f"--dist-dir={DIST_DIR}",
                    ],
                    cwd=os.path.join(TOP_DIR, nm),
                )

                if status != 0:
                    if WHEEL_BUILD_FAILURE_IS_ERROR:
                        raise RuntimeError(
                            f"WARNING: Building wheel for {nm} failed (python {variant})"
                        )

                    else:
                        print(
                            f"WARNING: Building wheel for {nm} failed (python {variant})"
                        )
                        failed.append((nm, "wheel", variant))

    print()
    print("Collected files")
    print("===============")
    print()
    for nm in names:
        if nm == "pyobjc":
            continue
        have_wheel = False
        pattern = nm.replace("-", "?") + "-*"
        print(f"{nm}:")
        for fn in sorted(files_matching(pattern, DIST_DIR)):
            if fn.endswith(".whl"):
                have_wheel = True
            print(f"  {fn}")
        if not have_wheel:
            print(f"ERROR: no wheels for {nm}")
        print()

    if failed:
        print()
        print("Build failures")
        print("==============")
        print()
        for nm, command, ver in failed:
            if ver:
                print(f"{nm} {command}@{ver}")
            else:
                print(f"{nm} {command}")

        sys.exit(0)

    sys.exit(0)


if __name__ == "__main__":
    main()

d3ec435e7260473d494d52ad7bf28d8d1151d311
<mask token>


def files_matching(pattern, dirname):
    return fnmatch.filter(os.listdir(dirname), pattern)


<mask token>


def is_usable_release(ver):
    path = os.path.join('/Library/Frameworks/Python.framework/Versions', ver)
    if not os.path.exists(path):
        return False
    output = subprocess.check_output([f'{path}/bin/python3', '--version']
        ).decode()
    if 'a' in output.strip():
        return False
    return True


<mask token>

<mask token>


def files_matching(pattern, dirname):
    return fnmatch.filter(os.listdir(dirname), pattern)


<mask token>


def is_usable_release(ver):
    path = os.path.join('/Library/Frameworks/Python.framework/Versions', ver)
    if not os.path.exists(path):
        return False
    output = subprocess.check_output([f'{path}/bin/python3', '--version']
        ).decode()
    if 'a' in output.strip():
        return False
    return True


def detect_pyversions():
    global _detected_versions
    if _detected_versions is not None:
        return _detected_versions
    result = []
    for ver in PY_VERSIONS:
        if is_usable_release(ver):
            result.append(ver)
    _detected_versions = result
    return _detected_versions


def main():
    if os.path.exists(DIST_DIR):
        shutil.rmtree(DIST_DIR)
    os.mkdir(DIST_DIR)
    system_report(os.path.join(TOP_DIR, 'build-info.txt'), detect_pyversions())
    names = ['pyobjc', 'pyobjc-core']
    for nm in sorted(os.listdir(TOP_DIR)):
        if nm.startswith('pyobjc-framework-'):
            names.append(nm)
    failed = []
    for nm in names:
        status = subprocess.call([f'python{detect_pyversions()[-1]}',
            'setup.py', 'sdist', f'--dist-dir={DIST_DIR}'], cwd=os.path.
            join(TOP_DIR, nm))
        if status != 0:
            if WHEEL_BUILD_FAILURE_IS_ERROR:
                raise RuntimeError(f'Building wheel for {nm} failed')
            else:
                print(f'WARNING: Building wheel for {nm} failed')
                failed.append((nm, 'sdist', ''))
        for ver in detect_pyversions():
            for variant in variants(ver):
                if ver == '3.8':
                    pass
                elif any(variant.endswith(x) for x in ('-x86_64', '-arm64')):
                    continue
                setup_variant(ver, variant)
                status = subprocess.call([f'python{ver}', 'setup.py',
                    'build_ext', '-j', str(os.cpu_count()), 'bdist_wheel',
                    f'--dist-dir={DIST_DIR}'], cwd=os.path.join(TOP_DIR, nm))
                if status != 0:
                    if WHEEL_BUILD_FAILURE_IS_ERROR:
                        raise RuntimeError(
                            f'WARNING: Building wheel for {nm} failed (python {variant})'
                            )
                    else:
                        print(
                            f'WARNING: Building wheel for {nm} failed (python {variant})'
                            )
                        failed.append((nm, 'wheel', variant))
    print()
    print('Collected files')
    print('===============')
    print()
    for nm in names:
        if nm == 'pyobjc':
            continue
        have_wheel = False
        pattern = nm.replace('-', '?') + '-*'
        print(f'{nm}:')
        for fn in sorted(files_matching(pattern, DIST_DIR)):
            if fn.endswith('.whl'):
                have_wheel = True
            print(f'  {fn}')
        if not have_wheel:
            print(f'ERROR: no wheels for {nm}')
        print()
    if failed:
        print()
        print('Build failures')
        print('==============')
        print()
        for nm, command, ver in failed:
            if ver:
                print(f'{nm} {command}@{ver}')
            else:
                print(f'{nm} {command}')
        sys.exit(0)
    sys.exit(0)


<mask token>

<mask token>


def files_matching(pattern, dirname):
    return fnmatch.filter(os.listdir(dirname), pattern)


<mask token>


def is_usable_release(ver):
    path = os.path.join('/Library/Frameworks/Python.framework/Versions', ver)
    if not os.path.exists(path):
        return False
    output = subprocess.check_output([f'{path}/bin/python3', '--version']
        ).decode()
    if 'a' in output.strip():
        return False
    return True


def detect_pyversions():
    global _detected_versions
    if _detected_versions is not None:
        return _detected_versions
    result = []
    for ver in PY_VERSIONS:
        if is_usable_release(ver):
            result.append(ver)
    _detected_versions = result
    return _detected_versions


def main():
    if os.path.exists(DIST_DIR):
        shutil.rmtree(DIST_DIR)
    os.mkdir(DIST_DIR)
    system_report(os.path.join(TOP_DIR, 'build-info.txt'), detect_pyversions())
    names = ['pyobjc', 'pyobjc-core']
    for nm in sorted(os.listdir(TOP_DIR)):
        if nm.startswith('pyobjc-framework-'):
            names.append(nm)
    failed = []
    for nm in names:
        status = subprocess.call([f'python{detect_pyversions()[-1]}',
            'setup.py', 'sdist', f'--dist-dir={DIST_DIR}'], cwd=os.path.
            join(TOP_DIR, nm))
        if status != 0:
            if WHEEL_BUILD_FAILURE_IS_ERROR:
                raise RuntimeError(f'Building wheel for {nm} failed')
            else:
                print(f'WARNING: Building wheel for {nm} failed')
                failed.append((nm, 'sdist', ''))
        for ver in detect_pyversions():
            for variant in variants(ver):
                if ver == '3.8':
                    pass
                elif any(variant.endswith(x) for x in ('-x86_64', '-arm64')):
                    continue
                setup_variant(ver, variant)
                status = subprocess.call([f'python{ver}', 'setup.py',
                    'build_ext', '-j', str(os.cpu_count()), 'bdist_wheel',
                    f'--dist-dir={DIST_DIR}'], cwd=os.path.join(TOP_DIR, nm))
                if status != 0:
                    if WHEEL_BUILD_FAILURE_IS_ERROR:
                        raise RuntimeError(
                            f'WARNING: Building wheel for {nm} failed (python {variant})'
                            )
                    else:
                        print(
                            f'WARNING: Building wheel for {nm} failed (python {variant})'
                            )
                        failed.append((nm, 'wheel', variant))
    print()
    print('Collected files')
    print('===============')
    print()
    for nm in names:
        if nm == 'pyobjc':
            continue
        have_wheel = False
        pattern = nm.replace('-', '?') + '-*'
        print(f'{nm}:')
        for fn in sorted(files_matching(pattern, DIST_DIR)):
            if fn.endswith('.whl'):
                have_wheel = True
            print(f'  {fn}')
        if not have_wheel:
            print(f'ERROR: no wheels for {nm}')
        print()
    if failed:
        print()
        print('Build failures')
        print('==============')
        print()
        for nm, command, ver in failed:
            if ver:
                print(f'{nm} {command}@{ver}')
            else:
                print(f'{nm} {command}')
        sys.exit(0)
    sys.exit(0)


if __name__ == '__main__':
    main()

<mask token>
WHEEL_BUILD_FAILURE_IS_ERROR = True


def files_matching(pattern, dirname):
    return fnmatch.filter(os.listdir(dirname), pattern)


_detected_versions = None


def is_usable_release(ver):
    path = os.path.join('/Library/Frameworks/Python.framework/Versions', ver)
    if not os.path.exists(path):
        return False
    output = subprocess.check_output([f'{path}/bin/python3', '--version']
        ).decode()
    if 'a' in output.strip():
        return False
    return True


def detect_pyversions():
    global _detected_versions
    if _detected_versions is not None:
        return _detected_versions
    result = []
    for ver in PY_VERSIONS:
        if is_usable_release(ver):
            result.append(ver)
    _detected_versions = result
    return _detected_versions


def main():
    if os.path.exists(DIST_DIR):
        shutil.rmtree(DIST_DIR)
    os.mkdir(DIST_DIR)
    system_report(os.path.join(TOP_DIR, 'build-info.txt'), detect_pyversions())
    names = ['pyobjc', 'pyobjc-core']
    for nm in sorted(os.listdir(TOP_DIR)):
        if nm.startswith('pyobjc-framework-'):
            names.append(nm)
    failed = []
    for nm in names:
        status = subprocess.call([f'python{detect_pyversions()[-1]}',
            'setup.py', 'sdist', f'--dist-dir={DIST_DIR}'], cwd=os.path.
            join(TOP_DIR, nm))
        if status != 0:
            if WHEEL_BUILD_FAILURE_IS_ERROR:
                raise RuntimeError(f'Building wheel for {nm} failed')
            else:
                print(f'WARNING: Building wheel for {nm} failed')
                failed.append((nm, 'sdist', ''))
        for ver in detect_pyversions():
            for variant in variants(ver):
                if ver == '3.8':
                    pass
                elif any(variant.endswith(x) for x in ('-x86_64', '-arm64')):
                    continue
                setup_variant(ver, variant)
                status = subprocess.call([f'python{ver}', 'setup.py',
                    'build_ext', '-j', str(os.cpu_count()), 'bdist_wheel',
                    f'--dist-dir={DIST_DIR}'], cwd=os.path.join(TOP_DIR, nm))
                if status != 0:
                    if WHEEL_BUILD_FAILURE_IS_ERROR:
                        raise RuntimeError(
                            f'WARNING: Building wheel for {nm} failed (python {variant})'
                            )
                    else:
                        print(
                            f'WARNING: Building wheel for {nm} failed (python {variant})'
                            )
                        failed.append((nm, 'wheel', variant))
    print()
    print('Collected files')
    print('===============')
    print()
    for nm in names:
        if nm == 'pyobjc':
            continue
        have_wheel = False
        pattern = nm.replace('-', '?') + '-*'
        print(f'{nm}:')
        for fn in sorted(files_matching(pattern, DIST_DIR)):
            if fn.endswith('.whl'):
                have_wheel = True
            print(f'  {fn}')
        if not have_wheel:
            print(f'ERROR: no wheels for {nm}')
        print()
    if failed:
        print()
        print('Build failures')
        print('==============')
        print()
        for nm, command, ver in failed:
            if ver:
                print(f'{nm} {command}@{ver}')
            else:
                print(f'{nm} {command}')
        sys.exit(0)
    sys.exit(0)


if __name__ == '__main__':
    main()

#!/usr/bin/env python3 -B
"""
Script for collecting distribution archives needed for doing a release.

This collects "sdist" and "wheel" archives, the latter for a number of
Python versions (see below).
"""

import fnmatch
import os
import shutil
import subprocess
import sys

from _common_definitions import (
    DIST_DIR,
    PY_VERSIONS,
    TOP_DIR,
    setup_variant,
    system_report,
    variants,
)

WHEEL_BUILD_FAILURE_IS_ERROR = True


def files_matching(pattern, dirname):
    return fnmatch.filter(os.listdir(dirname), pattern)


_detected_versions = None


def is_usable_release(ver):
    path = os.path.join("/Library/Frameworks/Python.framework/Versions", ver)

    if not os.path.exists(path):
        return False

    output = subprocess.check_output([f"{path}/bin/python3", "--version"]).decode()
    if "a" in output.strip():
        # Alpha release
        return False

    return True


def detect_pyversions():
    global _detected_versions
    if _detected_versions is not None:
        return _detected_versions

    result = []
    for ver in PY_VERSIONS:
        if is_usable_release(ver):
            result.append(ver)

    _detected_versions = result
    return _detected_versions


def main():
    if os.path.exists(DIST_DIR):
        shutil.rmtree(DIST_DIR)
    os.mkdir(DIST_DIR)

    # Information about this build:
    system_report(os.path.join(TOP_DIR, "build-info.txt"), detect_pyversions())

    # Collect the list of subprojects to build
    names = ["pyobjc", "pyobjc-core"]
    for nm in sorted(os.listdir(TOP_DIR)):
        if nm.startswith("pyobjc-framework-"):
            names.append(nm)

    failed = []
    for nm in names:
        # Collect sdist archive with most recent python version.
        status = subprocess.call(
            [
                f"python{detect_pyversions()[-1]}",
                "setup.py",
                "sdist",
                f"--dist-dir={DIST_DIR}",
            ],
            cwd=os.path.join(TOP_DIR, nm),
        )
        if status != 0:
            if WHEEL_BUILD_FAILURE_IS_ERROR:
                raise RuntimeError(f"Building wheel for {nm} failed")

            else:
                print(f"WARNING: Building wheel for {nm} failed")
                failed.append((nm, "sdist", ""))

        for ver in detect_pyversions():
            for variant in variants(ver):
                if ver == "3.8":
                    pass
                elif any(variant.endswith(x) for x in ("-x86_64", "-arm64")):
                    # Don't create single architecture wheels for anything other than
                    # Python 3.8 (where the universal2 build is only for macOS 11 or later)
                    continue
                setup_variant(ver, variant)
                status = subprocess.call(
                    [
                        f"python{ver}",
                        "setup.py",
                        "build_ext",
                        "-j",
                        str(os.cpu_count()),
                        "bdist_wheel",
                        f"--dist-dir={DIST_DIR}",
                    ],
                    cwd=os.path.join(TOP_DIR, nm),
                )

                if status != 0:
                    if WHEEL_BUILD_FAILURE_IS_ERROR:
                        raise RuntimeError(
                            f"WARNING: Building wheel for {nm} failed (python {variant})"
                        )

                    else:
                        print(
                            f"WARNING: Building wheel for {nm} failed (python {variant})"
                        )
                        failed.append((nm, "wheel", variant))

    print()
    print("Collected files")
    print("===============")
    print()
    for nm in names:
        if nm == "pyobjc":
            continue
        have_wheel = False
        pattern = nm.replace("-", "?") + "-*"
        print(f"{nm}:")
        for fn in sorted(files_matching(pattern, DIST_DIR)):
            if fn.endswith(".whl"):
                have_wheel = True
            print(f"  {fn}")
        if not have_wheel:
            print(f"ERROR: no wheels for {nm}")
        print()

    if failed:
        print()
        print("Build failures")
        print("==============")
        print()
        for nm, command, ver in failed:
            if ver:
                print(f"{nm} {command}@{ver}")
            else:
                print(f"{nm} {command}")

        sys.exit(0)

    sys.exit(0)


if __name__ == "__main__":
    main()
