1
0
Fork 0

Update update_unstable.py

- Port to Python 3.8 syntax
- Use type annotations
- Add a matrix notification using matrix-commander
This commit is contained in:
Luca Beltrame 2022-01-15 00:20:05 +01:00
parent 1a35e5637c
commit 86fe82e6cd
Signed by: einar
GPG key ID: 4707F46E9EC72DEC

View file

@ -3,43 +3,56 @@
# SPDX-License-Identifier: BSD-3-clause # SPDX-License-Identifier: BSD-3-clause
import argparse import argparse
from datetime import date
from collections import defaultdict
import logging import logging
import json import json
from pathlib import Path from pathlib import Path
from typing import Union, Dict, Any
from urllib.parse import quote from urllib.parse import quote
import git import git
import requests import requests
import sarge
API_URL = "https://invent.kde.org/api/v4/projects/" API_URL = "https://invent.kde.org/api/v4/projects/"
OBS_URL = "https://api.opensuse.org/trigger/runservice" OBS_URL = "https://api.opensuse.org/trigger/runservice"
MESSAGE_TEMPLATE = f"""
### OBS package update complete
Stats for {date.today().strftime('%Y-%m-%d')}:
"""
class GitHashCache: class GitHashCache:
def __init__(self, cache_file): def __init__(self, cache_file: str) -> None:
self.cache = cache_file self.cache = cache_file
self._data = dict() self._data: Dict[str, Dict[str, str]] = dict()
def __getitem__(self, key): def __getitem__(self, key: str) -> Dict[str, str]:
if key not in self._data: if key not in self._data:
return "" raise KeyError
return self._data[key] return self._data[key]
def __setitem__(self, key, value): def __setitem__(self, key: str, value: Dict[str, str]) -> None:
self._data[key] = value self._data[key] = value
def get(self, key, *args, **kwargs): def get(self, key: str,
*args: Any, **kwargs: Any) -> Union[None, str, Dict[str, str]]:
return self._data.get(key, *args, **kwargs) return self._data.get(key, *args, **kwargs)
def save(self): def save(self) -> None:
logging.debug("Saving pickled data") logging.debug("Saving pickled data")
with open(self.cache, "w") as handle: with open(self.cache, "w") as handle:
json.dump(self._data, handle, indent=4) json.dump(self._data, handle, indent=4)
def load(self): def load(self) -> None:
if not Path(self.cache).exists(): if not Path(self.cache).exists():
logging.debug("File cache not found, not loading") logging.debug("File cache not found, not loading")
@ -49,7 +62,7 @@ class GitHashCache:
self._data = json.load(handle) self._data = json.load(handle)
def project_exists(project): def project_exists(project: str) -> bool:
# We want / to get quoted, so put safe to "" # We want / to get quoted, so put safe to ""
project_name = quote(project, safe="") project_name = quote(project, safe="")
request = requests.get(API_URL + project_name) request = requests.get(API_URL + project_name)
@ -60,7 +73,7 @@ def project_exists(project):
return False return False
def lsremote(url): def lsremote(url: str) -> Dict[str, str]:
remote_refs = {} remote_refs = {}
gitcmd = git.cmd.Git() gitcmd = git.cmd.Git()
@ -71,12 +84,13 @@ def lsremote(url):
return remote_refs return remote_refs
def get_remote_hash(url, branch="master"): def get_remote_hash(url: str, branch: str = "master") -> str:
refs = "refs/heads/{}".format(branch) refs = "refs/heads/{}".format(branch)
return lsremote(url)[refs] return lsremote(url)[refs]
def trigger_update(repository, package_name, token): def trigger_update(repository: str, package_name: str,
token: str) -> Union[requests.Response, bool]:
header = {"Authorization": f"Token {token}"} header = {"Authorization": f"Token {token}"}
parameters = {"project": repository, "package": package_name} parameters = {"project": repository, "package": package_name}
@ -94,9 +108,11 @@ def trigger_update(repository, package_name, token):
return result return result
def update_package(hash_data, package_name, def update_package(hash_data: GitHashCache, package_name: str,
remote_name, obs_repository, remote_name: str, obs_repository: str,
branch, token): branch: str,
token: str,
stats: Dict[str, int]) -> None:
repo_name = "https://invent.kde.org/{}".format(remote_name) repo_name = "https://invent.kde.org/{}".format(remote_name)
@ -119,19 +135,26 @@ def update_package(hash_data, package_name,
logging.debug("Hash doesn't match, updating") logging.debug("Hash doesn't match, updating")
if trigger_update(obs_repository, package_name, token): if trigger_update(obs_repository, package_name, token):
hash_data[obs_repository][remote_name] = remote_hash hash_data[obs_repository][remote_name] = remote_hash
stats["updated"] += 1
hash_data.save() hash_data.save()
else:
stats["errors"] += 1
def update_packages(cache_file, repo_mapping_file, token): def update_packages(cache_file: str,
repo_mapping_file: str, token: str) -> None:
hash_data = GitHashCache(cache_file) hash_data = GitHashCache(cache_file)
hash_data.load() hash_data.load()
stats = dict()
with open(repo_mapping_file, "r") as mapping: with open(repo_mapping_file, "r") as mapping:
repo_data = json.load(mapping) repo_data = json.load(mapping)
for obs_repository, branch_data in repo_data.items(): for obs_repository, branch_data in repo_data.items():
repo_stats: Dict[str, int] = defaultdict(int)
logging.info("Updating packages for %s", obs_repository) logging.info("Updating packages for %s", obs_repository)
@ -144,13 +167,30 @@ def update_packages(cache_file, repo_mapping_file, token):
package_name, obs_name) package_name, obs_name)
logging.debug("Using branch %s", branch) logging.debug("Using branch %s", branch)
update_package(hash_data, obs_name, kde_name, obs_repository, update_package(hash_data, obs_name, kde_name, obs_repository,
branch, token) branch, token, repo_stats)
stats[obs_repository] = repo_stats
logging.debug("Saving data") logging.debug("Saving data")
hash_data.save() hash_data.save()
notify_matrix(stats)
def commit_changes(cache_file, repo_home): def notify_matrix(stats: Dict[str, Dict[str, int]]) -> None:
structure = [MESSAGE_TEMPLATE]
for key, value in stats.items():
row = (f"* {key}: {stats['updated']} updated packages,"
f" {stats['errors']} errors")
structure.append(row)
message = "\n".join(structure)
cmd = ["matrix_commander.py", "--markdown", "-m", message]
logging.debug("Sending Matrix notification")
sarge.run(cmd)
def commit_changes(cache_file: str, repo_home: str) -> None:
repo = git.Repo(repo_home) repo = git.Repo(repo_home)
repo.index.add([cache_file]) repo.index.add([cache_file])
@ -160,7 +200,7 @@ def commit_changes(cache_file, repo_home):
origin.push() origin.push()
def main(): def main() -> None:
parser = argparse.ArgumentParser() parser = argparse.ArgumentParser()
parser.add_argument( parser.add_argument(