|
|
|
|
|
|
|
|
import enum |
|
|
import enum |
|
|
from pathlib import Path |
|
|
from pathlib import Path |
|
|
|
|
|
import os |
|
|
from contextlib import contextmanager |
|
|
from contextlib import contextmanager |
|
|
from typing import Iterator |
|
|
|
|
|
|
|
|
from typing import Iterator, Optional, Mapping |
|
|
import sys |
|
|
import sys |
|
|
import urllib.request |
|
|
import urllib.request |
|
|
|
|
|
import platform |
|
|
import shutil |
|
|
import shutil |
|
|
|
|
|
|
|
|
from . import paths |
|
|
|
|
|
|
|
|
from . import paths, proc |
|
|
from .dds import DDSWrapper |
|
|
from .dds import DDSWrapper |
|
|
from .paths import new_tempdir |
|
|
from .paths import new_tempdir |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}.get(sys.platform) |
|
|
}.get(sys.platform) |
|
|
if filename is None: |
|
|
if filename is None: |
|
|
raise RuntimeError(f'We do not have a prebuilt DDS binary for the "{sys.platform}" platform') |
|
|
raise RuntimeError(f'We do not have a prebuilt DDS binary for the "{sys.platform}" platform') |
|
|
url = f'https://github.com/vector-of-bool/dds/releases/download/0.1.0-alpha.4/{filename}' |
|
|
|
|
|
|
|
|
url = f'https://github.com/vector-of-bool/dds/releases/download/0.1.0-alpha.6/{filename}' |
|
|
|
|
|
|
|
|
print(f'Downloading prebuilt DDS executable: {url}') |
|
|
print(f'Downloading prebuilt DDS executable: {url}') |
|
|
stream = urllib.request.urlopen(url) |
|
|
stream = urllib.request.urlopen(url) |
|
|
|
|
|
|
|
|
elif mode is BootstrapMode.Download: |
|
|
elif mode is BootstrapMode.Download: |
|
|
f = _do_bootstrap_download() |
|
|
f = _do_bootstrap_download() |
|
|
elif mode is BootstrapMode.Build: |
|
|
elif mode is BootstrapMode.Build: |
|
|
f = _do_bootstrap_build() # type: ignore # TODO |
|
|
|
|
|
|
|
|
f = _do_bootstrap_build() |
|
|
elif mode is BootstrapMode.Skip: |
|
|
elif mode is BootstrapMode.Skip: |
|
|
f = paths.PREBUILT_DDS |
|
|
f = paths.PREBUILT_DDS |
|
|
|
|
|
|
|
|
with pin_exe(f) as dds: |
|
|
with pin_exe(f) as dds: |
|
|
yield DDSWrapper(dds) |
|
|
yield DDSWrapper(dds) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def _do_bootstrap_build() -> Path: |
|
|
|
|
|
return _bootstrap_p6() |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def _bootstrap_p6() -> Path: |
|
|
|
|
|
prev_dds = _bootstrap_alpha_4() |
|
|
|
|
|
p6_dir = paths.PREBUILT_DIR / 'p6' |
|
|
|
|
|
ret_dds = _dds_in(p6_dir) |
|
|
|
|
|
if ret_dds.exists(): |
|
|
|
|
|
return ret_dds |
|
|
|
|
|
|
|
|
|
|
|
_clone_self_at(p6_dir, '0.1.0-alpha.6') |
|
|
|
|
|
tc = 'msvc-rel.jsonc' if platform.system() == 'Windows' else 'gcc-9-rel.jsonc' |
|
|
|
|
|
|
|
|
|
|
|
catalog_arg = f'--catalog={p6_dir}/_catalog.db' |
|
|
|
|
|
repo_arg = f'--repo-dir={p6_dir}/_repo' |
|
|
|
|
|
|
|
|
|
|
|
proc.check_run( |
|
|
|
|
|
[prev_dds, 'catalog', 'import', catalog_arg, '--json=old-catalog.json'], |
|
|
|
|
|
cwd=p6_dir, |
|
|
|
|
|
) |
|
|
|
|
|
proc.check_run( |
|
|
|
|
|
[ |
|
|
|
|
|
prev_dds, |
|
|
|
|
|
'build', |
|
|
|
|
|
catalog_arg, |
|
|
|
|
|
repo_arg, |
|
|
|
|
|
('--toolchain', p6_dir / 'tools' / tc), |
|
|
|
|
|
], |
|
|
|
|
|
cwd=p6_dir, |
|
|
|
|
|
) |
|
|
|
|
|
return ret_dds |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def _bootstrap_alpha_4() -> Path: |
|
|
|
|
|
prev_dds = _bootstrap_alpha_3() |
|
|
|
|
|
a4_dir = paths.PREBUILT_DIR / 'alpha-4' |
|
|
|
|
|
ret_dds = _dds_in(a4_dir) |
|
|
|
|
|
if ret_dds.exists(): |
|
|
|
|
|
return ret_dds |
|
|
|
|
|
|
|
|
|
|
|
_clone_self_at(a4_dir, '0.1.0-alpha.4') |
|
|
|
|
|
build_py = a4_dir / 'tools/build.py' |
|
|
|
|
|
proc.check_run( |
|
|
|
|
|
[ |
|
|
|
|
|
sys.executable, |
|
|
|
|
|
'-u', |
|
|
|
|
|
build_py, |
|
|
|
|
|
], |
|
|
|
|
|
env=_prev_dds_env(prev_dds), |
|
|
|
|
|
cwd=a4_dir, |
|
|
|
|
|
) |
|
|
|
|
|
return ret_dds |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def _bootstrap_alpha_3() -> Path: |
|
|
|
|
|
prev_dds = _bootstrap_p5() |
|
|
|
|
|
a3_dir = paths.PREBUILT_DIR / 'alpha-3' |
|
|
|
|
|
ret_dds = _dds_in(a3_dir) |
|
|
|
|
|
if ret_dds.exists(): |
|
|
|
|
|
return ret_dds |
|
|
|
|
|
|
|
|
|
|
|
_clone_self_at(a3_dir, '0.1.0-alpha.3') |
|
|
|
|
|
build_py = a3_dir / 'tools/build.py' |
|
|
|
|
|
proc.check_run( |
|
|
|
|
|
[ |
|
|
|
|
|
sys.executable, |
|
|
|
|
|
'-u', |
|
|
|
|
|
build_py, |
|
|
|
|
|
], |
|
|
|
|
|
env=_prev_dds_env(prev_dds), |
|
|
|
|
|
cwd=a3_dir, |
|
|
|
|
|
) |
|
|
|
|
|
return ret_dds |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def _bootstrap_p5() -> Path: |
|
|
|
|
|
prev_dds = _bootstrap_p4() |
|
|
|
|
|
p5_dir = paths.PREBUILT_DIR / 'p5' |
|
|
|
|
|
ret_dds = _dds_in(p5_dir) |
|
|
|
|
|
if ret_dds.exists(): |
|
|
|
|
|
return ret_dds |
|
|
|
|
|
|
|
|
|
|
|
_clone_self_at(p5_dir, 'bootstrap-p5') |
|
|
|
|
|
build_py = p5_dir / 'tools/build.py' |
|
|
|
|
|
proc.check_run( |
|
|
|
|
|
[ |
|
|
|
|
|
sys.executable, |
|
|
|
|
|
'-u', |
|
|
|
|
|
build_py, |
|
|
|
|
|
], |
|
|
|
|
|
env=_prev_dds_env(prev_dds), |
|
|
|
|
|
cwd=p5_dir, |
|
|
|
|
|
) |
|
|
|
|
|
return ret_dds |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def _bootstrap_p4() -> Path: |
|
|
|
|
|
prev_dds = _bootstrap_p1() |
|
|
|
|
|
p4_dir = paths.PREBUILT_DIR / 'p4' |
|
|
|
|
|
p4_dir.mkdir(exist_ok=True, parents=True) |
|
|
|
|
|
ret_dds = _dds_in(p4_dir) |
|
|
|
|
|
if ret_dds.exists(): |
|
|
|
|
|
return ret_dds |
|
|
|
|
|
|
|
|
|
|
|
_clone_self_at(p4_dir, 'bootstrap-p4') |
|
|
|
|
|
build_py = p4_dir / 'tools/build.py' |
|
|
|
|
|
proc.check_run( |
|
|
|
|
|
[ |
|
|
|
|
|
sys.executable, |
|
|
|
|
|
'-u', |
|
|
|
|
|
build_py, |
|
|
|
|
|
'--cxx=cl.exe' if platform.system() == 'Windows' else '--cxx=g++-8', |
|
|
|
|
|
], |
|
|
|
|
|
env=_prev_dds_env(prev_dds), |
|
|
|
|
|
) |
|
|
|
|
|
return ret_dds |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def _bootstrap_p1() -> Path: |
|
|
|
|
|
p1_dir = paths.PREBUILT_DIR / 'p1' |
|
|
|
|
|
p1_dir.mkdir(exist_ok=True, parents=True) |
|
|
|
|
|
ret_dds = _dds_in(p1_dir) |
|
|
|
|
|
if ret_dds.exists(): |
|
|
|
|
|
return ret_dds |
|
|
|
|
|
|
|
|
|
|
|
_clone_self_at(p1_dir, 'bootstrap-p1') |
|
|
|
|
|
build_py = p1_dir / 'tools/build.py' |
|
|
|
|
|
proc.check_run([ |
|
|
|
|
|
sys.executable, |
|
|
|
|
|
'-u', |
|
|
|
|
|
build_py, |
|
|
|
|
|
'--cxx=cl.exe' if platform.system() == 'Windows' else '--cxx=g++-8', |
|
|
|
|
|
]) |
|
|
|
|
|
_build_prev(p1_dir) |
|
|
|
|
|
return ret_dds |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def _clone_self_at(dir: Path, ref: str) -> None: |
|
|
|
|
|
if dir.is_dir(): |
|
|
|
|
|
shutil.rmtree(dir) |
|
|
|
|
|
dir.mkdir(exist_ok=True, parents=True) |
|
|
|
|
|
proc.check_run(['git', 'clone', '-qq', paths.PROJECT_ROOT, f'--branch={ref}', dir]) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def _dds_in(dir: Path) -> Path: |
|
|
|
|
|
return dir.joinpath('_build/dds' + paths.EXE_SUFFIX) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def _prev_dds_env(dds: Path) -> Mapping[str, str]: |
|
|
|
|
|
env = os.environ.copy() |
|
|
|
|
|
env.update({'DDS_BOOTSTRAP_PREV_EXE': str(dds)}) |
|
|
|
|
|
return env |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def _build_prev(dir: Path, prev_dds: Optional[Path] = None) -> None: |
|
|
|
|
|
build_py = dir / 'tools/build.py' |
|
|
|
|
|
proc.check_run( |
|
|
|
|
|
[ |
|
|
|
|
|
sys.executable, |
|
|
|
|
|
'-u', |
|
|
|
|
|
build_py, |
|
|
|
|
|
'--cxx=cl.exe' if platform.system() == 'Windows' else '--cxx=g++-8', |
|
|
|
|
|
], |
|
|
|
|
|
cwd=dir, |
|
|
|
|
|
env=None if prev_dds is None else os.environ.clone().update({'DDS_BOOTSTRAP_PREV_EXE', |
|
|
|
|
|
str(prev_dds)}), |
|
|
|
|
|
) |