123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192 |
- from __future__ import annotations
- import concurrent.futures
- import configparser
- import functools
- import os
- from libdevinfra.jobs import Job, Task, run_jobs
- from devenv import constants
- from devenv.lib import colima, config, fs, limactl, proc, venv, volta
- def main(context: dict[str, str]) -> int:
- repo = context["repo"]
- reporoot = context["reporoot"]
- FRONTEND_ONLY = os.environ.get("SENTRY_DEVENV_FRONTEND_ONLY") is not None
- # venv's still needed for frontend because repo-local devenv and pre-commit
- # exist inside it
- 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)
- # TODO: move volta version into per-repo config
- try:
- volta.install(reporoot)
- except TypeError:
- # this is needed for devenv <=1.4.0,>1.2.3 to finish syncing and therefore update itself
- volta.install()
- if constants.DARWIN:
- repo_config = configparser.ConfigParser()
- repo_config.read(f"{reporoot}/devenv/config.ini")
- try:
- colima.install(
- repo_config["colima"]["version"],
- repo_config["colima"][constants.SYSTEM_MACHINE],
- repo_config["colima"][f"{constants.SYSTEM_MACHINE}_sha256"],
- reporoot,
- )
- except TypeError:
- # this is needed for devenv <=1.4.0,>1.2.3 to finish syncing and therefore update itself
- 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
- try:
- limactl.install(reporoot)
- except TypeError:
- # this is needed for devenv <=1.4.0,>1.2.3 to finish syncing and therefore update itself
- limactl.install()
- jp1 = Task(
- name="upgrade pip",
- func=functools.partial(
- proc.run,
- (
- f"{venv_dir}/bin/python3",
- "-m",
- "pip",
- "--disable-pip-version-check",
- "install",
- "--constraint",
- "requirements-dev-frozen.txt",
- "pip",
- ),
- stdout=True,
- ),
- )
- jp2 = Task(
- name="uninstall some problems",
- func=functools.partial(
- proc.run,
- (
- f"{venv_dir}/bin/python3",
- "-m",
- "pip",
- "--disable-pip-version-check",
- "uninstall",
- "-qqy",
- "djangorestframework-stubs",
- "django-stubs",
- ),
- stdout=True,
- ),
- )
- jp3 = Task(
- name="install dependencies",
- func=functools.partial(
- proc.run,
- (
- f"{venv_dir}/bin/python3",
- "-m",
- "pip",
- "--disable-pip-version-check",
- "install",
- "--constraint",
- "requirements-dev-frozen.txt",
- "-r",
- "requirements-dev-frozen.txt",
- ),
- stdout=True,
- ),
- )
- jp4 = Task(
- name="install editable",
- func=functools.partial(
- proc.run,
- (f"{venv_dir}/bin/python3", "-m", "tools.fast_editable", "--path", "."),
- stdout=True,
- ),
- )
- jp5 = Task(
- name="init sentry config",
- func=functools.partial(
- proc.run,
- (f"{venv_dir}/bin/sentry", "init", "--dev", "--no-clobber"),
- stdout=True,
- ),
- )
- jpc1 = Task(
- name="install pre-commit dependencies",
- func=functools.partial(
- proc.run,
- (f"{venv_dir}/bin/pre-commit", "install", "--install-hooks", "-f"),
- stdout=True,
- ),
- )
- jm1 = Task(
- name="bring up redis and postgres",
- func=functools.partial(
- proc.run,
- (f"{venv_dir}/bin/sentry", "devservices", "up", "redis", "postgres"),
- stdout=True,
- ),
- )
- jm2 = Task(
- name="apply migrations",
- func=functools.partial(
- proc.run,
- ("make", "apply-migrations"),
- pathprepend=f"{venv_dir}/bin:{reporoot}/.devenv/bin",
- env={"VIRTUAL_ENV": venv_dir},
- stdout=True,
- ),
- )
- jt1 = Task(
- name="install js dependencies",
- func=functools.partial(
- proc.run,
- (
- "yarn",
- "install",
- "--frozen-lockfile",
- "--no-progress",
- "--non-interactive",
- ),
- pathprepend=f"{venv_dir}/bin:{reporoot}/.devenv/bin",
- env={
- "NODE_ENV": "development",
- "VOLTA_HOME": f"{reporoot}/.devenv/bin/volta-home",
- },
- stdout=True,
- ),
- )
- jp = Job(name="python dependencies", tasks=(jp1, jp2, jp3, jp4, jp5))
- jm = Job(name="sentry migrations", tasks=(jm1, jm2))
- jpc = Job(name="pre-commit dependencies", tasks=(jpc1,))
- jt = Job(name="javascript dependencies", tasks=(jt1,))
- # after python deps are installed we can install pre-commit deps
- jp3.spawn_jobs = (jpc,)
- # Frontend engineers don't necessarily always have devservices running and
- # can configure to skip them to save on local resources
- if FRONTEND_ONLY:
- print("Skipping python migrations since SENTRY_DEVENV_FRONTEND_ONLY is set.")
- else:
- jp5.spawn_jobs = (jm,)
- with concurrent.futures.ThreadPoolExecutor() as tpe:
- run_jobs((jp, jt), tpe)
- fs.ensure_symlink("../../config/hooks/post-merge", f"{reporoot}/.git/hooks/post-merge")
|