install_extras.py 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. #!/usr/bin/env python3
  2. from __future__ import annotations
  3. import os
  4. import pathlib
  5. import platform
  6. import subprocess
  7. import tarfile
  8. import httpx
  9. CURRENT_DIR = pathlib.Path(__file__).parent
  10. def main():
  11. delta()
  12. eza()
  13. git_whence()
  14. starship()
  15. def delta():
  16. if platform.system() == 'Darwin':
  17. print('$ brew install git-delta')
  18. subprocess.run(['brew', 'install', 'git-delta'], check=True)
  19. return
  20. else:
  21. assert platform.system() == 'Linux'
  22. if subprocess.run(['dpkg', '-l', 'git-delta'], stdout=subprocess.DEVNULL).returncode == 0:
  23. print('git-delta package already installed')
  24. return
  25. client = httpx.Client()
  26. latest = gh_latest_version(client, 'dandavison', 'delta')
  27. version = latest['name']
  28. arch = get_output(['dpkg', '--print-architecture'])
  29. filename = f'git-delta_{version}_{arch}.deb'
  30. (asset,) = (asset for asset in latest['assets'] if asset['name'] == filename)
  31. deb_path = CURRENT_DIR / 'git-delta.deb'
  32. download(client, asset['browser_download_url'], deb_path)
  33. try:
  34. subprocess.run(['sudo', 'dpkg', '-i', deb_path], check=True)
  35. finally:
  36. os.unlink(deb_path)
  37. def eza():
  38. if platform.system() == 'Darwin':
  39. print('$ brew install eza')
  40. subprocess.run(['brew', 'install', 'eza'], check=True)
  41. return
  42. else:
  43. assert platform.system() == 'Linux'
  44. if (CURRENT_DIR / 'eza').exists():
  45. print('eza already downloaded')
  46. return
  47. client = httpx.Client()
  48. url = f'https://github.com/eza-community/eza/releases/latest/download/eza_{platform.machine()}-unknown-linux-gnu.tar.gz'
  49. tarball_path = CURRENT_DIR / 'eza.tar.gz'
  50. download(client, url, tarball_path)
  51. with tarfile.open(tarball_path) as tar:
  52. tar.extract('./eza', CURRENT_DIR)
  53. tarball_path.unlink()
  54. def git_whence():
  55. if platform.system() == 'Darwin':
  56. print('$ brew install raylu/formulae/git-whence')
  57. subprocess.run(['brew', 'install', 'raylu/formulae/git-whence'], check=True)
  58. return
  59. else:
  60. assert platform.system() == 'Linux'
  61. if (CURRENT_DIR / 'git-whence').exists():
  62. print('git-whence already downloaded')
  63. return
  64. client = httpx.Client()
  65. url = f'https://github.com/raylu/git-whence/releases/latest/download/git-whence-{platform.machine()}-unknown-linux-gnu'
  66. download(client, url, CURRENT_DIR / 'git-whence')
  67. os.chmod(CURRENT_DIR / 'git-whence', 0o755)
  68. def starship():
  69. if platform.system() == 'Darwin':
  70. print('$ brew install starship')
  71. subprocess.run(['brew', 'install', 'starship'], check=True)
  72. return
  73. else:
  74. assert platform.system() == 'Linux'
  75. if (CURRENT_DIR / 'starship').exists():
  76. print('starship already downloaded')
  77. return
  78. client = httpx.Client()
  79. url = f'https://github.com/starship/starship/releases/latest/download/starship-{platform.machine()}-unknown-linux-gnu.tar.gz'
  80. tarball_path = CURRENT_DIR / 'starship.tar.gz'
  81. download(client, url, tarball_path)
  82. with tarfile.open(tarball_path, 'r:gz') as tar:
  83. tar.extract('starship', CURRENT_DIR)
  84. tarball_path.unlink()
  85. def get_output(argv: list[str]) -> str:
  86. proc = subprocess.run(argv, check=True, capture_output=True, encoding='ascii')
  87. return proc.stdout.rstrip('\n')
  88. def gh_latest_version(client: httpx.Client, org: str, repo: str) -> dict:
  89. r = client.get(f'https://api.github.com/repos/{org}/{repo}/releases/latest',
  90. headers={'Accept': 'application/vnd.github+json', 'X-GitHub-Api-Version': '2022-11-28'})
  91. r.raise_for_status()
  92. return r.json()
  93. def download(client: httpx.Client, url: str, path: pathlib.Path) -> None:
  94. print('downloading', url, 'to', path)
  95. with client.stream('GET', url, follow_redirects=True) as r:
  96. r.raise_for_status()
  97. with path.open('wb') as f:
  98. for chunk in r.iter_bytes():
  99. f.write(chunk)
  100. if __name__ == '__main__':
  101. main()