git_helper.py 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. #!/usr/bin/env python3
  2. # Installs git hooks, updates them, updates submodules, that kind of thing.
  3. import subprocess
  4. import sys
  5. import os
  6. import shutil
  7. from pathlib import Path
  8. from typing import List
  9. SOLUTION_PATH = Path("..") / "SpaceStation14.sln"
  10. # If this doesn't match the saved version we overwrite them all.
  11. CURRENT_HOOKS_VERSION = "2"
  12. QUIET = len(sys.argv) == 2 and sys.argv[1] == "--quiet"
  13. def run_command(command: List[str], capture: bool = False) -> subprocess.CompletedProcess:
  14. """
  15. Runs a command with pretty output.
  16. """
  17. text = ' '.join(command)
  18. if not QUIET:
  19. print("$ {}".format(text))
  20. sys.stdout.flush()
  21. completed = None
  22. if capture:
  23. completed = subprocess.run(command, cwd="..", stdout=subprocess.PIPE)
  24. else:
  25. completed = subprocess.run(command, cwd="..")
  26. if completed.returncode != 0:
  27. print("Error: command exited with code {}!".format(completed.returncode))
  28. return completed
  29. def update_submodules():
  30. """
  31. Updates all submodules.
  32. """
  33. if ('GITHUB_ACTIONS' in os.environ):
  34. return
  35. if os.path.isfile("DISABLE_SUBMODULE_AUTOUPDATE"):
  36. return
  37. if shutil.which("git") is None:
  38. raise FileNotFoundError("git not found in PATH")
  39. # If the status doesn't match, force VS to reload the solution.
  40. # status = run_command(["git", "submodule", "status"], capture=True)
  41. run_command(["git", "submodule", "update", "--init", "--recursive"])
  42. # status2 = run_command(["git", "submodule", "status"], capture=True)
  43. # Something changed.
  44. # if status.stdout != status2.stdout:
  45. # print("Git submodules changed. Reloading solution.")
  46. # reset_solution()
  47. def install_hooks():
  48. """
  49. Installs the necessary git hooks into .git/hooks.
  50. """
  51. # Read version file.
  52. if os.path.isfile("INSTALLED_HOOKS_VERSION"):
  53. with open("INSTALLED_HOOKS_VERSION", "r") as f:
  54. if f.read() == CURRENT_HOOKS_VERSION:
  55. if not QUIET:
  56. print("No hooks change detected.")
  57. return
  58. with open("INSTALLED_HOOKS_VERSION", "w") as f:
  59. f.write(CURRENT_HOOKS_VERSION)
  60. print("Hooks need updating.")
  61. hooks_target_dir = Path("..")/".git"/"hooks"
  62. hooks_source_dir = Path("hooks")
  63. # Clear entire tree since we need to kill deleted files too.
  64. for filename in os.listdir(str(hooks_target_dir)):
  65. os.remove(str(hooks_target_dir/filename))
  66. for filename in os.listdir(str(hooks_source_dir)):
  67. print("Copying hook {}".format(filename))
  68. shutil.copy2(str(hooks_source_dir/filename),
  69. str(hooks_target_dir/filename))
  70. def reset_solution():
  71. """
  72. Force VS to think the solution has been changed to prompt the user to reload it, thus fixing any load errors.
  73. """
  74. with SOLUTION_PATH.open("r") as f:
  75. content = f.read()
  76. with SOLUTION_PATH.open("w") as f:
  77. f.write(content)
  78. if __name__ == '__main__':
  79. install_hooks()
  80. update_submodules()