ASDF Auto Updater
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
from shlex import split | |
from subprocess import CompletedProcess, run # noqa | |
from typing import cast | |
from packaging.version import InvalidVersion, parse | |
from requests import get | |
def run_cmd( | |
cmd: str, capture_output: bool = True, check: bool = True | |
) -> CompletedProcess[str]: | |
return run( | |
args=split(cmd), capture_output=capture_output, check=check, encoding="utf-8" | |
) | |
def list_plugins() -> tuple[str, ...]: | |
proc = run_cmd(cmd="asdf plugin list") | |
return tuple(proc.stdout.strip().split("\n")) | |
def list_versions(plugin_name: str) -> tuple[str, ...]: | |
proc = run_cmd(cmd=f"asdf list {plugin_name}") | |
return tuple(vers.strip("*").strip() for vers in proc.stdout.strip().split("\n")) | |
def latest_version(plugin_name: str, constraint: str | None = None) -> str: | |
cmd = f"asdf latest {plugin_name}" | |
if constraint is not None: | |
cmd = f"{cmd} {constraint}" | |
proc = run_cmd(cmd=cmd) | |
return proc.stdout.strip() | |
def latest_nodejs_lts_release() -> str | None: | |
resp = get(url="https://nodejs.org/download/release/index.json") | |
if not resp.ok: | |
print("Failed to retrieve latest NodeJS LTS release, skipping...") | |
return None | |
body = resp.json() | |
version_to_codename = {} | |
for version in body: | |
if version["lts"] is False: | |
continue | |
version_full = version["version"] | |
version_major = int(cast(str, version_full.split(".")[0]).removeprefix("v")) | |
version_codename = version["lts"] | |
if version_major not in version_to_codename: | |
version_to_codename[version_major] = version_codename | |
latest_lts_version = max(version_to_codename.keys()) | |
return str(latest_lts_version) | |
def update_version(plugin_name: str, current_version: str, target_version: str) -> None: | |
print(f"Installling {plugin_name} version: {target_version}...") | |
run_cmd(cmd=f"asdf install {plugin_name} {target_version}") | |
print(f"Setting global version of {plugin_name}: {target_version}...") | |
run_cmd(cmd=f"asdf global {plugin_name} {target_version}") | |
print(f"Removing previous version of {plugin_name}: {current_version}...") | |
run_cmd(cmd=f"asdf uninstall {plugin_name} {current_version}") | |
if plugin_name == "python": | |
print(f"{plugin_name} was updated, but is currently in use by this script") | |
print("Please reshim the langauge manually") | |
else: | |
print(f"Reshimming {plugin_name}") | |
run_cmd(cmd=f"asdf reshim {plugin_name}") | |
def main() -> None: | |
plugins = list_plugins() | |
for plugin in plugins: | |
constraint = None | |
versions = list_versions(plugin_name=plugin) | |
if len(versions) > 1: | |
print(f"{plugin} has multiple versions installed, skipping...") | |
continue | |
elif len(versions) == 0: | |
print(f"{plugin} has no versions installed, skipping...") | |
continue | |
current = versions[0] | |
if plugin == "nodejs": | |
constraint = latest_nodejs_lts_release() | |
if constraint is None: | |
continue | |
latest = latest_version(plugin_name=plugin, constraint=constraint) | |
try: | |
if parse(latest) > parse(current): | |
update_version( | |
plugin_name=plugin, target_version=latest, current_version=current | |
) | |
print(f"asdf {plugin} language upgrade complete") | |
else: | |
print(f"No asdf {plugin} langauge updates") | |
except InvalidVersion as e: | |
print(f"Updating {plugin} failed with version error") | |
print(f"* {latest=}") | |
print(f"* {current=}") | |
print(f"* {e}") | |
if __name__ == "__main__": | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment