From 6a092ffdf97433ee9e44dde2f6a81f07caee5442 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Tue, 27 Aug 2013 13:33:41 +0200 Subject: [PATCH 1/4] bugfix: do not alter objects, as these changes are global --- github-backup.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/github-backup.py b/github-backup.py index 4351438..f9edc71 100755 --- a/github-backup.py +++ b/github-backup.py @@ -65,9 +65,11 @@ def process_repo(repo, args): def clone_repo(repo, dir, args): if args.mirror: - args.git += " --mirror" + options = args.git + " --mirror" + else: + options = args.git - os.system('git clone %s %s %s'%(args.git, repo.git_url, dir)) + os.system('git clone %s %s %s'%(options, repo.git_url, dir)) def update_repo(repo, dir, args): @@ -76,8 +78,7 @@ def update_repo(repo, dir, args): # GitHub => Local if args.mirror: - args.git += " --prune" - os.system("git fetch %s"%(args.git,)) + os.system("git fetch %s"%(args.git + " --prune",)) else: os.system("git pull %s"%(args.git,)) From 0014d6a4a32b0c3ab4e5252509413b8d5ec76277 Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Tue, 27 Aug 2013 15:17:50 +0200 Subject: [PATCH 2/4] adding github repo details to repo config (useful for gitweb, cgit, etc..) --- github-backup.py | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/github-backup.py b/github-backup.py index f9edc71..fa8eff0 100755 --- a/github-backup.py +++ b/github-backup.py @@ -26,6 +26,7 @@ def main(): # Get all of the given user's repos user_repos = gh.repos.list(args.username).all() for repo in user_repos: + repo.user = gh.users.get(repo.owner.login) process_repo(repo, args) @@ -45,7 +46,6 @@ def init_parser(): return parser - def process_repo(repo, args): if not args.cron: print("Processing repo: %s"%(repo.full_name)) @@ -53,14 +53,15 @@ def process_repo(repo, args): dir = "%s/%s"%(args.backupdir, repo.name + args.suffix) config = "%s/%s"%(dir, "config" if args.mirror else ".git/config") - if os.access(config, os.F_OK): - if not args.cron: - print("Repo already exists, let's try to update it instead") - update_repo(repo, dir, args) - else: + if not os.access(config, os.F_OK): if not args.cron: print("Repo doesn't exists, lets clone it") clone_repo(repo, dir, args) + else: + if not args.cron: + print("Repo already exists, let's try to update it instead") + + update_repo(repo, dir, args) def clone_repo(repo, dir, args): @@ -82,7 +83,18 @@ def update_repo(repo, dir, args): else: os.system("git pull %s"%(args.git,)) + # Fetch description and owner (useful for gitweb, cgit etc.) + os.system("git config --local gitweb.description %s"%(shell_escape(repo.description),)) + os.system("git config --local gitweb.owner %s"%(shell_escape("%s <%s>"%(repo.user.name, repo.user.email.encode("utf-8"))),)) + + os.system("git config --local cgit.name %s"%(shell_escape(repo.name),)) + os.system("git config --local cgit.defbranch %s"%(shell_escape(repo.master_branch),)) + os.system("git config --local cgit.clone-url %s"%(shell_escape(repo.clone_url),)) + os.chdir(savedPath) +def shell_escape(str): + return "'" + unicode(str.replace("'", "\\'")).encode("utf-8") + "'" + if __name__ == "__main__": main() From a3507dcfe69967b94fefc1309ede598907f188db Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Tue, 27 Aug 2013 15:26:18 +0200 Subject: [PATCH 3/4] added password authentification in case you're getting rate limited --- github-backup.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/github-backup.py b/github-backup.py index fa8eff0..088a05d 100755 --- a/github-backup.py +++ b/github-backup.py @@ -21,10 +21,16 @@ def main(): args.git += "--quiet" # Make the connection to Github here. - gh = Github() + config = { 'user': args.username } + + if (args.password): + config['password'] = args.password + config['login'] = args.username + + gh = Github(**config) # Get all of the given user's repos - user_repos = gh.repos.list(args.username).all() + user_repos = gh.repos.list().all() for repo in user_repos: repo.user = gh.users.get(repo.owner.login) process_repo(repo, args) @@ -43,6 +49,7 @@ def init_parser(): parser.add_argument("-m","--mirror", help="Create a bare mirror", action="store_true") parser.add_argument("-g","--git", help="Pass extra arguments to git", default="", metavar="ARGS") parser.add_argument("-s", "--suffix", help="Add suffix to repository directory names", default="") + parser.add_argument("-p", "--password", help="Authenticate with Github API") return parser From 5aef303f2616ebbc97d84d463a6fca9a71b5e4ed Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Tue, 27 Aug 2013 15:30:42 +0200 Subject: [PATCH 4/4] code cleanup: fixed indentions added comments --- github-backup.py | 122 +++++++++++++++++++++++------------------------ 1 file changed, 61 insertions(+), 61 deletions(-) diff --git a/github-backup.py b/github-backup.py index 088a05d..ae95f33 100755 --- a/github-backup.py +++ b/github-backup.py @@ -13,95 +13,95 @@ import os def main(): - parser = init_parser() - args = parser.parse_args() + parser = init_parser() + args = parser.parse_args() - # Process args - if args.cron: - args.git += "--quiet" + # Process args + if args.cron: + args.git += "--quiet" - # Make the connection to Github here. - config = { 'user': args.username } + # Make the connection to Github here. + config = { 'user': args.username } - if (args.password): - config['password'] = args.password - config['login'] = args.username + if (args.password): + config['password'] = args.password + config['login'] = args.username - gh = Github(**config) + gh = Github(**config) - # Get all of the given user's repos - user_repos = gh.repos.list().all() - for repo in user_repos: - repo.user = gh.users.get(repo.owner.login) - process_repo(repo, args) + # Get all of the given user's repos + user_repos = gh.repos.list().all() + for repo in user_repos: + repo.user = gh.users.get(repo.owner.login) + process_repo(repo, args) def init_parser(): - """ - set up the argument parser - """ + """ + set up the argument parser + """ - parser = ArgumentParser(description="makes a backup of all of a github user's repositories") + parser = ArgumentParser(description="makes a backup of all of a github user's repositories") - parser.add_argument("username", help="A Github username") - parser.add_argument("backupdir", help="The folder where you want your backups to go") - parser.add_argument("-c","--cron", help="Use this when running from a cron job", action="store_true") - parser.add_argument("-m","--mirror", help="Create a bare mirror", action="store_true") - parser.add_argument("-g","--git", help="Pass extra arguments to git", default="", metavar="ARGS") - parser.add_argument("-s", "--suffix", help="Add suffix to repository directory names", default="") - parser.add_argument("-p", "--password", help="Authenticate with Github API") + parser.add_argument("username", help="A Github username") + parser.add_argument("backupdir", help="The folder where you want your backups to go") + parser.add_argument("-c","--cron", help="Use this when running from a cron job", action="store_true") + parser.add_argument("-m","--mirror", help="Create a bare mirror", action="store_true") + parser.add_argument("-g","--git", help="Pass extra arguments to git", default="", metavar="ARGS") + parser.add_argument("-s", "--suffix", help="Add suffix to repository directory names", default="") + parser.add_argument("-p", "--password", help="Authenticate with Github API") - return parser + return parser def process_repo(repo, args): - if not args.cron: - print("Processing repo: %s"%(repo.full_name)) + if not args.cron: + print("Processing repo: %s"%(repo.full_name)) - dir = "%s/%s"%(args.backupdir, repo.name + args.suffix) - config = "%s/%s"%(dir, "config" if args.mirror else ".git/config") + dir = "%s/%s"%(args.backupdir, repo.name + args.suffix) + config = "%s/%s"%(dir, "config" if args.mirror else ".git/config") - if not os.access(config, os.F_OK): - if not args.cron: - print("Repo doesn't exists, lets clone it") - clone_repo(repo, dir, args) - else: - if not args.cron: - print("Repo already exists, let's try to update it instead") + if not os.access(config, os.F_OK): + if not args.cron: print("Repo doesn't exists, lets clone it") + clone_repo(repo, dir, args) + else: + if not args.cron: print("Repo already exists, let's try to update it instead") - update_repo(repo, dir, args) + update_repo(repo, dir, args) def clone_repo(repo, dir, args): - if args.mirror: - options = args.git + " --mirror" - else: - options = args.git + if args.mirror: + options = args.git + " --mirror" + else: + options = args.git - os.system('git clone %s %s %s'%(options, repo.git_url, dir)) + os.system('git clone %s %s %s'%(options, repo.git_url, dir)) def update_repo(repo, dir, args): - savedPath = os.getcwd() - os.chdir(dir) + savedPath = os.getcwd() + os.chdir(dir) - # GitHub => Local - if args.mirror: - os.system("git fetch %s"%(args.git + " --prune",)) - else: - os.system("git pull %s"%(args.git,)) + # GitHub => Local + # TODO: use subprocess package and fork git into background (major performance boost expected) + if args.mirror: + os.system("git fetch %s"%(args.git + " --prune",)) + else: + os.system("git pull %s"%(args.git,)) - # Fetch description and owner (useful for gitweb, cgit etc.) - os.system("git config --local gitweb.description %s"%(shell_escape(repo.description),)) - os.system("git config --local gitweb.owner %s"%(shell_escape("%s <%s>"%(repo.user.name, repo.user.email.encode("utf-8"))),)) + # Fetch description and owner (useful for gitweb, cgit etc.) + # TODO: can we combine that in a single call to 'git config' + os.system("git config --local gitweb.description %s"%(shell_escape(repo.description),)) + os.system("git config --local gitweb.owner %s"%(shell_escape("%s <%s>"%(repo.user.name, repo.user.email.encode("utf-8"))),)) - os.system("git config --local cgit.name %s"%(shell_escape(repo.name),)) - os.system("git config --local cgit.defbranch %s"%(shell_escape(repo.master_branch),)) - os.system("git config --local cgit.clone-url %s"%(shell_escape(repo.clone_url),)) + os.system("git config --local cgit.name %s"%(shell_escape(repo.name),)) + os.system("git config --local cgit.defbranch %s"%(shell_escape(repo.master_branch),)) + os.system("git config --local cgit.clone-url %s"%(shell_escape(repo.clone_url),)) - os.chdir(savedPath) + os.chdir(savedPath) def shell_escape(str): - return "'" + unicode(str.replace("'", "\\'")).encode("utf-8") + "'" + return "'" + unicode(str.replace("'", "\\'")).encode("utf-8") + "'" if __name__ == "__main__": - main() + main()