Skip to content

Instantly share code, notes, and snippets.

@ryanwilsonperkin
Created May 17, 2020 17:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ryanwilsonperkin/11b0a6550f45621cae41821371aa668c to your computer and use it in GitHub Desktop.
Save ryanwilsonperkin/11b0a6550f45621cae41821371aa668c to your computer and use it in GitHub Desktop.
Clone all repos from an organization
#!/usr/bin/env python3
"""
clone.py
A script for downloading all of your organization's GitHub repos.
usage: GITHUB_ACCESS_TOKEN=foobar python3 clone.py <organization>
Your GITHUB_ACCESS_TOKEN is created by following the steps in this guide:
https://help.github.com/articles/creating-a-personal-access-token-for-the-command-line/
Dependencies:
pip3 install pygithub tqdm
"""
import github
import os
import subprocess
import sys
import tqdm
import multiprocessing
PROJECT_DIR = "/Users/rwilsonperkin/Projects/wave"
FNULL = open(os.devnull, 'w')
def get_repos(organization, access_token):
session = github.Github(access_token)
organization = session.get_organization(organization)
return list(organization.get_repos(type='private'))
def get_local_repos():
return os.listdir(PROJECT_DIR)
def clone_repo(repo):
subprocess.run(
['git', 'clone', repo.ssh_url],
cwd=PROJECT_DIR,
stdout=FNULL,
stderr=FNULL,
)
return repo
def filter_archived_repos(repos):
return [repo for repo in repos if not repo.archived]
def filter_existing_repos(repos):
existing = get_local_repos()
return [repo for repo in repos if repo.name not in existing]
def clone_repos(repos):
with multiprocessing.Pool(5) as pool:
pool_iterator = pool.imap_unordered(clone_repo, repos)
with tqdm.tqdm(pool_iterator, total=len(repos)) as pbar:
for repo in pbar:
pbar.write('Cloned {}'.format(repo.name))
def help():
sys.stdout.write(
'usage: GITHUB_ACCESS_TOKEN=foobar clone <organization>\n'
)
sys.exit(1)
if __name__ == "__main__":
if len(sys.argv) != 2:
help()
organization = sys.argv[1]
access_token = os.getenv('GITHUB_ACCESS_TOKEN')
if not access_token or not organization:
help()
repos = filter_archived_repos(filter_existing_repos(get_repos(organization, access_token)))
clone_repos(repos)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment