Skip to content

Instantly share code, notes, and snippets.

@birgersp
Last active April 17, 2024 08:43
Show Gist options
  • Save birgersp/c616e940132b39d847e5a8dd29ddfbda to your computer and use it in GitHub Desktop.
Save birgersp/c616e940132b39d847e5a8dd29ddfbda to your computer and use it in GitHub Desktop.
Mirror your Github repos
from os import getenv, makedirs, rename
from shutil import rmtree
import subprocess
from dotenv import load_dotenv
import requests
from typing import List
from pathlib import Path
from os.path import join
def get_github_repos(token: str) -> List[str]:
headers = {
'Authorization': f'token {token}',
'Accept': 'application/vnd.github.v3+json',
}
repos_url = 'https://api.github.com/user/repos'
response = requests.get(repos_url, headers=headers)
response.raise_for_status()
repos = response.json()
ssh_urls = [repo['ssh_url'] for repo in repos]
return ssh_urls
def execute(cmd: str, cwd: str = "."):
print(f"{cwd} {cmd}")
process = subprocess.run(cmd, shell=True, cwd=cwd)
if process.returncode != 0:
raise Exception("Command did not succeed")
def tryremove(path: str):
try:
rmtree(path)
except Exception as e:
print(e)
pass
if __name__ == '__main__':
load_dotenv()
GITHUB_TOKEN = getenv("GITHUB_TOKEN")
if GITHUB_TOKEN is None:
raise Exception('No Github token was supplied (hint: set ENV variable "GITHUB_TOKEN")')
script_path = Path(__file__).absolute()
script_dir = str(script_path.parent)
temp_dir = join(script_dir, ".tempdir")
dest_dir = join(script_dir, "mirrored-repos")
ssh_urls = get_github_repos(GITHUB_TOKEN)
tryremove(temp_dir)
makedirs(temp_dir, exist_ok=True)
for url in ssh_urls:
command = f"git clone --mirror {url}"
process = subprocess.run(command, shell=True, cwd=temp_dir)
if process.returncode != 0:
raise Exception(f"Command did not succeed: {command}")
tryremove(dest_dir)
rename(temp_dir, dest_dir)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment