|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142 |
- import argparse
- import os
- import sys
- import pytest
- from pathlib import Path
- from typing import Sequence, NamedTuple
- import multiprocessing
- import subprocess
- import urllib.request
- import shutil
-
- from self_build import self_build
- from dds_ci import paths, proc
-
-
- class CIOptions(NamedTuple):
- toolchain: str
- toolchain_2: str
-
-
- def _do_bootstrap_build(opts: CIOptions) -> None:
- print('Bootstrapping by a local build of prior versions...')
- subprocess.check_call([
- sys.executable,
- '-u',
- str(paths.TOOLS_DIR / 'bootstrap.py'),
- ])
-
-
- def _do_bootstrap_download() -> None:
- filename = {
- 'win32': 'dds-win-x64.exe',
- 'linux': 'dds-linux-x64',
- 'darwin': 'dds-macos-x64',
- 'freebsd11': 'dds-freebsd-x64',
- 'freebsd12': 'dds-freebsd-x64',
- }.get(sys.platform)
- if filename is None:
- raise RuntimeError(f'We do not have a prebuilt DDS binary for '
- f'the "{sys.platform}" platform')
- url = f'https://github.com/vector-of-bool/dds/releases/download/0.1.0-alpha.3/{filename}'
-
- print(f'Downloading prebuilt DDS executable: {url}')
- stream = urllib.request.urlopen(url)
- paths.PREBUILT_DDS.parent.mkdir(exist_ok=True, parents=True)
- with paths.PREBUILT_DDS.open('wb') as fd:
- while True:
- buf = stream.read(1024 * 4)
- if not buf:
- break
- fd.write(buf)
-
- if os.name != 'nt':
- # Mark the binary executable. By default it won't be
- mode = paths.PREBUILT_DDS.stat().st_mode
- mode |= 0b001_001_001
- paths.PREBUILT_DDS.chmod(mode)
-
-
- def main(argv: Sequence[str]) -> int:
- parser = argparse.ArgumentParser()
- parser.add_argument(
- '-B',
- '--bootstrap-with',
- help='How are we to obtain a bootstrapped DDS executable?',
- choices=('download', 'build', 'skip'),
- required=True,
- )
- parser.add_argument(
- '--toolchain',
- '-T',
- help='The toolchain to use for the CI process',
- required=True,
- )
- parser.add_argument(
- '--toolchain-2',
- '-T2',
- help='The toolchain to use for the self-build',
- required=True,
- )
- parser.add_argument(
- '--build-only',
- action='store_true',
- help='Only build the `dds` executable. Skip second-phase and tests.')
- args = parser.parse_args(argv)
-
- opts = CIOptions(toolchain=args.toolchain, toolchain_2=args.toolchain_2)
-
- if args.bootstrap_with == 'build':
- _do_bootstrap_build(opts)
- elif args.bootstrap_with == 'download':
- _do_bootstrap_download()
- elif args.bootstrap_with == 'skip':
- pass
- else:
- assert False, 'impossible'
-
- old_cat_path = paths.PREBUILT_DIR / 'catalog.db'
- if old_cat_path.is_file():
- old_cat_path.unlink()
-
- ci_repo_dir = paths.PREBUILT_DIR / 'ci-repo'
- if ci_repo_dir.exists():
- shutil.rmtree(ci_repo_dir)
-
- self_build(
- paths.PREBUILT_DDS,
- toolchain=opts.toolchain,
- cat_path=old_cat_path,
- cat_json_path=Path('catalog.old.json'),
- dds_flags=[('--repo-dir', ci_repo_dir)])
- print('Main build PASSED!')
- print(f'A `dds` executable has been generated: {paths.CUR_BUILT_DDS}')
-
- if args.build_only:
- print(
- f'`--build-only` was given, so second phase and tests will not execute'
- )
- return 0
-
- print('Bootstrapping myself:')
- new_cat_path = paths.BUILD_DIR / 'catalog.db'
- new_repo_dir = paths.BUILD_DIR / 'ci-repo'
- self_build(
- paths.CUR_BUILT_DDS,
- toolchain=opts.toolchain_2,
- cat_path=new_cat_path,
- dds_flags=[f'--repo-dir={new_repo_dir}'])
- print('Bootstrap test PASSED!')
-
- return pytest.main([
- '-v',
- '--durations=10',
- f'--basetemp={paths.BUILD_DIR / "_tmp"}',
- '-n',
- str(multiprocessing.cpu_count() + 2),
- 'tests/',
- ])
-
-
- if __name__ == "__main__":
- sys.exit(main(sys.argv[1:]))
|