azure-sphere-gallery/scripts/build-all.py

137 строки
4.1 KiB
Python
Executable File

#!/usr/bin/env python3
from pathlib import Path
import subprocess
import os
exclude_paths=[
"MT3620_M4_Sample_Code",
"AzureSphereDevX",
"threadx"
"AzureIoT_StoreAndForward/src/SimpleFileSystem",
"AzureSphereSquirrel/HLCore",
"AzureSphereSquirrel/HLCore/squirrel",
"BalancingRobot/Software/RTOS/mt3620_m4_software",
"CO2_MonitorHealthySpaces/src/AzureSphereDrivers",
"IndustrialDeviceController/Software/HighLevelApp/external",
"MQTT-C_Client/src/HighLevelApp/MQTT-C",
"BalancingRobot/Software/RTOS/threadx",
"AzureIoT_StoreAndForward"
]
BUILD_OK = "✅ Build OK"
BUILD_FAILED = "❌ Build failed"
GENERATE_FAILED = "❌ Generate failed"
MISSING_PRESETS = "❌ Missing CMakePresets.json"
NOT_SPHERE = "🤔 Not an Azure Sphere project (Consider adding to excludes)"
class Messages:
def __init__(self):
self.messages = {}
def add(self, category, instance, detail = None):
if not category in self.messages.keys():
self.messages[category] = []
self.messages[category] += [ (instance, detail) ]
def categories(self):
return self.messages.keys()
def instances(self, category):
if category not in self.messages.keys():
return []
return self.messages[category]
class Log:
def __init__(self): pass
def _log(self, level, message):
print(f"::{level}::{message}")
def error(self, message):
self._log("error", message)
def notice(self, message):
self._log("notice", message)
def should_exclude(path, exclude_paths):
for e in exclude_paths:
if e in path:
return True
return False
def code(str, lang=None):
lang = lang or ""
return f"```{lang}\n{str}\n```\n";
def indent(str, amount=1):
return "\n".join( (" " * amount) + line for line in str.split('\n') )
def build(cmakelists, log, messages):
print(f"Building {cmakelists}...")
preset = "ARM-Release"
generate_args = [ "cmake", f"--preset {preset}", str(cmakelists) ]
generate = subprocess.run( generate_args, capture_output=True)
if generate.returncode != 0:
detail = indent(code(generate.stdout.decode("utf-8")))
detail += indent(code(generate.stderr.decode("utf-8")))
messages.add(GENERATE_FAILED, p.parent, detail)
return False
folder = p.parent.joinpath("out").joinpath(preset)
build_args = [ "cmake", "--build", folder]
build = subprocess.run(build_args, capture_output=True)
if build.returncode != 0:
detail = indent(code(build.stdout.decode("utf-8")))
detail += indent(code(build.stderr.decode("utf-8")))
messages.add(BUILD_FAILED, p.parent, detail)
return False
messages.add(BUILD_OK, p.parent)
return True
cmakelists = list(( path
for path in list(Path(".").rglob("CMakeLists.txt"))
if not should_exclude(str(path), exclude_paths) ))
log = Log()
messages = Messages()
success = True
for p in cmakelists:
azsphere_project = False
with open(p,"r") as f:
for line in f:
if "azsphere_target_add_image_package" in line:
azsphere_project = True
if not azsphere_project:
messages.add(NOT_SPHERE, p)
continue
print(f"Considering {p}...")
folder = p.parent
if not folder.joinpath("CMakePresets.json").exists():
messages.add(MISSING_PRESETS, folder)
success = False
continue
if not build(p, log, messages):
success = False
with open(os.environ.get("GITHUB_STEP_SUMMARY", "summary.md"), "w") as summary:
for category in (BUILD_OK, BUILD_FAILED, GENERATE_FAILED, MISSING_PRESETS, NOT_SPHERE):
sorted_messages = sorted(messages.instances(category), key=lambda i: i[0])
summary.write(f"# {category}\n")
if len(sorted_messages) == 0:
summary.write("(none)\n")
else:
for (message, detail) in sorted_messages:
summary.write(f" * **{message}**\n")
if detail:
summary.write(f"{detail}\n")
exit(0 if success else -1)