From 3a2c675792db96792dd3e47681f11b5634fdf6d4 Mon Sep 17 00:00:00 2001 From: puddly <32534428+puddly@users.noreply.github.com> Date: Mon, 6 May 2024 14:16:04 -0400 Subject: [PATCH 1/7] Create a pre-commit hook to normalize .cproject files --- .pre-commit-config.yaml | 9 +++++++++ tools/cproject_normalizer.py | 31 +++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+) create mode 100644 .pre-commit-config.yaml create mode 100644 tools/cproject_normalizer.py diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 00000000..2493710b --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,9 @@ +repos: + - repo: local + hooks: + - id: normalize-cproject + name: Normalize Eclipse .cproject files + entry: python tools/cproject_normalizer.py + language: system + files: \.cproject$ + pass_filenames: true diff --git a/tools/cproject_normalizer.py b/tools/cproject_normalizer.py new file mode 100644 index 00000000..385d1f7c --- /dev/null +++ b/tools/cproject_normalizer.py @@ -0,0 +1,31 @@ +import re +import sys +import json +import pathlib +import xml.etree.ElementTree as ET + +cproject_path = pathlib.Path(sys.argv[1]) +cproject = cproject_path.read_text() + +tree = ET.fromstring(cproject) + +for storage_module in tree.findall(".//storageModule"): + if "projectCommon.copiedFiles" in storage_module.attrib: + copied_files = json.loads(storage_module.attrib["projectCommon.copiedFiles"]) + copied_files.sort( + key=lambda f: (f["generated"], f["projectPath"], f["version"]) + ) + storage_module.attrib["projectCommon.copiedFiles"] = json.dumps( + copied_files, separators=(",", ":"), indent=None + ) + + if "cppBuildConfig.projectBuiltInState" in storage_module.attrib: + project_built_in_state = json.loads( + storage_module.attrib["cppBuildConfig.projectBuiltInState"] + ) + +match = re.search(r'(<\?.*\?>)', cproject[:200], flags=re.DOTALL) +processing_instructions = match.group(0) + +xml_data = ET.tostring(tree, encoding="unicode", xml_declaration=False).replace(" />", "/>") +cproject_path.write_text(processing_instructions + xml_data) From 16d60a4da0e7baf5c5c0b28ea6f0388481b3ccd9 Mon Sep 17 00:00:00 2001 From: puddly <32534428+puddly@users.noreply.github.com> Date: Mon, 6 May 2024 14:32:48 -0400 Subject: [PATCH 2/7] Normalize existing projects --- misc/firmware-eraser/.cproject | 2 +- src/ot-rcp/.cproject | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/misc/firmware-eraser/.cproject b/misc/firmware-eraser/.cproject index 38bd6a04..5fd36b36 100644 --- a/misc/firmware-eraser/.cproject +++ b/misc/firmware-eraser/.cproject @@ -330,7 +330,7 @@ - + diff --git a/src/ot-rcp/.cproject b/src/ot-rcp/.cproject index 7d9646a7..1b426f48 100644 --- a/src/ot-rcp/.cproject +++ b/src/ot-rcp/.cproject @@ -442,7 +442,7 @@ - + From 139c0a15d99c9069d62ca67d51fc9eb80eb200f6 Mon Sep 17 00:00:00 2001 From: puddly <32534428+puddly@users.noreply.github.com> Date: Mon, 6 May 2024 14:42:00 -0400 Subject: [PATCH 3/7] Normalize deeper --- misc/firmware-eraser/.cproject | 4 ++-- src/ot-rcp/.cproject | 2 +- src/rcp-uart-802154/.cproject | 4 ++-- tools/cproject_normalizer.py | 21 ++++++++++++++++++--- 4 files changed, 23 insertions(+), 8 deletions(-) diff --git a/misc/firmware-eraser/.cproject b/misc/firmware-eraser/.cproject index 5fd36b36..e43de06c 100644 --- a/misc/firmware-eraser/.cproject +++ b/misc/firmware-eraser/.cproject @@ -23,7 +23,7 @@ - + @@ -264,7 +264,7 @@ - + diff --git a/src/ot-rcp/.cproject b/src/ot-rcp/.cproject index 1b426f48..e4436990 100644 --- a/src/ot-rcp/.cproject +++ b/src/ot-rcp/.cproject @@ -23,7 +23,7 @@ - + diff --git a/src/rcp-uart-802154/.cproject b/src/rcp-uart-802154/.cproject index cecebab1..c8e71939 100644 --- a/src/rcp-uart-802154/.cproject +++ b/src/rcp-uart-802154/.cproject @@ -23,7 +23,7 @@ - + @@ -499,7 +499,7 @@ - + diff --git a/tools/cproject_normalizer.py b/tools/cproject_normalizer.py index 385d1f7c..01be15d8 100644 --- a/tools/cproject_normalizer.py +++ b/tools/cproject_normalizer.py @@ -24,8 +24,23 @@ storage_module.attrib["cppBuildConfig.projectBuiltInState"] ) -match = re.search(r'(<\?.*\?>)', cproject[:200], flags=re.DOTALL) + for state in project_built_in_state: + if "resolvedOptionsStr" in state: + resolved_options = json.loads(state["resolvedOptionsStr"]) + resolved_options.sort(key=lambda o: (o["optionId"])) + + state["resolvedOptionsStr"] = json.dumps( + resolved_options, separators=(",", ":"), indent=None + ) + + storage_module.attrib["cppBuildConfig.projectBuiltInState"] = json.dumps( + project_built_in_state, separators=(",", ":"), indent=None + ) + +match = re.search(r"(<\?.*\?>)", cproject[:200], flags=re.DOTALL) processing_instructions = match.group(0) -xml_data = ET.tostring(tree, encoding="unicode", xml_declaration=False).replace(" />", "/>") -cproject_path.write_text(processing_instructions + xml_data) +xml_text = ET.tostring(tree, encoding="unicode", xml_declaration=False) +xml_text = xml_text.replace(" />", "/>") + +cproject_path.write_text(processing_instructions + xml_text) From 833c7fddf29752ad5403d482dcb834b2ec70e2f6 Mon Sep 17 00:00:00 2001 From: puddly <32534428+puddly@users.noreply.github.com> Date: Mon, 6 May 2024 14:52:24 -0400 Subject: [PATCH 4/7] Clean up normalizer script --- .pre-commit-config.yaml | 2 +- ...ct_normalizer.py => normalize_cproject.py} | 32 ++++++++++++------- 2 files changed, 21 insertions(+), 13 deletions(-) rename tools/{cproject_normalizer.py => normalize_cproject.py} (64%) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 2493710b..46c7e8b5 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -3,7 +3,7 @@ repos: hooks: - id: normalize-cproject name: Normalize Eclipse .cproject files - entry: python tools/cproject_normalizer.py + entry: python tools/normalize_cproject.py language: system files: \.cproject$ pass_filenames: true diff --git a/tools/cproject_normalizer.py b/tools/normalize_cproject.py similarity index 64% rename from tools/cproject_normalizer.py rename to tools/normalize_cproject.py index 01be15d8..29c5ab6b 100644 --- a/tools/cproject_normalizer.py +++ b/tools/normalize_cproject.py @@ -4,9 +4,19 @@ import pathlib import xml.etree.ElementTree as ET + +def json_dumps_compact(obj: dict | list) -> str: + """Compactly dump JSON into a string.""" + return json.dumps(copied_files, separators=(",", ":"), indent=None) + + cproject_path = pathlib.Path(sys.argv[1]) cproject = cproject_path.read_text() +# Capture all preprocessing directives verbatim +match = re.search(r"(<\?.*\?>)", cproject[:200], flags=re.DOTALL) +processing_instructions = match.group(0) + tree = ET.fromstring(cproject) for storage_module in tree.findall(".//storageModule"): @@ -15,8 +25,8 @@ copied_files.sort( key=lambda f: (f["generated"], f["projectPath"], f["version"]) ) - storage_module.attrib["projectCommon.copiedFiles"] = json.dumps( - copied_files, separators=(",", ":"), indent=None + storage_module.attrib["projectCommon.copiedFiles"] = json_dumps_compact( + copied_files ) if "cppBuildConfig.projectBuiltInState" in storage_module.attrib: @@ -29,18 +39,16 @@ resolved_options = json.loads(state["resolvedOptionsStr"]) resolved_options.sort(key=lambda o: (o["optionId"])) - state["resolvedOptionsStr"] = json.dumps( - resolved_options, separators=(",", ":"), indent=None - ) - - storage_module.attrib["cppBuildConfig.projectBuiltInState"] = json.dumps( - project_built_in_state, separators=(",", ":"), indent=None - ) + state["resolvedOptionsStr"] = json_dumps_compact(resolved_options) -match = re.search(r"(<\?.*\?>)", cproject[:200], flags=re.DOTALL) -processing_instructions = match.group(0) + storage_module.attrib[ + "cppBuildConfig.projectBuiltInState" + ] = json_dumps_compact(project_built_in_state) +# Normalize self-closing tag spacing xml_text = ET.tostring(tree, encoding="unicode", xml_declaration=False) xml_text = xml_text.replace(" />", "/>") -cproject_path.write_text(processing_instructions + xml_text) +# Only touch the filesystem if we need to +if processing_instructions + xml_text != cproject: + cproject_path.write_text(processing_instructions + xml_text) From 2e99e296b33683b0f76874f2a0dfed7b6bee4e48 Mon Sep 17 00:00:00 2001 From: puddly <32534428+puddly@users.noreply.github.com> Date: Mon, 6 May 2024 14:52:34 -0400 Subject: [PATCH 5/7] Add ruff --- .pre-commit-config.yaml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 46c7e8b5..2582ac15 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -7,3 +7,10 @@ repos: language: system files: \.cproject$ pass_filenames: true + + - repo: https://github.com/astral-sh/ruff-pre-commit + rev: v0.4.3 + hooks: + - id: ruff + args: [--fix] + - id: ruff-format From 4e249610abde65d54b625ed98c5f171926a4e87b Mon Sep 17 00:00:00 2001 From: puddly <32534428+puddly@users.noreply.github.com> Date: Mon, 6 May 2024 14:53:45 -0400 Subject: [PATCH 6/7] Run ruff --- tools/build_project.py | 5 ++--- tools/normalize_cproject.py | 10 +++++----- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/tools/build_project.py b/tools/build_project.py index d677cb27..7852ead4 100755 --- a/tools/build_project.py +++ b/tools/build_project.py @@ -9,7 +9,6 @@ import sys import copy import json -import shlex import shutil import hashlib import logging @@ -489,7 +488,7 @@ def main(): f' --parameter sdk_dir:"{sdk}"' "\n" ) - f.write(f"\t-@echo ' '") + f.write("\t-@echo ' '") subprocess.run( [ @@ -534,7 +533,7 @@ def main(): # Insert our postbuild step cmakelists_txt = cmake_build_root / "CMakeLists.txt" cmakelists = cmakelists_txt.read_text() - s37_line = next(l for l in cmakelists.split("\n") if "-O srec" in l) + s37_line = next(line for line in cmakelists.split("\n") if "-O srec" in line) s37_output_file = s37_line.split(" ")[-1] s37_build_folder = s37_output_file.split("/", 1)[0] + '"' diff --git a/tools/normalize_cproject.py b/tools/normalize_cproject.py index 29c5ab6b..4d4e7116 100644 --- a/tools/normalize_cproject.py +++ b/tools/normalize_cproject.py @@ -7,7 +7,7 @@ def json_dumps_compact(obj: dict | list) -> str: """Compactly dump JSON into a string.""" - return json.dumps(copied_files, separators=(",", ":"), indent=None) + return json.dumps(obj, separators=(",", ":"), indent=None) cproject_path = pathlib.Path(sys.argv[1]) @@ -37,13 +37,13 @@ def json_dumps_compact(obj: dict | list) -> str: for state in project_built_in_state: if "resolvedOptionsStr" in state: resolved_options = json.loads(state["resolvedOptionsStr"]) - resolved_options.sort(key=lambda o: (o["optionId"])) + resolved_options.sort(key=lambda o: o["optionId"]) state["resolvedOptionsStr"] = json_dumps_compact(resolved_options) - storage_module.attrib[ - "cppBuildConfig.projectBuiltInState" - ] = json_dumps_compact(project_built_in_state) + storage_module.attrib["cppBuildConfig.projectBuiltInState"] = ( + json_dumps_compact(project_built_in_state) + ) # Normalize self-closing tag spacing xml_text = ET.tostring(tree, encoding="unicode", xml_declaration=False) From dbfade1c2682cb981a50354433ad93b422e0c419 Mon Sep 17 00:00:00 2001 From: puddly <32534428+puddly@users.noreply.github.com> Date: Mon, 6 May 2024 14:58:57 -0400 Subject: [PATCH 7/7] Run pre-commit in CI --- .github/workflows/build.yaml | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 1e17b875..e979bf0a 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -9,10 +9,25 @@ on: paths-ignore: - '.gitignore' - 'README.md' + env: REGISTRY: ghcr.io jobs: + run-pre-commit: + name: Run pre-commit + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-python@v3 + - name: Install pre-commit + run: | + pip install pre-commit + pre-commit install + - name: Run pre-commit + run: | + pre-commit run --show-diff-on-failure --color=always --all-files + build-container: name: Create build container image runs-on: ubuntu-latest