123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164 |
- from __future__ import annotations
- import configparser
- import os
- import subprocess
- from devenv import constants
- from devenv.lib import venv # type: ignore[attr-defined]
- from devenv.lib import colima, config, limactl, proc, volta
- # TODO: need to replace this with a nicer process executor in devenv.lib
- def run_procs(
- repo: str,
- reporoot: str,
- venv_path: str,
- _procs: tuple[tuple[str, tuple[str, ...]], ...],
- ) -> bool:
- procs: list[tuple[str, tuple[str, ...], subprocess.Popen[bytes]]] = []
- for name, cmd in _procs:
- print(f"⏳ {name}")
- if constants.DEBUG:
- proc.xtrace(cmd)
- procs.append(
- (
- name,
- cmd,
- subprocess.Popen(
- cmd,
- stdout=subprocess.PIPE,
- stderr=subprocess.STDOUT,
- env={
- **constants.user_environ,
- **proc.base_env,
- "VIRTUAL_ENV": venv_path,
- "VOLTA_HOME": constants.VOLTA_HOME,
- "PATH": f"{venv_path}/bin:{proc.base_path}",
- },
- cwd=reporoot,
- ),
- )
- )
- all_good = True
- for name, final_cmd, p in procs:
- out, _ = p.communicate()
- if p.returncode != 0:
- all_good = False
- out_str = "" if out is None else out.decode()
- print(
- f"""
- ❌ {name}
- failed command (code p.returncode):
- {proc.quote(final_cmd)}
- Output:
- {out_str}
- """
- )
- else:
- print(f"✅ {name}")
- return all_good
- def main(context: dict[str, str]) -> int:
- repo = context["repo"]
- reporoot = context["reporoot"]
- venv_dir, python_version, requirements, editable_paths, bins = venv.get(reporoot, repo)
- url, sha256 = config.get_python(reporoot, python_version)
- print(f"ensuring {repo} venv at {venv_dir}...")
- venv.ensure(venv_dir, python_version, url, sha256)
- # This is for engineers with existing dev environments transitioning over.
- # Bootstrap will set devenv-managed volta up but they won't be running
- # devenv bootstrap, just installing devenv then running devenv sync.
- # make install-js-dev will fail since our run_procs expects devenv-managed
- # volta.
- volta.install()
- if constants.DARWIN:
- repo_config = configparser.ConfigParser()
- repo_config.read(f"{reporoot}/devenv/config.ini")
- # we don't officially support colima on linux yet
- if constants.CI:
- # colima 0.6.8 doesn't work with macos-13,
- # but integration coverage is still handy
- colima.install(
- "v0.6.2",
- "https://github.com/abiosoft/colima/releases/download/v0.6.2/colima-Darwin-x86_64",
- "43ef3fc80a8347d51b8ec1706f9caf8863bd8727a6f7532caf1ccd20497d8485",
- )
- else:
- colima.install(
- repo_config["colima"]["version"],
- repo_config["colima"][constants.SYSTEM_MACHINE],
- repo_config["colima"][f"{constants.SYSTEM_MACHINE}_sha256"],
- )
- # TODO: move limactl version into per-repo config
- limactl.install()
- if not run_procs(
- repo,
- reporoot,
- venv_dir,
- (
- ("javascript dependencies", ("make", "install-js-dev")),
- ("python dependencies", ("make", "install-py-dev")),
- ),
- ):
- return 1
- if not run_procs(
- repo,
- reporoot,
- venv_dir,
- (
- (
- "git and precommit",
- # this can't be done in paralell with python dependencies
- # as multiple pips cannot act on the same venv
- ("make", "setup-git"),
- ),
- ),
- ):
- return 1
- if not os.path.exists(f"{constants.home}/.sentry/config.yml") or not os.path.exists(
- f"{constants.home}/.sentry/sentry.conf.py"
- ):
- proc.run((f"{venv_dir}/bin/sentry", "init", "--dev"))
- # TODO: check healthchecks for redis and postgres to short circuit this
- proc.run(
- (
- f"{venv_dir}/bin/{repo}",
- "devservices",
- "up",
- "redis",
- "postgres",
- ),
- exit=True,
- )
- if run_procs(
- repo,
- reporoot,
- venv_dir,
- (
- (
- "python migrations",
- ("make", "apply-migrations"),
- ),
- ),
- ):
- return 0
- return 1
|