def get_compatible_commit_from_tags(self) -> Optional[Commit]: """ This method is new for v6, but intentionally undocumented because we still want extension devs to use the old way until Ulauncher 5/apiv2 is fully phased out """ tags = {} # pagination is only implemented for GitHub (default 30, max 100) tags_url = f"{self.host_api}/repos/{self.user}/{self.repo}/tags?per_page=100" if self.host == "gitlab.com": # GitLab's API allows to filter out tags starting with our prefix tags_url = f"{self.host_api}/tags?search=^apiv" tags_data, _ = json_fetch(tags_url) try: for tag in tags_data or []: if tag["name"].startswith("apiv") and satisfies(API_VERSION, tag["name"][4:]): commit = tag["commit"] verion = tag["name"][4:] id = commit.get("sha", commit["id"]) # id fallback is needed for GitLab commit_time = commit.get("created", commit.get("created_at")) tags[verion] = (id, commit_time) except (KeyError, TypeError): pass if tags: id, commit_time = tags[max(tags)] if id and self.host == "github.com": # GitHub's tag API doesn't give any dates commit_data, _ = json_fetch(f"{self.host_api}/repos/{self.user}/{self.repo}/commits/{id}") commit_time = commit_data["commiter"]["date"] if id and commit_time: return id, datetime.strptime(commit_time, self.date_format) return None
def check_compatibility(self): if not satisfies(API_VERSION, self.get_required_api_version()): err_msg = ( f'Extension "{self.extension_id}" requires API version {self.get_required_api_version()}, ' f'but the current API version is: {API_VERSION})') raise ExtensionManifestError(err_msg, ErrorName.ExtensionCompatibilityError)
def get_compatible_commit_from_versions_json(self) -> Optional[Commit]: # This saves us a request compared to using the "raw" file API that needs to know the branch versions = [] try: versions = json.loads(self.fetch_file("versions.json") or "[]") except URLError: pass self.validate_versions(versions) versions_filter = (v['commit'] for v in versions if satisfies(API_VERSION, v['required_api_version'])) ref = next(versions_filter, None) return self.get_commit(ref) if ref else None
def find_compatible_version(self) -> Commit: """ Finds maximum version that is compatible with current version of Ulauncher and returns a commit or branch/tag name :raises ulauncher.modes.extensions.GithubExtension.InvalidVersionsFileError: """ sha_or_branch = "" for ver in self.read_versions(): if satisfies(API_VERSION, ver['required_api_version']): sha_or_branch = ver['commit'] if not sha_or_branch: raise GithubExtensionError( f"This extension is not compatible with current version Ulauncher extension API (v{API_VERSION})", ErrorName.IncompatibleVersion) return self.get_commit(sha_or_branch)
def get_latest_compatible_commit(self) -> Commit: """ Finds first version that is compatible with users Ulauncher version. Returns a commit hash and datetime. """ try: manifest = json.loads(self.fetch_file("manifest.json") or "{}") except URLError as e: raise ExtensionRemoteError("Could not access repository", ExtensionError.Network) from e if satisfies(API_VERSION, manifest.get("required_api_version")): return self.get_commit("HEAD") commit = self.get_compatible_commit_from_tags() or self.get_compatible_commit_from_versions_json() if not commit: message = f"This extension is not compatible with your Ulauncher API version (v{API_VERSION})." raise ExtensionRemoteError(message, ExtensionError.Incompatible) return commit