Pastery

github_install +

 1#!/usr/bin/env python3 2 3""" 4Install .deb packages from GitHub releases directly. 5 6Use as: 7    sudo ./github_install BurntSushi/ripgrep sharkdp/fd 8""" 9import re10import subprocess11import sys12import tempfile13from typing import Optional14from typing import Tuple1516import requests171819def download_file(url: str, temp_dir: str) -> str:20    local_filename = url.split("/")[-1]21    with requests.get(url, stream=True) as r:22        r.raise_for_status()23        with open(temp_dir + "/file.deb", "wb") as f:24            for chunk in r.iter_content(chunk_size=8192):25                f.write(chunk)26    return temp_dir + "/file.deb"272829def get_installed_version(package_name: str) -> Optional[str]:30    try:31        out = subprocess.check_output(32            ["apt", "show", package_name], stderr=subprocess.DEVNULL33        )34    except subprocess.CalledProcessError:35        return None36    return re.search("Version:\s+v?(.*)", out.decode()).group(1)373839def get_repo_details(repo_name: str) -> Tuple[str, str]:40    r = requests.get(f"https://api.github.com/repos/{repo_name}/releases/latest")41    version = r.json()["tag_name"].strip("v")4243    urls = [x["browser_download_url"] for x in r.json()["assets"]]44    linux_urls = sorted(45        (url for url in urls if "amd64" in url and "deb" in url), reverse=True46    )47    url = linux_urls[0] if linux_urls else None48    return version, url495051def install_package(repo_name: str) -> None:52    print(f"Processing {repo_name}...")53    package_name = repo_name.split("/")[1]54    installed_version = get_installed_version(package_name)55    repo_version, url = get_repo_details(repo_name)56    if not url:57        sys.exit("Could not find a suitable download for this package.")5859    if installed_version == repo_version:60        print(61            f"{package_name} is up to date at {installed_version}, will not continue."62        )63        return6465    if installed_version:66        print(67            f"Version {repo_version} found for {package_name}, which is currently at {installed_version}, upgrading..."68        )69    else:70        print(71            f"Version {repo_version} found for {package_name}, which is currently not installed, installing..."72        )7374    print(f"URL: {url}")7576    with tempfile.TemporaryDirectory() as temp_dir:77        file_name = download_file(url, temp_dir)78        subprocess.run(["dpkg", "-i", file_name])798081if __name__ == "__main__":82    repos = sys.argv[1:]83    for repo in repos:84        install_package(repo)85    print("Done.")
New paste