A console script that allows you to easily update multiple git repositories at once
Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  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. from __future__ import print_function
  6. from glob import glob
  7. import os
  8. from colorama import Fore, Style
  9. from gitup.migrate import run_migrations
  10. __all__ = ["get_default_config_path", "get_bookmarks", "add_bookmarks",
  11. "delete_bookmarks", "list_bookmarks", "clean_bookmarks"]
  12. YELLOW = Fore.YELLOW + Style.BRIGHT
  13. RED = Fore.RED + Style.BRIGHT
  14. INDENT1 = " " * 3
  15. def _ensure_dirs(path):
  16. """Ensure the directories within the given pathname exist."""
  17. dirname = os.path.dirname(path)
  18. if dirname and not os.path.exists(dirname): # Race condition, meh...
  19. os.makedirs(dirname)
  20. def _load_config_file(config_path=None):
  21. """Read the config file and return a list of bookmarks."""
  22. run_migrations()
  23. cfg_path = config_path or get_default_config_path()
  24. try:
  25. with open(cfg_path, "rb") as config_file:
  26. paths = config_file.read().split(b"\n")
  27. except IOError:
  28. return []
  29. paths = [path.decode("utf8").strip() for path in paths]
  30. paths = _strip_comment_lines(paths)
  31. return [path for path in paths if path]
  32. def _strip_comment_lines(paths):
  33. """Remove any lines starting with #."""
  34. i = 0
  35. while i < len(paths):
  36. path = paths[i]
  37. removed_comment = False
  38. for j in range(0, len(path)):
  39. path_char = path[j]
  40. if path_char == " ":
  41. continue
  42. if path_char == "#":
  43. removed_comment = True
  44. paths.pop(i)
  45. break
  46. if removed_comment is False:
  47. i = i + 1
  48. return paths
  49. def _save_config_file(bookmarks, config_path=None):
  50. """Save the bookmarks list to the given config file."""
  51. run_migrations()
  52. cfg_path = config_path or get_default_config_path()
  53. _ensure_dirs(cfg_path)
  54. dump = b"\n".join(path.encode("utf8") for path in bookmarks)
  55. with open(cfg_path, "wb") as config_file:
  56. config_file.write(dump)
  57. def _normalize_path(path):
  58. """Normalize the given path."""
  59. if path.startswith("~"):
  60. return os.path.normcase(os.path.normpath(path))
  61. return os.path.normcase(os.path.abspath(path))
  62. def get_default_config_path():
  63. """Return the default path to the configuration file."""
  64. xdg_cfg = os.environ.get("XDG_CONFIG_HOME") or os.path.join("~", ".config")
  65. return os.path.join(os.path.expanduser(xdg_cfg), "gitup", "bookmarks")
  66. def get_bookmarks(config_path=None):
  67. """Get a list of all bookmarks, or an empty list if there are none."""
  68. return _load_config_file(config_path)
  69. def add_bookmarks(paths, config_path=None):
  70. """Add a list of paths as bookmarks to the config file."""
  71. config = _load_config_file(config_path)
  72. paths = [_normalize_path(path) for path in paths]
  73. added, exists = [], []
  74. for path in paths:
  75. if path in config:
  76. exists.append(path)
  77. else:
  78. config.append(path)
  79. added.append(path)
  80. _save_config_file(config, config_path)
  81. if added:
  82. print(YELLOW + "Added bookmarks:")
  83. for path in added:
  84. print(INDENT1, path)
  85. if exists:
  86. print(RED + "Already bookmarked:")
  87. for path in exists:
  88. print(INDENT1, path)
  89. def delete_bookmarks(paths, config_path=None):
  90. """Remove a list of paths from the bookmark config file."""
  91. config = _load_config_file(config_path)
  92. paths = [_normalize_path(path) for path in paths]
  93. deleted, notmarked = [], []
  94. if config:
  95. for path in paths:
  96. if path in config:
  97. config.remove(path)
  98. deleted.append(path)
  99. else:
  100. notmarked.append(path)
  101. _save_config_file(config, config_path)
  102. else:
  103. notmarked = paths
  104. if deleted:
  105. print(YELLOW + "Deleted bookmarks:")
  106. for path in deleted:
  107. print(INDENT1, path)
  108. if notmarked:
  109. print(RED + "Not bookmarked:")
  110. for path in notmarked:
  111. print(INDENT1, path)
  112. def list_bookmarks(config_path=None):
  113. """Print all of our current bookmarks."""
  114. bookmarks = _load_config_file(config_path)
  115. if bookmarks:
  116. print(YELLOW + "Current bookmarks:")
  117. for bookmark_path in bookmarks:
  118. print(INDENT1, bookmark_path)
  119. else:
  120. print("You have no bookmarks to display.")
  121. def clean_bookmarks(config_path=None):
  122. """Delete any bookmarks that don't exist."""
  123. bookmarks = _load_config_file(config_path)
  124. if not bookmarks:
  125. print("You have no bookmarks to clean up.")
  126. return
  127. delete = [path for path in bookmarks
  128. if not (os.path.isdir(path) or glob(os.path.expanduser(path)))]
  129. if not delete:
  130. print("All of your bookmarks are valid.")
  131. return
  132. bookmarks = [path for path in bookmarks if path not in delete]
  133. _save_config_file(bookmarks, config_path)
  134. print(YELLOW + "Deleted bookmarks:")
  135. for path in delete:
  136. print(INDENT1, path)