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.

139 line
5.2 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 (get_default_config_path, get_bookmarks, add_bookmarks,
  11. delete_bookmarks, list_bookmarks, clean_bookmarks)
  12. from gitup.update import update_bookmarks, update_directories, run_command
  13. def _build_parser():
  14. """Build and return the argument parser."""
  15. parser = argparse.ArgumentParser(
  16. description="Easily update multiple git repositories at once.",
  17. epilog="""
  18. Both relative and absolute paths are accepted by all arguments.
  19. Direct bug reports and feature requests to
  20. https://github.com/earwig/git-repo-updater.""",
  21. add_help=False)
  22. group_u = parser.add_argument_group("updating repositories")
  23. group_b = parser.add_argument_group("bookmarking")
  24. group_a = parser.add_argument_group("advanced")
  25. group_m = parser.add_argument_group("miscellaneous")
  26. group_u.add_argument(
  27. 'directories_to_update', nargs="*", metavar="path",
  28. help="""update this repository, or all repositories it contains
  29. (if not a repo directly)""")
  30. group_u.add_argument(
  31. '-u', '--update', action="store_true", help="""update all bookmarks
  32. (default behavior when called without arguments)""")
  33. group_u.add_argument(
  34. '-t', '--depth', dest="max_depth", metavar="n", type=int, default=3,
  35. help="""max recursion depth when searching for repos in subdirectories
  36. (default: 3; use 0 for no recursion, or -1 for unlimited)""")
  37. group_u.add_argument(
  38. '-c', '--current-only', action="store_true", help="""only fetch the
  39. remote tracked by the current branch instead of all remotes""")
  40. group_u.add_argument(
  41. '-f', '--fetch-only', action="store_true",
  42. help="only fetch remotes, don't try to fast-forward any branches")
  43. group_u.add_argument(
  44. '-p', '--prune', action="store_true", help="""after fetching, delete
  45. remote-tracking branches that no longer exist on their remote""")
  46. group_b.add_argument(
  47. '-a', '--add', dest="bookmarks_to_add", nargs="+", metavar="path", help="add directory(s) as bookmarks")
  48. group_b.add_argument(
  49. '-d', '--delete', dest="bookmarks_to_del", nargs="+", metavar="path",
  50. help="delete bookmark(s) (leaves actual directories alone)")
  51. group_b.add_argument(
  52. '-l', '--list', dest="list_bookmarks", action="store_true",
  53. help="list current bookmarks")
  54. group_b.add_argument(
  55. '-n', '--clean', '--cleanup', dest="clean_bookmarks",
  56. action="store_true", help="delete any bookmarks that don't exist")
  57. group_b.add_argument(
  58. '-b', '--bookmark-file', nargs="?", metavar="path",
  59. help="use a specific bookmark config file (default: {0})".format(
  60. get_default_config_path()))
  61. group_a.add_argument(
  62. '-e', '--exec', '--batch', dest="command", metavar="command",
  63. help="run a shell command on all repos")
  64. group_m.add_argument(
  65. '-h', '--help', action="help", help="show this help message and exit")
  66. group_m.add_argument(
  67. '-v', '--version', action="version",
  68. version="gitup {0} (Python {1})".format(
  69. __version__, platform.python_version()))
  70. group_m.add_argument(
  71. '--selftest', action="store_true",
  72. help="run integrated test suite and exit (pytest must be available)")
  73. return parser
  74. def _selftest():
  75. """Run the integrated test suite with pytest."""
  76. from .test import run_tests
  77. run_tests()
  78. def main():
  79. """Parse arguments and then call the appropriate function(s)."""
  80. parser = _build_parser()
  81. color_init(autoreset=True)
  82. args = parser.parse_args()
  83. print(Style.BRIGHT + "gitup" + Style.RESET_ALL + ": the git-repo-updater")
  84. print()
  85. if args.selftest:
  86. _selftest()
  87. return
  88. if args.bookmark_file:
  89. args.bookmark_file = os.path.expanduser(args.bookmark_file)
  90. acted = False
  91. if args.bookmarks_to_add:
  92. add_bookmarks(args.bookmarks_to_add, args.bookmark_file)
  93. acted = True
  94. if args.bookmarks_to_del:
  95. delete_bookmarks(args.bookmarks_to_del, args.bookmark_file)
  96. acted = True
  97. if args.list_bookmarks:
  98. list_bookmarks(args.bookmark_file)
  99. acted = True
  100. if args.clean_bookmarks:
  101. clean_bookmarks(args.bookmark_file)
  102. acted = True
  103. if args.command:
  104. if args.directories_to_update:
  105. run_command(args.directories_to_update, args)
  106. if args.update or not args.directories_to_update:
  107. run_command(get_bookmarks(args.bookmark_file), args)
  108. else:
  109. if args.directories_to_update:
  110. update_directories(args.directories_to_update, args)
  111. acted = True
  112. if args.update or not acted:
  113. update_bookmarks(get_bookmarks(args.bookmark_file), args)
  114. def run():
  115. """Thin wrapper for main() that catches KeyboardInterrupts."""
  116. try:
  117. main()
  118. except KeyboardInterrupt:
  119. print("Stopped by user.")