Skip to content

Instantly share code, notes, and snippets.

@Palpatineli
Last active October 5, 2023 16:38
Show Gist options
  • Save Palpatineli/1046481088eaeca8c6895f58f8236df9 to your computer and use it in GitHub Desktop.
Save Palpatineli/1046481088eaeca8c6895f58f8236df9 to your computer and use it in GitHub Desktop.
auto-updater
#!/usr/bin/env python3
"""Update binaries from github release page. Check if there are new binaries and download the files
"""
from pathlib import Path
from datetime import datetime, timedelta
import json
import requests
import re
import subprocess
BIN_DIR = Path('~/.local/bin/').expanduser()
SHARE_DIR = Path('~/.local/share').expanduser()
DOWNLOAD_DIR = Path('~/.local/share/downloads').expanduser()
tools = {
'nvim': {'repo': 'neovim/neovim', 'filter': 'linux64', 'binary': 'bin/nvim', 'need_folder': True},
'sg': {'repo': 'ast-grep/ast-grep', 'filter': 'x86_64-.*linux-gnu'},
'exa': {'repo': 'ogham/exa', 'filter': 'linux-x86_64-musl', 'binary': 'bin/exa'},
'fd': {'repo': 'sharkdp/fd', 'filter': 'x86_64-unknown-linux-musl'},
'mcfly': {'repo': 'cantino/mcfly', 'filter': 'x86_64-unknown-linux-musl'},
'rg': {'repo': 'BurntSushi/ripgrep', 'filter': 'x86_64-unknown-linux-musl'},
'starship': {'repo': 'starship/starship', 'filter': 'x86_64-unknown-linux-musl'},
'zoxide': {'repo': 'ajeetdsouza/zoxide', 'filter': 'x86_64-unknown-linux-musl'},
'lazygit': {'repo': 'jesseduffield/lazygit', 'filter': 'Linux_x86_64'},
}
BIN_DIR.mkdir(parents=True, exist_ok=True)
SHARE_DIR.mkdir(parents=True, exist_ok=True)
for name, config in tools.items():
# name, config = 'sg', tools['sg']
print(f"[checking] {name}")
res = requests.get(f'https://api.github.com/repos/{config["repo"]}/releases')
res = json.loads(res.content)
filter_re = re.compile(config['filter'])
out = []
for release in res:
for asset in release['assets']:
if 'sha' in asset['name'].rsplit('.', maxsplit=1)[-1]:
continue
if filter_re.findall(asset['name']):
release['assets'] = asset
out.append(release)
if any(x['prerelease'] for x in out):
recent = sorted([x for x in out if x['prerelease']], key=lambda x: x['created_at'])[-1]
else:
recent = sorted(out, key=lambda x: x['created_at'])[-1]
try:
local_time = datetime.fromtimestamp(BIN_DIR.joinpath(name).stat().st_mtime)
except FileNotFoundError:
local_time = datetime.fromtimestamp(0)
remote_date = datetime.strptime(recent['created_at'], '%Y-%m-%dT%H:%M:%SZ').date()
if remote_date <= local_time.date() + timedelta(days=1):
print(f"[skipped] no new binaries for {name}")
continue
print(f"[downloading] {name}, recent package from {remote_date}, newer than local package from {local_time.date()}")
ballname = recent['assets']['name']
subprocess.run(['wget', recent['assets']['browser_download_url'], '-O', DOWNLOAD_DIR.joinpath(ballname)])
DOWNLOAD_DIR.joinpath(name).mkdir(exist_ok=True)
download_folder = DOWNLOAD_DIR.joinpath(name)
if ballname.endswith('.zip'):
subprocess.run(['unzip', DOWNLOAD_DIR.joinpath(ballname), '-d', download_folder])
ballstem = ballname[:-4]
else:
subprocess.run(['tar', 'xf', DOWNLOAD_DIR.joinpath(ballname), '-C', download_folder])
ballstem = ballname[:-7]
if config.get('need_folder'):
subprocess.run(['cp', '-r', download_folder.joinpath(ballstem), SHARE_DIR.joinpath(name)])
subprocess.run(['ln', '-s', SHARE_DIR.joinpath(name, config['binary']), BIN_DIR.joinpath(name)])
else:
source = download_folder.joinpath(config.get('binary', name))
subprocess.run(['mv', source, BIN_DIR.joinpath(name)])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment