Advertisement
Guest User

Untitled

a guest
Mar 2nd, 2019
172
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.77 KB | None | 0 0
  1. """This module provides tools to clone github repos. The GithubOrgCloner
  2. can clone an entire org worth of codebases and create a local corpus of projects.
  3. """
  4.  
  5. import git
  6. import shutil
  7. import traceback
  8. import urllib.parse
  9. from argparse import ArgumentParser
  10. from functools import partial
  11. from getpass import getpass
  12. from github import Github
  13. from os import environ, makedirs, path
  14. from subprocess import call
  15.  
  16.  
  17. class GithubOrgCloner:
  18. def get_parser(self):
  19. """ Create parser for command line arguments """
  20. parser = ArgumentParser(
  21. usage=u'python archex/github.py -u\'\n\t\t\tUsername and password will be prompted.',
  22. description='Clone all your Github repositories.')
  23. parser.add_argument('-u', '--user', help='Your github username')
  24. parser.add_argument('-p', '--password', help=u'Github password')
  25. parser.add_argument('-t', '--token', help=u'Github OAuth token')
  26. parser.add_argument(
  27. '-o', '--org', help=u'Organisation/team. User used by default.')
  28. parser.add_argument(
  29. '-d', '--dest', help=u'Destination directory. Created if doesn\'t exist. [curr_dir]')
  30. parser.add_argument('--nopull', action='store_true',
  31. help=u'Don\'t pull if repository exists. [false]')
  32. parser.add_argument('--shallow', action='store_true',
  33. help=u'Perform shallow clone. [false]')
  34. parser.add_argument('--ssh', action='store_true',
  35. help=u'Use ssh+git urls for checkout. [false]')
  36. return parser
  37.  
  38. def get_github_client(self, args):
  39. """ Create github agent to auth """
  40. if args.token:
  41. g = Github(args.token)
  42. else:
  43. user = args.user
  44. password = args.password
  45. if not user:
  46. user = input(u'Username: ')
  47. if not password:
  48. password = getpass('Password: ')
  49. if not args.dest:
  50. args.dest = input(u'Destination: ')
  51. g = Github(user, password)
  52. return g
  53.  
  54. def clone_org(self):
  55. """ Clone all repos """
  56. print("Cloning all repos from an org.")
  57. parser = self.get_parser()
  58. args = parser.parse_args()
  59. g = self.get_github_client(args)
  60. user = g.get_user().login
  61. # (BadCredentialsException, TwoFactorException, RateLimitExceededException)
  62.  
  63. join = path.join
  64. if args.dest:
  65. if not path.exists(args.dest):
  66. makedirs(args.dest)
  67. print(u'mkdir -p "{}"'.format(args.dest))
  68. join = partial(path.join, args.dest)
  69.  
  70. get_repos = g.get_organization(
  71. args.org).get_repos if args.org else g.get_user().get_repos
  72. for repo in get_repos():
  73. if not path.exists(join(repo.name)):
  74. clone_url = repo.clone_url
  75. if args.ssh:
  76. clone_url = repo.ssh_url
  77. if args.shallow:
  78. print(
  79. u'Shallow cloning "{repo.full_name}"'.format(repo=repo))
  80. call([u'git', u'clone', '--depth=1',
  81. clone_url, join(repo.name)])
  82. else:
  83. print(
  84. u'Cloning "{repo.full_name}"'.format(repo=repo))
  85. call([u'git', u'clone', clone_url, join(repo.name)])
  86. elif not args.nopull:
  87. print(u'Updating "{repo.name}"'.format(repo=repo))
  88. call([u'git', u'pull'], env=dict(
  89. environ, GIT_DIR=join(repo.name, '.git').encode('utf8')))
  90. else:
  91. print(
  92. u'Already cloned, skipping...\t"{repo.name}"'.format(repo=repo))
  93. print(u'FIN')
  94.  
  95.  
  96. if __name__ == '__main__':
  97. GithubOrgCloner().clone_org()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement