From 628ec96975ab84b4e13567c8d4bdc25ad1a8f937 Mon Sep 17 00:00:00 2001 From: Christoph Reiter Date: Wed, 8 Apr 2020 20:46:47 +0200 Subject: [PATCH] Include cygwin related info in the base packages We might add a mapping and version checks in the future, but this is a start. See #17 --- main.py | 63 ++++++++++++++++++++++++++++++++++++++++++++- templates/base.html | 9 +++++++ test_main.py | 19 +++++++++++++- 3 files changed, 89 insertions(+), 2 deletions(-) diff --git a/main.py b/main.py index 8866ba8..314be27 100755 --- a/main.py +++ b/main.py @@ -113,10 +113,15 @@ ARCH_MAPPING_CONFIG = [ "", "") ] +CYGWIN_VERSION_CONFIG = [ + ("https://mirrors.kernel.org/sourceware/cygwin/x86_64/setup.ini", + "", "") +] + def get_update_urls() -> List[str]: urls = [] - for config in VERSION_CONFIG + SRCINFO_CONFIG + ARCH_MAPPING_CONFIG: + for config in VERSION_CONFIG + SRCINFO_CONFIG + ARCH_MAPPING_CONFIG + CYGWIN_VERSION_CONFIG: urls.append(config[0]) for repo in REPOSITORIES: urls.append(repo.files_url) @@ -135,6 +140,9 @@ class ArchMapping: self.skipped = set(json_object.get("skipped", [])) +CygwinVersions = Dict[str, Tuple[str, str, str]] + + class AppState: def __init__(self) -> None: @@ -146,6 +154,7 @@ class AppState: self._sourceinfos: Dict[str, SrcInfoPackage] = {} self._versions: Dict[str, Tuple[str, str, int]] = {} self._arch_mapping: ArchMapping = ArchMapping() + self._cygwin_versions: CygwinVersions = {} self._update_etag() def _update_etag(self) -> None: @@ -196,6 +205,15 @@ class AppState: self._arch_mapping = arch_mapping self._update_etag() + @property + def cygwin_versions(self) -> CygwinVersions: + return self._cygwin_versions + + @cygwin_versions.setter + def cygwin_versions(self, cygwin_versions: CygwinVersions) -> None: + self._cygwin_versions = cygwin_versions + self._update_etag() + UPDATE_INTERVAL = 60 * 5 REQUEST_TIMEOUT = 60 @@ -410,6 +428,15 @@ class Source: licenses.update(p.licenses) return sorted(licenses) + @property + def cygwin_info(self) -> Optional[Tuple[str, str, str]]: + global state + + cygwin_versions = state.cygwin_versions + if self.name in cygwin_versions: + return cygwin_versions[self.name] + return None + @property def arch_url(self) -> str: arch_info = get_arch_info_for_base(self) @@ -873,6 +900,39 @@ def update_arch_mapping() -> None: state.arch_mapping = ArchMapping(json.loads(data)) +def parse_cygwin_versions(base_url: str, data: bytes) -> CygwinVersions: + # This is kinda hacky: extract the source name from the src tarball and take + # last version line before it + version = None + source_package = None + versions: CygwinVersions = {} + base_url = base_url.rsplit("/", 2)[0] + print(base_url) + for line in data.decode("utf-8").splitlines(): + if line.startswith("version:"): + version = line.split(":", 1)[-1].strip().split("-", 1)[0].split("+", 1)[0] + elif line.startswith("source:"): + source = line.split(":", 1)[-1].strip() + fn = source.rsplit(None, 2)[0] + source_package = fn.rsplit("/")[-1].rsplit("-", 3)[0] + src_url = base_url + "/" + fn + assert version is not None + if source_package not in versions: + versions[source_package] = (version, "https://cygwin.com/packages/summary/%s-src.html" % source_package, src_url) + return versions + + +def update_cygwin_versions() -> None: + global state, CYGWIN_VERSION_CONFIG + + print("update cygwin info") + url = CYGWIN_VERSION_CONFIG[0][0] + print("Loading %r" % url) + data = get_content_cached(url, timeout=REQUEST_TIMEOUT) + cygwin_versions = parse_cygwin_versions(url, data) + state.cygwin_versions = cygwin_versions + + def update_versions() -> None: global VERSION_CONFIG, state @@ -1322,6 +1382,7 @@ def update_thread() -> None: with check_needs_update() as needs: if needs: update_arch_mapping() + update_cygwin_versions() update_source() update_sourceinfos() update_versions() diff --git a/templates/base.html b/templates/base.html index 76056b4..218e601 100644 --- a/templates/base.html +++ b/templates/base.html @@ -63,6 +63,15 @@ {% endif%} +
Cygwin Info:
+
+ {% if s.cygwin_info %} + {{ s.cygwin_info[0] }} | {{ s.cygwin_info[2].rsplit("/")[-1] }} + {% else %} + - + {% endif%} +
+
GIT Version:
{{ s.git_version or "-" }} diff --git a/test_main.py b/test_main.py index 30d9a1d..71ddba3 100644 --- a/test_main.py +++ b/test_main.py @@ -1,7 +1,7 @@ # type: ignore import pytest -from main import app +from main import app, parse_cygwin_versions @pytest.fixture @@ -18,3 +18,20 @@ def test_main_endpoints(client): for name in endpoints: r = client.get('/' + name, follow_redirects=True) assert r.status_code == 200 + + +def test_parse_cygwin_versions(): + data = b"""\ +@ python36 +category: Python Interpreters +requires: binutils cygwin libbz2_1 libcrypt0 libcrypt2 libexpat1 libffi6 +version: 3.6.9-1 +install: x86_64/release/python36/python36-3.6.9-1.tar.xz 5750152 96dd43cf9 +source: x86_64/release/python36/python36-3.6.9-1-src.tar.xz 17223444 ef39d9419""" + + setup_ini_url = "https://mirrors.kernel.org/sourceware/cygwin/x86_64/setup.ini" + versions = parse_cygwin_versions(setup_ini_url, data) + assert "python36" in versions + assert versions["python36"][0] == "3.6.9" + assert versions["python36"][1] == "https://cygwin.com/packages/summary/python36-src.html" + assert versions["python36"][2] == "https://mirrors.kernel.org/sourceware/cygwin/x86_64/release/python36/python36-3.6.9-1-src.tar.xz"