check_schema_delta.py 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. #!/usr/bin/env python3
  2. # Check that no schema deltas have been added to the wrong version.
  3. import re
  4. from typing import Any, Dict, List
  5. import click
  6. import git
  7. SCHEMA_FILE_REGEX = re.compile(r"^synapse/storage/schema/(.*)/delta/(.*)/(.*)$")
  8. @click.command()
  9. @click.option(
  10. "--force-colors",
  11. is_flag=True,
  12. flag_value=True,
  13. default=None,
  14. help="Always output ANSI colours",
  15. )
  16. def main(force_colors: bool) -> None:
  17. click.secho(
  18. "+++ Checking schema deltas are in the right folder",
  19. fg="green",
  20. bold=True,
  21. color=force_colors,
  22. )
  23. click.secho("Updating repo...")
  24. repo = git.Repo()
  25. repo.remote().fetch()
  26. click.secho("Getting current schema version...")
  27. r = repo.git.show("origin/develop:synapse/storage/schema/__init__.py")
  28. locals: Dict[str, Any] = {}
  29. exec(r, locals)
  30. current_schema_version = locals["SCHEMA_VERSION"]
  31. diffs: List[git.Diff] = repo.remote().refs.develop.commit.diff(None)
  32. # Get the schema version of the local file to check against current schema on develop
  33. with open("synapse/storage/schema/__init__.py", "r") as file:
  34. local_schema = file.read()
  35. new_locals: Dict[str, Any] = {}
  36. exec(local_schema, new_locals)
  37. local_schema_version = new_locals["SCHEMA_VERSION"]
  38. if local_schema_version != current_schema_version:
  39. # local schema version must be +/-1 the current schema version on develop
  40. if abs(local_schema_version - current_schema_version) != 1:
  41. click.secho(
  42. "The proposed schema version has diverged more than one version from develop, please fix!",
  43. fg="red",
  44. bold=True,
  45. color=force_colors,
  46. )
  47. click.get_current_context().exit(1)
  48. # right, we've changed the schema version within the allowable tolerance so
  49. # let's now use the local version as the canonical version
  50. current_schema_version = local_schema_version
  51. click.secho(f"Current schema version: {current_schema_version}")
  52. seen_deltas = False
  53. bad_files = []
  54. for diff in diffs:
  55. if not diff.new_file or diff.b_path is None:
  56. continue
  57. match = SCHEMA_FILE_REGEX.match(diff.b_path)
  58. if not match:
  59. continue
  60. seen_deltas = True
  61. _, delta_version, _ = match.groups()
  62. if delta_version != str(current_schema_version):
  63. bad_files.append(diff.b_path)
  64. if not seen_deltas:
  65. click.secho(
  66. "No deltas found.",
  67. fg="green",
  68. bold=True,
  69. color=force_colors,
  70. )
  71. return
  72. if not bad_files:
  73. click.secho(
  74. f"All deltas are in the correct folder: {current_schema_version}!",
  75. fg="green",
  76. bold=True,
  77. color=force_colors,
  78. )
  79. return
  80. bad_files.sort()
  81. click.secho(
  82. "Found deltas in the wrong folder!",
  83. fg="red",
  84. bold=True,
  85. color=force_colors,
  86. )
  87. for f in bad_files:
  88. click.secho(
  89. f"\t{f}",
  90. fg="red",
  91. bold=True,
  92. color=force_colors,
  93. )
  94. click.secho()
  95. click.secho(
  96. f"Please move these files to delta/{current_schema_version}/",
  97. fg="red",
  98. bold=True,
  99. color=force_colors,
  100. )
  101. click.get_current_context().exit(1)
  102. if __name__ == "__main__":
  103. main()