2023-03-24 14:09:24 +01:00

101 lines
3.1 KiB
Python

import os
from contextlib import contextmanager
from datetime import timedelta
from functools import lru_cache
from typing import Any, AnyStr, Dict, Generator, List, Union
import requests
from requests.adapters import HTTPAdapter
from .config import REQUESTS_RETRY, REQUESTS_TIMEOUT, Config
PathLike = Union[os.PathLike, AnyStr]
SCRIPT_DIR = os.path.dirname(os.path.realpath(__file__))
def requests_cache_disabled() -> Any:
import requests_cache
return requests_cache.disabled()
@lru_cache(maxsize=None)
def get_requests_session(nocache: bool = False) -> requests.Session:
adapter = HTTPAdapter(max_retries=REQUESTS_RETRY)
if nocache:
with requests_cache_disabled():
http = requests.Session()
else:
http = requests.Session()
http.mount("https://", adapter)
http.mount("http://", adapter)
return http
@contextmanager
def install_requests_cache() -> Generator:
# This adds basic etag based caching, to avoid hitting API rate limiting
import requests_cache
from requests_cache.backends.sqlite import SQLiteCache
# Monkey patch globally, so pygithub uses it as well.
# Only do re-validation with etag/date etc and ignore the cache-control headers that
# github sends by default with 60 seconds.
cache_dir = os.path.join(os.getcwd(), '.autobuild_cache')
os.makedirs(cache_dir, exist_ok=True)
requests_cache.install_cache(
always_revalidate=True,
cache_control=False,
expire_after=requests_cache.EXPIRE_IMMEDIATELY,
backend=SQLiteCache(os.path.join(cache_dir, 'http_cache.sqlite')))
# Call this once, so it gets cached from the main thread and can be used in a thread pool
get_requests_session(nocache=True)
try:
yield
finally:
# Delete old cache entries, so this doesn't grow indefinitely
cache = requests_cache.get_cache()
assert cache is not None
cache.delete(older_than=timedelta(hours=3))
# un-monkey-patch again
requests_cache.uninstall_cache()
@contextmanager
def gha_group(title: str) -> Generator:
print(f'\n::group::{title}')
try:
yield
finally:
print('::endgroup::')
def queue_website_update() -> None:
session = get_requests_session()
r = session.post('https://packages.msys2.org/api/trigger_update', timeout=REQUESTS_TIMEOUT)
try:
# it's not worth stopping the build if this fails, so just log it
r.raise_for_status()
except requests.RequestException as e:
print(e)
def parse_optional_deps(optional_deps: str) -> Dict[str, List[str]]:
res: Dict[str, List[str]] = {}
optional_deps = optional_deps.replace(" ", "")
if not optional_deps:
return res
for entry in optional_deps.split(","):
assert ":" in entry
first, second = entry.split(":", 2)
res.setdefault(first, []).append(second)
return res
def apply_optional_deps(optional_deps: str) -> None:
for dep, ignored in parse_optional_deps(optional_deps).items():
Config.OPTIONAL_DEPS.setdefault(dep, []).extend(ignored)