#!/usr/bin/env python3 import argparse import csv import logging from pathlib import Path import pickle import git import sarge logging.basicConfig(format='%(levelname)s:%(message)s', level=logging.INFO) class GitHashCache: def __init__(self, cache_file): self.cache = cache_file self._data = dict() def __getitem__(self, key): if key not in self._data: return "" return self._data[key] def __setitem__(self, key, value): self._data[key] = value def save(self): logging.debug("Saving pickled data") with open(self.cache, "wb") as handle: pickle.dump(self._data, handle, pickle.HIGHEST_PROTOCOL) def load(self): if not Path(self.cache).exists(): logging.debug("File cache not found, not loading") return logging.debug("Saving pickled data") with open(self.cache, "rb") as handle: self._data = pickle.load(handle) def lsremote(url): remote_refs = {} g = git.cmd.Git() for ref in g.ls_remote(url).split('\n'): hash_ref_list = ref.split('\t') remote_refs[hash_ref_list[1]] = hash_ref_list[0] return remote_refs def get_remote_hash(url, branch="master"): refs = "refs/heads/{}".format(branch) return lsremote(url)[refs] def run_osc(repository, package_name): cmd = "osc service remoterun {0} {1}" cmd = cmd.format(repository, package_name) logging.debug("Running {}".format(cmd)) pid = sarge.run(cmd) if pid.returncode != 0: logging.error("Error during service run, package {}".format( package_name)) logging.debug("Package {} complete".format(package_name)) def update_package(hash_data, package_name, remote_name, obs_repository, branch): repo_name = "kde:{}".format(remote_name) remote_hash = get_remote_hash(repo_name, branch) current_hash = hash_data[remote_name] logging.debug("Package {}, theirs {}, ours {}".format(remote_name, remote_hash, current_hash)) if remote_hash != current_hash: logging.debug("Hash doesn't match, updating") run_osc(obs_repository, package_name) hash_data[remote_name] = remote_hash def update_packages(cache_file, obs_repository, repo_mapping_file): hash_data = GitHashCache(cache_file) hash_data.load() logging.info("Updating packages for {}".format(obs_repository)) with open(repo_mapping_file, "r") as mapping: reader = csv.reader(mapping, delimiter="\t") for row in reader: kde_name, obs_name, branch = row branch = "master" if not branch else branch logging.debug("Updating package {} ({})".format(kde_name, obs_name)) logging.debug("Using branch {}".format(branch)) update_package(hash_data, obs_name, kde_name, obs_repository, branch) logging.debug("Saving data") hash_data.save() def main(): parser = argparse.ArgumentParser() parser.add_argument("repository", help="OBS repository to use") parser.add_argument("mapping_file", help="KDE:OBS repository mapping file") options = parser.parse_args() cache_file = Path.home() / ".local/share/obs_{}_cache".format(options.repository.replace(":", "_")) cache_file = str(cache_file) update_packages(cache_file, options.repository, options.mapping_file) logging.info("Complete") if __name__ == "__main__": main()