diff --git a/scripts/west/zap_append.py b/scripts/west/zap_append.py index 5ac740e3a2..549dd5945d 100644 --- a/scripts/west/zap_append.py +++ b/scripts/west/zap_append.py @@ -12,6 +12,15 @@ from zap_common import DEFAULT_MATTER_PATH, DEFAULT_MATTER_TYPES_RELATIVE_PATH, DEFAULT_ZCL_JSON_RELATIVE_PATH +def get_attribute_name(attribute: ET.Element) -> str: + """If attribute has a name, return it, otherwise fallback to the text of the attribute entry.""" + from_attr = attribute.get('name') + if from_attr: + return from_attr + text = ''.join(attribute.itertext()).strip() + return text or None + + def add_custom_attributes_from_xml(xml_file: Path, zcl_data: dict, matter_path: Path = DEFAULT_MATTER_PATH): """ Parse the cluster XML file and add attributes with custom types to @@ -50,7 +59,7 @@ def add_custom_attributes_from_xml(xml_file: Path, zcl_data: dict, matter_path: # Check all attributes in the cluster for attribute in cluster.findall('attribute'): attr_type = attribute.get('type') - attr_name = attribute.get('name') + attr_name = get_attribute_name(attribute) if attr_type and attr_type not in types: attributes_with_missing_types.append({ diff --git a/scripts/west/zap_common.py b/scripts/west/zap_common.py index 8585b307c6..e6c973443a 100644 --- a/scripts/west/zap_common.py +++ b/scripts/west/zap_common.py @@ -299,13 +299,18 @@ def __exit__(self, exc_type, exc_val, exc_tb): def display_zap_message(output: subprocess.CompletedProcess[str]) -> None: """ - If the output contains the error from napi_throw, suggest user to use zap-sync to sync the ZAP file. + If the output contains the error from napi_throw, suggest user to use zap-sync to sync the ZAP file and make sure that all attributes are provided. """ + if output.stdout: + log.dbg(f"output: {output.stdout}") + + if output.stderr: + log.wrn(f"stderr: {output.stderr}") + if 'Unknown attribute' in output.stdout: - log.err("Your zcl.json file seems to be outdated. Please use 'west zap-sync' command to synchronize it with the newest Matter Data Model.") - return - else: - print(f"output: {output.stdout}") + log.err("Your zcl.json file seems to be outdated or is missing some attributes. " + "Please use 'west zap-sync' command to synchronize it with the newest Matter Data Model " + "and make sure that all cluster attributes are properly defined in the cluster XML file.") class ZapInstaller: diff --git a/scripts/west/zap_gui.py b/scripts/west/zap_gui.py index 34588689e9..b1b9e4a845 100644 --- a/scripts/west/zap_gui.py +++ b/scripts/west/zap_gui.py @@ -102,6 +102,10 @@ def run_zap(): cmd += ["--tempState"] output = subprocess.run([str(x) for x in cmd], capture_output=True, text=True) + # Chromium often prints nothing to stdout when the sandbox aborts early. + # returncode -5 is a sentinel consumed by fix_sandbox_permissions(). + if output.returncode != 0 and not output.stdout and not output.stderr: + raise subprocess.CalledProcessError(-5, cmd) display_zap_message(output) return output diff --git a/scripts/west/zap_sync.py b/scripts/west/zap_sync.py index 753694c5e3..db8ace920e 100644 --- a/scripts/west/zap_sync.py +++ b/scripts/west/zap_sync.py @@ -56,13 +56,17 @@ def do_run(self, args, unknown_args): zap_installer.update_zap_if_needed() if args.zcl_json: - # Provided zcl.json file exists, so we need to remove it and create a copy of the default zcl.json file. - zcl_file_path = Path(args.zcl_json).absolute() - if zcl_file_path.exists(): - zcl_file_path.unlink() - shutil.copy(default_zcl_path, zcl_file_path) + zcl_candidate = Path(args.zcl_json).absolute() + # Reset project zcl.json from the SDK default. If -j is the default path itself, + # do not unlink/copy (to avoid deleting the source then failing to copy if the path is the same). + if zcl_candidate.resolve() == default_zcl_path.resolve(): + zcl_file_path = default_zcl_path + else: + if zcl_candidate.exists(): + zcl_candidate.unlink() + shutil.copy(default_zcl_path, zcl_candidate) + zcl_file_path = zcl_candidate else: - # No zcl.json file provided, so we need to create a new one because a path was provided. zcl_file_path = default_zcl_path log.inf(f"Synchronizing zcl.json file ({zcl_file_path.resolve()})...") @@ -91,6 +95,10 @@ def run_zap(): cmd += ["--tempState"] output = subprocess.run([str(x) for x in cmd], capture_output=True, text=True) + # Chromium often prints nothing to stdout when the sandbox aborts early. + # returncode -5 is a sentinel consumed by fix_sandbox_permissions(). + if output.returncode != 0 and not output.stdout and not output.stderr: + raise subprocess.CalledProcessError(-5, cmd) display_zap_message(output) return output