Skip to content

Instantly share code, notes, and snippets.

@lostfictions
Last active September 7, 2024 03:11
Show Gist options
  • Save lostfictions/2341c97428055bad271db22b02fde71a to your computer and use it in GitHub Desktop.
Save lostfictions/2341c97428055bad271db22b02fde71a to your computer and use it in GitHub Desktop.
show current and new version for flatpak apps with updates
#!/usr/bin/env python3
import asyncio
# boilerplate for asyncio
async def run(cmd: str) -> str:
proc = await asyncio.create_subprocess_shell(
cmd,
stdout=asyncio.subprocess.PIPE,
stderr=asyncio.subprocess.PIPE,
)
stdout, stderr = await proc.communicate()
if proc.returncode != 0:
raise RuntimeError(f"Command failed: {' '.join(cmd)}\n{stderr.decode()}")
return stdout.decode()
async def get_updates() -> list[tuple[str, str, str]]:
# `flatpak remote-ls --updates` can include a `version` column, but the
# version it shows is actually the installed version instead of the new one!
# what's more, requesting the version column is far slower than fetching only
# the updated app ids and using `flatpak list` later to get the local versions.
masked_apps, updatable_apps = await asyncio.gather(
run("flatpak mask"),
run("flatpak remote-ls --updates --app --columns=application"),
)
masked = {line.strip() for line in masked_apps.splitlines()}
updates = {row for row in updatable_apps.splitlines() if not row in masked}
if not updates:
return []
# if there are unmasked updates, check the actual remote versions via another
# invocation of `flatpak remote-ls` (without `--update`)
remote_apps, local_apps = await asyncio.gather(
run("flatpak remote-ls --app --columns=application,version"),
run("flatpak list --app --columns=application,version"),
)
current_versions = dict(row.split("\t") for row in local_apps.splitlines())
# not all remote apps include a version column, so we can't unpack immediately
return [
(id_and_ver[0], current_versions[id_and_ver[0]], id_and_ver[1])
for row in remote_apps.splitlines()
if (id_and_ver := row.split("\t"))[0] in updates
]
async def main() -> None:
print("Looking up Flatpak app version update info...\n")
updates = await get_updates()
if updates:
id_pad = 12
version_pad = 12
for id, old, new in updates:
id_pad = max(id_pad, len(id))
version_pad = max(version_pad, len(old), len(new))
print(
f"{'Application ID':<{id_pad}} {'Old Version':<{version_pad}} {'New Version':<{version_pad}}"
)
for id, old, new in updates:
print(f"{id:<{id_pad}} {old:<{version_pad}} {new:<{version_pad}}")
if __name__ == "__main__":
asyncio.run(main())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment