From 348bbc40f63e1672595ec2785b1c7e3893c14b25 Mon Sep 17 00:00:00 2001 From: Chris Lockfort Date: Mon, 24 Oct 2011 16:04:33 -0400 Subject: [PATCH 1/9] fixed a hardcoding mistake and accomodate for https --- github-backup.pl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/github-backup.pl b/github-backup.pl index 567035c..4cffd0d 100755 --- a/github-backup.pl +++ b/github-backup.pl @@ -12,7 +12,7 @@ die "Could not complete github API query for $username\n" unless defined $page; my @list = split(/\n/, $page); my @urls = grep { /url/ } @list; -my @giturls = grep s/ :url: http/git/, @urls; +my @giturls = grep s/ :url: https/git/, @urls; @urls = @giturls; my @reponames = grep s/.*$username\///, @giturls; @@ -24,7 +24,7 @@ for(my $i = 0; $i < @urls; ++$i){ } unless(-e "$backupdir/$name"){ #We haven't backed this up before, let's clone it print "CLONING REPOSITORY: $url\n"; - system("cd backups && git clone $url") and die "Encountered an error while git-cloning repository $name\n"; + system("cd $backupdir && git clone $url") and die "Encountered an error while git-cloning repository $name\n"; } else{ #We've backed it up before, just fetch the most recent copy print "REPOSITORY EXISTED, FETCHING: $name\n"; From 8781e10f1a9ce7dad627faf02190cacf2ea27c2d Mon Sep 17 00:00:00 2001 From: Anthony Gargiulo Date: Sat, 16 Jun 2012 02:24:45 -0400 Subject: [PATCH 2/9] Initial commit of this file. Not much done here yet though --- github-backup.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100755 github-backup.py diff --git a/github-backup.py b/github-backup.py new file mode 100755 index 0000000..f6a600f --- /dev/null +++ b/github-backup.py @@ -0,0 +1,12 @@ +#!/usr/bin/env python3 + +# Author: Anthony Gargiulo (anthony@agargiulo.com) +# Created Fri Jun 15 2012 + +from pygithub3 import Github +from argparse import ArgumentParser + +parser = ArgumentParser(description="makes a local backup copy of all of a github user's repositories") +args = parser.parse_args() + +gh = Github() From a248ae726d97254cf838de83523298f5f5495a24 Mon Sep 17 00:00:00 2001 From: Anthony Gargiulo Date: Mon, 18 Jun 2012 01:15:54 -0400 Subject: [PATCH 3/9] Works with new repos. Still need to make it update existing repos. As of right now, it will just fail because git will fail to clone into a non-empty directory. --- github-backup.py | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/github-backup.py b/github-backup.py index f6a600f..cc1308a 100755 --- a/github-backup.py +++ b/github-backup.py @@ -1,12 +1,26 @@ -#!/usr/bin/env python3 +#!/usr/bin/env python # Author: Anthony Gargiulo (anthony@agargiulo.com) # Created Fri Jun 15 2012 from pygithub3 import Github from argparse import ArgumentParser +import os +# A sane way to handle command line args. parser = ArgumentParser(description="makes a local backup copy 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", default="./backups") +parser.add_argument("-v","--verbose", help="Produces more output", action="store_true") + +# Now actually store the args args = parser.parse_args() +# Make the connection to Github here. gh = Github() + +# Get all of the given user's repos +user_repos = gh.repos.list(args.username).all() +print user_repos[0].__dict__ +for repo in user_repos: + os.system('git clone {} {}/{}'.format(repo.git_url, args.backupdir, repo.name)) From 7a874e281dca202b663fbec199fe3ddddc8bae35 Mon Sep 17 00:00:00 2001 From: Anthony Gargiulo Date: Mon, 18 Jun 2012 18:18:54 -0400 Subject: [PATCH 4/9] moved the code into a main method because it's more sane. --- github-backup.py | 35 ++++++++++++++++++++--------------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/github-backup.py b/github-backup.py index cc1308a..abd6c3d 100755 --- a/github-backup.py +++ b/github-backup.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # Author: Anthony Gargiulo (anthony@agargiulo.com) # Created Fri Jun 15 2012 @@ -7,20 +7,25 @@ from pygithub3 import Github from argparse import ArgumentParser import os -# A sane way to handle command line args. -parser = ArgumentParser(description="makes a local backup copy 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", default="./backups") -parser.add_argument("-v","--verbose", help="Produces more output", action="store_true") +def main(): + # A sane way to handle command line args. + parser = ArgumentParser(description="makes a local backup copy 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", default="./backups") + parser.add_argument("-v","--verbose", help="Produces more output", action="store_true") -# Now actually store the args -args = parser.parse_args() + # Now actually store the args + args = parser.parse_args() -# Make the connection to Github here. -gh = Github() + # Make the connection to Github here. + gh = Github() -# Get all of the given user's repos -user_repos = gh.repos.list(args.username).all() -print user_repos[0].__dict__ -for repo in user_repos: - os.system('git clone {} {}/{}'.format(repo.git_url, args.backupdir, repo.name)) + # Get all of the given user's repos + user_repos = gh.repos.list(args.username).all() + #print user_repos[0].__dict__ + for repo in user_repos: + os.system('git clone {} {}/{}'.format(repo.git_url, args.backupdir, repo.name)) + +if __name__ == "__main__": + main() + print("foobar") From 0330e39d96ffbfa765553b6d335f83330d6c2965 Mon Sep 17 00:00:00 2001 From: Anthony Gargiulo Date: Sat, 23 Jun 2012 13:24:48 -0400 Subject: [PATCH 5/9] This file is made obsolete by github-backup.py. --- github-backup.pl | 33 --------------------------------- 1 file changed, 33 deletions(-) delete mode 100755 github-backup.pl diff --git a/github-backup.pl b/github-backup.pl deleted file mode 100755 index 4cffd0d..0000000 --- a/github-backup.pl +++ /dev/null @@ -1,33 +0,0 @@ -#!/usr/bin/perl -use strict; -use warnings; -use LWP::Simple; - -die "Please supply a github username and backups directory\n" unless (@ARGV == 2); - -my $username = $ARGV[0]; -my $backupdir = $ARGV[1]; -my $page = get("http://github.com/api/v2/yaml/repos/show/$username"); -die "Could not complete github API query for $username\n" unless defined $page; - -my @list = split(/\n/, $page); -my @urls = grep { /url/ } @list; -my @giturls = grep s/ :url: https/git/, @urls; -@urls = @giturls; -my @reponames = grep s/.*$username\///, @giturls; - -for(my $i = 0; $i < @urls; ++$i){ - my $url = $urls[$i]; - my $name = $reponames[$i]; - unless(-e $backupdir){ - system("mkdir $backupdir") and die "Couldn't make $backupdir.\n"; - } - unless(-e "$backupdir/$name"){ #We haven't backed this up before, let's clone it - print "CLONING REPOSITORY: $url\n"; - system("cd $backupdir && git clone $url") and die "Encountered an error while git-cloning repository $name\n"; - } - else{ #We've backed it up before, just fetch the most recent copy - print "REPOSITORY EXISTED, FETCHING: $name\n"; - system("cd $backupdir/$name && git fetch -q") and die "Encountered an error while git-fetching repository $name\n"; - } -} From 762aa093e0daee0fa0ba3099a4d064521ad2cf3b Mon Sep 17 00:00:00 2001 From: Anthony Gargiulo Date: Sat, 23 Jun 2012 14:59:50 -0400 Subject: [PATCH 6/9] Switching back to python 2.x for now --- github-backup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/github-backup.py b/github-backup.py index abd6c3d..a7a2763 100755 --- a/github-backup.py +++ b/github-backup.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python3 +#!/usr/bin/env python # Author: Anthony Gargiulo (anthony@agargiulo.com) # Created Fri Jun 15 2012 From 8a2c44245e10cfc595ceb2d742373bc6678a34ec Mon Sep 17 00:00:00 2001 From: Anthony Gargiulo Date: Sat, 23 Jun 2012 15:48:44 -0400 Subject: [PATCH 7/9] moved the setup of the parser to a function --- github-backup.py | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/github-backup.py b/github-backup.py index a7a2763..bf16258 100755 --- a/github-backup.py +++ b/github-backup.py @@ -9,12 +9,8 @@ import os def main(): # A sane way to handle command line args. - parser = ArgumentParser(description="makes a local backup copy 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", default="./backups") - parser.add_argument("-v","--verbose", help="Produces more output", action="store_true") - # Now actually store the args + parser = init_parser() args = parser.parse_args() # Make the connection to Github here. @@ -22,10 +18,23 @@ def main(): # Get all of the given user's repos user_repos = gh.repos.list(args.username).all() - #print user_repos[0].__dict__ for repo in user_repos: - os.system('git clone {} {}/{}'.format(repo.git_url, args.backupdir, repo.name)) + process_repo(repo, args) + +def init_parser(): + """ + set up the argument parser + """ + 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") + return parser + + if __name__ == "__main__": main() - print("foobar") From 03e3982ef3f754edc5ec46107d76cf0c5dfe41dd Mon Sep 17 00:00:00 2001 From: Anthony Gargiulo Date: Sat, 23 Jun 2012 15:49:34 -0400 Subject: [PATCH 8/9] the process_repo function works --- github-backup.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/github-backup.py b/github-backup.py index bf16258..53a9c87 100755 --- a/github-backup.py +++ b/github-backup.py @@ -35,6 +35,21 @@ def init_parser(): return parser +def process_repo(repo, args): + if args.cron: + git_args = "-q" + else: + git_args = "" + + if not args.cron: + print("Processing repo: {}".format(repo.full_name)) + + if os.access('{}/{}/.git'.format(args.backupdir,repo.name),os.F_OK): + if not args.cron: + print("Repo already exists, let's try to update it instead") + os.system('cd {}/{};git pull {}'.format(args.backupdir, repo.name, git_args)) + else: # Repo doesn't exist, let's clone it + os.system('git clone {} {} {}/{}'.format(git_args, repo.git_url, args.backupdir, repo.name)) if __name__ == "__main__": main() From 0aeee6d91b2256e6fa887267742ca1466ce0e1eb Mon Sep 17 00:00:00 2001 From: Anthony Gargiulo Date: Sat, 23 Jun 2012 16:58:55 -0400 Subject: [PATCH 9/9] updated the README --- README.markdown | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.markdown b/README.markdown index 188d59f..3137ef2 100644 --- a/README.markdown +++ b/README.markdown @@ -1,13 +1,14 @@ GitHub-Backup ============= -By Chris Lockfort (devnull@csh.rit.edu) (Github username: Clockfort) +Idea By Chris Lockfort (devnull@csh.rit.edu) (Github username: Clockfort) +Python version By Anthony Gargiulo (anthony@agargiulo.com) (Github username: agargiulo) GitHub-Backup makes a local backup copy of all of a github user's (or github organization's) repositories. Usage ----- -"./github-backup.pl USERNAME BACKUP_DIRECTORY" +"./github-backup.py USERNAME BACKUPDIR [-c|--cron] [-h|--help]" Then, put it in a cron job somewhere and forget about it for eternity.