Fork of the espurna firmware for `mhsw` switches
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.

138 lines
3.9 KiB

  1. import os
  2. import argparse
  3. import re
  4. import shlex
  5. import configparser
  6. import collections
  7. CI = any([os.environ.get("TRAVIS"), os.environ.get("CI")])
  8. Build = collections.namedtuple("Build", "env extends build_flags src_build_flags")
  9. def expand_variables(cfg, value):
  10. RE_VARS = re.compile("\$\{.*?\}")
  11. for var in RE_VARS.findall(value):
  12. section, option = var.replace("${", "").replace("}", "").split(".", 1)
  13. value = value.replace(var, expand_variables(cfg, cfg.get(section, option)))
  14. return value
  15. def get_builds(cfg):
  16. RE_NEWLINE = re.compile("\r\n|\n")
  17. BASE_BUILD_FLAGS = set(
  18. shlex.split(expand_variables(cfg, cfg.get("env", "build_flags")))
  19. )
  20. for section in cfg.sections():
  21. if (not section.startswith("env:")) or (
  22. section.startswith("env:esp8266-") and section.endswith("-base")
  23. ):
  24. continue
  25. build_flags = None
  26. src_build_flags = None
  27. try:
  28. build_flags = cfg.get(section, "build_flags")
  29. build_flags = RE_NEWLINE.sub(" ", build_flags).strip()
  30. build_flags = " ".join(
  31. BASE_BUILD_FLAGS ^ set(shlex.split(expand_variables(cfg, build_flags)))
  32. )
  33. except configparser.NoOptionError:
  34. pass
  35. try:
  36. src_build_flags = cfg.get(section, "src_build_flags")
  37. src_build_flags = RE_NEWLINE.sub(" ", src_build_flags).strip()
  38. src_build_flags = expand_variables(cfg, src_build_flags)
  39. except configparser.NoOptionError:
  40. pass
  41. yield Build(
  42. section.replace("env:", ""),
  43. cfg.get(section, "extends").replace("env:", ""),
  44. build_flags,
  45. src_build_flags,
  46. )
  47. def find_any(string, values):
  48. for value in values:
  49. if value in string:
  50. return True
  51. return False
  52. def generate_lines(builds, ignore):
  53. cores = []
  54. generic = []
  55. for build in builds:
  56. if find_any(build.env, ignore):
  57. continue
  58. flags = []
  59. if build.build_flags:
  60. flags.append('PLATFORMIO_BUILD_FLAGS="{}"'.format(build.build_flags))
  61. if build.src_build_flags:
  62. flags.append('ESPURNA_FLAGS="{}"'.format(build.src_build_flags))
  63. flags.append('ESPURNA_NAME="{env}"'.format(env=build.env))
  64. cmd = ["env"]
  65. cmd.extend(flags)
  66. cmd.extend(["pio", "run", "-e", build.extends, "-s", "-t", "release"])
  67. line = " ".join(cmd)
  68. # push core variants to the front as they definetly include global build_flags
  69. output = generic
  70. if "ESPURNA_CORE" in build.src_build_flags:
  71. output = cores
  72. output.append(line)
  73. return cores + generic
  74. def every(seq, nth, total):
  75. index = 0
  76. for value in seq:
  77. if index == nth:
  78. yield value
  79. index = (index + 1) % total
  80. if __name__ == "__main__":
  81. if not CI:
  82. raise ValueError("* Not in CI *")
  83. parser = argparse.ArgumentParser()
  84. parser.add_argument("version")
  85. parser.add_argument("--ignore", action="append")
  86. args = parser.parse_args()
  87. Config = configparser.ConfigParser()
  88. with open("platformio.ini", "r") as f:
  89. Config.read_file(f)
  90. builder_total_threads = int(os.environ["BUILDER_TOTAL_THREADS"])
  91. builder_thread = int(os.environ["BUILDER_THREAD"])
  92. if builder_thread >= builder_total_threads:
  93. raise ValueError("* Builder thread index out of range *")
  94. builds = every(get_builds(Config), builder_thread, builder_total_threads)
  95. print("#!/bin/bash")
  96. print("set -e -x")
  97. print('export ESPURNA_VERSION="{}"'.format(args.version))
  98. print('trap "ls -l ${TRAVIS_BUILD_DIR}/firmware/${ESPURNA_VERSION}" EXIT')
  99. print(
  100. 'echo "Selected thread #{} out of {}"'.format(
  101. builder_thread + 1, builder_total_threads
  102. )
  103. )
  104. for line in generate_lines(builds, args.ignore or ()):
  105. print(line)