version.py 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. #!/usb/bin/env python3
  2. from flipper.app import App
  3. import subprocess
  4. import os
  5. import json
  6. from datetime import date
  7. class GitVersion:
  8. def __init__(self, source_dir):
  9. self.source_dir = source_dir
  10. def get_version_info(self):
  11. commit = self._exec_git("rev-parse --short HEAD") or "unknown"
  12. dirty = False
  13. try:
  14. self._exec_git("diff --quiet")
  15. except subprocess.CalledProcessError as e:
  16. if e.returncode == 1:
  17. dirty = True
  18. # If WORKFLOW_BRANCH_OR_TAG is set in environment, is has precedence
  19. # (set by CI)
  20. branch = (
  21. os.environ.get("WORKFLOW_BRANCH_OR_TAG", None)
  22. or self._exec_git("rev-parse --abbrev-ref HEAD")
  23. or "unknown"
  24. )
  25. branch_num = self._exec_git("rev-list --count HEAD") or "n/a"
  26. try:
  27. version = self._exec_git("describe --tags --abbrev=0 --exact-match")
  28. except subprocess.CalledProcessError:
  29. version = "unknown"
  30. return {
  31. "GIT_COMMIT": commit,
  32. "GIT_BRANCH": branch,
  33. "GIT_BRANCH_NUM": branch_num,
  34. "VERSION": version,
  35. "BUILD_DIRTY": dirty and 1 or 0,
  36. }
  37. def _exec_git(self, args):
  38. cmd = ["git"]
  39. cmd.extend(args.split(" "))
  40. return (
  41. subprocess.check_output(cmd, cwd=self.source_dir, stderr=subprocess.STDOUT)
  42. .strip()
  43. .decode()
  44. )
  45. class Main(App):
  46. def init(self):
  47. self.subparsers = self.parser.add_subparsers(help="sub-command help")
  48. # generate
  49. self.parser_generate = self.subparsers.add_parser(
  50. "generate", help="Generate version header"
  51. )
  52. self.parser_generate.add_argument("-o", dest="outdir", required=True)
  53. self.parser_generate.add_argument(
  54. "-t",
  55. dest="target",
  56. type=int,
  57. help="hardware target",
  58. required=True,
  59. )
  60. self.parser_generate.add_argument("--dir", dest="sourcedir", required=True)
  61. self.parser_generate.set_defaults(func=self.generate)
  62. def generate(self):
  63. current_info = GitVersion(self.args.sourcedir).get_version_info()
  64. current_info.update(
  65. {
  66. "BUILD_DATE": date.today().strftime("%d-%m-%Y"),
  67. "TARGET": self.args.target,
  68. }
  69. )
  70. version_values = []
  71. for key in current_info:
  72. val = current_info[key]
  73. if isinstance(val, str):
  74. val = f'"{val}"'
  75. version_values.append(f"#define {key} {val}")
  76. new_version_info_fmt = "\n".join(version_values) + "\n"
  77. current_version_info = None
  78. version_header_name = os.path.join(self.args.outdir, "version.inc.h")
  79. version_json_name = os.path.join(self.args.outdir, "version.json")
  80. try:
  81. with open(version_header_name, "r") as file:
  82. current_version_info = file.read()
  83. except EnvironmentError as e:
  84. if self.args.debug:
  85. print(e)
  86. if current_version_info != new_version_info_fmt:
  87. if self.args.debug:
  88. print("old: ", current_version_info)
  89. print("new: ", new_version_info_fmt)
  90. with open(version_header_name, "w", newline="\n") as file:
  91. file.write(new_version_info_fmt)
  92. # os.utime("../lib/toolbox/version.c", None)
  93. print("Version information updated")
  94. else:
  95. if self.args.debug:
  96. print("Version information hasn't changed")
  97. version_json = {
  98. "firmware_build_date": current_info["BUILD_DATE"],
  99. "firmware_commit": current_info["GIT_COMMIT"],
  100. "firmware_branch": current_info["GIT_BRANCH"],
  101. "firmware_target": current_info["TARGET"],
  102. }
  103. with open(version_json_name, "w", newline="\n") as file:
  104. json.dump(version_json, file, indent=4)
  105. return 0
  106. if __name__ == "__main__":
  107. Main()()