A console script that allows you to easily update multiple git repositories at once
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

209 lines
5.6 KiB

  1. # -*- coding: utf-8 -*-
  2. #
  3. # Copyright (C) 2011-2018 Ben Kurtovic <ben.kurtovic@gmail.com>
  4. # Released under the terms of the MIT License. See LICENSE for details.
  5. import argparse
  6. import os
  7. import platform
  8. from colorama import init as color_init, Style
  9. from gitup import __version__
  10. from gitup.config import (
  11. get_default_config_path,
  12. get_bookmarks,
  13. add_bookmarks,
  14. delete_bookmarks,
  15. list_bookmarks,
  16. clean_bookmarks,
  17. )
  18. from gitup.update import update_bookmarks, update_directories, run_command
  19. def _build_parser():
  20. """Build and return the argument parser."""
  21. parser = argparse.ArgumentParser(
  22. description="Easily update multiple git repositories at once.",
  23. epilog="""
  24. Both relative and absolute paths are accepted by all arguments.
  25. Direct bug reports and feature requests to
  26. https://github.com/earwig/git-repo-updater.""",
  27. add_help=False,
  28. )
  29. group_u = parser.add_argument_group("updating repositories")
  30. group_b = parser.add_argument_group("bookmarking")
  31. group_a = parser.add_argument_group("advanced")
  32. group_m = parser.add_argument_group("miscellaneous")
  33. group_u.add_argument(
  34. "directories_to_update",
  35. nargs="*",
  36. metavar="path",
  37. help="""update this repository, or all repositories it contains
  38. (if not a repo directly)""",
  39. )
  40. group_u.add_argument(
  41. "-u",
  42. "--update",
  43. action="store_true",
  44. help="""update all bookmarks
  45. (default behavior when called without arguments)""",
  46. )
  47. group_u.add_argument(
  48. "-t",
  49. "--depth",
  50. dest="max_depth",
  51. metavar="n",
  52. type=int,
  53. default=3,
  54. help="""max recursion depth when searching for repos in subdirectories
  55. (default: 3; use 0 for no recursion, or -1 for unlimited)""",
  56. )
  57. group_u.add_argument(
  58. "-c",
  59. "--current-only",
  60. action="store_true",
  61. help="""only fetch the
  62. remote tracked by the current branch instead of all remotes""",
  63. )
  64. group_u.add_argument(
  65. "-f",
  66. "--fetch-only",
  67. action="store_true",
  68. help="only fetch remotes, don't try to fast-forward any branches",
  69. )
  70. group_u.add_argument(
  71. "-p",
  72. "--prune",
  73. action="store_true",
  74. help="""after fetching, delete
  75. remote-tracking branches that no longer exist on their remote""",
  76. )
  77. group_b.add_argument(
  78. "-a",
  79. "--add",
  80. dest="bookmarks_to_add",
  81. nargs="+",
  82. metavar="path",
  83. help="add directory(s) as bookmarks",
  84. )
  85. group_b.add_argument(
  86. "-d",
  87. "--delete",
  88. dest="bookmarks_to_del",
  89. nargs="+",
  90. metavar="path",
  91. help="delete bookmark(s) (leaves actual directories alone)",
  92. )
  93. group_b.add_argument(
  94. "-l",
  95. "--list",
  96. dest="list_bookmarks",
  97. action="store_true",
  98. help="list current bookmarks",
  99. )
  100. group_b.add_argument(
  101. "-n",
  102. "--clean",
  103. "--cleanup",
  104. dest="clean_bookmarks",
  105. action="store_true",
  106. help="delete any bookmarks that don't exist",
  107. )
  108. group_b.add_argument(
  109. "-b",
  110. "--bookmark-file",
  111. nargs="?",
  112. metavar="path",
  113. help="use a specific bookmark config file (default: {0})".format(
  114. get_default_config_path()
  115. ),
  116. )
  117. group_a.add_argument(
  118. "-e",
  119. "--exec",
  120. "--batch",
  121. dest="command",
  122. metavar="command",
  123. help="run a shell command on all repos",
  124. )
  125. group_m.add_argument(
  126. "-h", "--help", action="help", help="show this help message and exit"
  127. )
  128. group_m.add_argument(
  129. "-v",
  130. "--version",
  131. action="version",
  132. version="gitup {0} (Python {1})".format(__version__, platform.python_version()),
  133. )
  134. group_m.add_argument(
  135. "--selftest",
  136. action="store_true",
  137. help="run integrated test suite and exit (pytest must be available)",
  138. )
  139. return parser
  140. def _selftest():
  141. """Run the integrated test suite with pytest."""
  142. from .test import run_tests
  143. run_tests()
  144. def main():
  145. """Parse arguments and then call the appropriate function(s)."""
  146. parser = _build_parser()
  147. color_init(autoreset=True)
  148. args = parser.parse_args()
  149. print(Style.BRIGHT + "gitup" + Style.RESET_ALL + ": the git-repo-updater")
  150. print()
  151. if args.selftest:
  152. _selftest()
  153. return
  154. if args.bookmark_file:
  155. args.bookmark_file = os.path.expanduser(args.bookmark_file)
  156. acted = False
  157. if args.bookmarks_to_add:
  158. add_bookmarks(args.bookmarks_to_add, args.bookmark_file)
  159. acted = True
  160. if args.bookmarks_to_del:
  161. delete_bookmarks(args.bookmarks_to_del, args.bookmark_file)
  162. acted = True
  163. if args.list_bookmarks:
  164. list_bookmarks(args.bookmark_file)
  165. acted = True
  166. if args.clean_bookmarks:
  167. clean_bookmarks(args.bookmark_file)
  168. acted = True
  169. if args.command:
  170. if args.directories_to_update:
  171. run_command(args.directories_to_update, args)
  172. if args.update or not args.directories_to_update:
  173. run_command(get_bookmarks(args.bookmark_file), args)
  174. else:
  175. if args.directories_to_update:
  176. update_directories(args.directories_to_update, args)
  177. acted = True
  178. if args.update or not acted:
  179. update_bookmarks(get_bookmarks(args.bookmark_file), args)
  180. def run():
  181. """Thin wrapper for main() that catches KeyboardInterrupts."""
  182. try:
  183. main()
  184. except KeyboardInterrupt:
  185. print("Stopped by user.")