-
-
Save kergoth/782970 to your computer and use it in GitHub Desktop.
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 | |
# -*- coding: utf-8 -*- | |
"""Kenneth Reitz's GitHub Syncer | |
This script uses the GitHub API to get a list of all forked, mirrored, public, and | |
private repos in your GitHub account. If the repo already exists locally, it will | |
update it via git-pull. Otherwise, it will properly clone the repo. | |
It will organize your repos into the following directory structure: | |
+ repos | |
├── forks (public fork repos) | |
├── mirrors (public mirror repos) | |
├── private (private repos) | |
├── public (public repos) | |
├── watched (public watched repos) | |
└── sync.py (this script) | |
Requires Ask Solem's github2 (http://pypi.python.org/pypi/github2). | |
Inspired by Gisty (http://github.com/swdyh/gisty). | |
""" | |
import errno | |
import os | |
from commands import getoutput as cmd | |
from github2.client import Github | |
try: | |
from gistapi import Gists | |
except ImportError: | |
gist = False | |
else: | |
gist = True | |
def makedir(directory): | |
try: | |
os.makedirs(directory) | |
except OSError, exc: | |
if exc.errno != errno.EEXIST: | |
raise | |
def have(executable): | |
for path in os.environ['PATH'].split(':'): | |
if os.path.exists(os.path.join(path, executable)): | |
return True | |
return False | |
def clone(url, dest): | |
if have('git-cached-clone'): | |
cmd = 'git cached-clone' | |
else: | |
cmd = 'git clone' | |
cmd += ' %s %s' % (url, dest) | |
os.system(cmd) | |
# GitHub configurations | |
GITHUB_USER = cmd('git config github.user') | |
GITHUB_TOKEN = cmd('git config github.token') | |
# API Object | |
github = Github(username=GITHUB_USER, api_token=GITHUB_TOKEN) | |
# repo slots | |
repos = {} | |
repos['watched'] = [r for r in github.repos.watching(GITHUB_USER)] | |
repos['private'] = [] | |
repos['mirrors'] = [] | |
repos['public'] = [] | |
repos['forks'] = [] | |
# Collect GitHub repos via API | |
for repo in github.repos.list(): | |
if repo.private: | |
repos['private'].append(repo) | |
elif repo.fork: | |
repos['forks'].append(repo) | |
elif 'mirror' in repo.description.lower(): | |
# mirrors owned by self if mirror in description... | |
repos['mirrors'].append(repo) | |
else: | |
repos['public'].append(repo) | |
topdir = os.getcwd() | |
for org, repos in repos.iteritems(): | |
for repo in repos: | |
makedir(org) | |
if org == 'watched': | |
localdir = os.path.join(repo.owner, repo.name) | |
if repo.owner == GITHUB_USER: | |
# Don't clone any of my repositories into the watched area | |
continue | |
else: | |
localdir = repo.name | |
# I own the repo | |
private = org in ('private', 'fork', 'mirror') | |
# enter org dir | |
os.chdir(org) | |
# just `git pull` if it's already there | |
if os.path.exists(localdir): | |
os.chdir(localdir) | |
print('Updating repo: %s' % (localdir)) | |
os.system('git pull') | |
else: | |
print('Cloning repo: %s/%s' % (org, localdir)) | |
clone('git://github.com/%s/%s.git' % (repo.owner, repo.name), | |
localdir) | |
# return to base | |
os.chdir(topdir) | |
if gist: | |
makedir('gist') | |
for gist in Gists.fetch_by_user(GITHUB_USER): | |
destdir = os.path.join('gist', gist.repo) | |
if os.path.exists(destdir): | |
os.system('cd gist/%s && git pull' % gist.repo) | |
else: | |
clone('git://gist.github.com/%s.git' % gist.repo, | |
'gist/%s' % gist.repo) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment