Skip to content

Commit

Permalink
Normalize .cproject files with pre-commit (#60)
Browse files Browse the repository at this point in the history
* Create a pre-commit hook to normalize .cproject files

* Normalize existing projects

* Normalize deeper

* Clean up normalizer script

* Add ruff

* Run ruff

* Run pre-commit in CI
  • Loading branch information
puddly authored May 6, 2024
1 parent d44ebf9 commit c446ab1
Show file tree
Hide file tree
Showing 7 changed files with 94 additions and 10 deletions.
15 changes: 15 additions & 0 deletions .github/workflows/build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
16 changes: 16 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
repos:
- repo: local
hooks:
- id: normalize-cproject
name: Normalize Eclipse .cproject files
entry: python tools/normalize_cproject.py
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
6 changes: 3 additions & 3 deletions misc/firmware-eraser/.cproject

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions src/ot-rcp/.cproject

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions src/rcp-uart-802154/.cproject

Large diffs are not rendered by default.

5 changes: 2 additions & 3 deletions tools/build_project.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
import sys
import copy
import json
import shlex
import shutil
import hashlib
import logging
Expand Down Expand Up @@ -511,7 +510,7 @@ def main():
f' --parameter sdk_dir:"{sdk}"'
"\n"
)
f.write(f"\t-@echo ' '")
f.write("\t-@echo ' '")

subprocess.run(
[
Expand Down Expand Up @@ -556,7 +555,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] + '"'

Expand Down
54 changes: 54 additions & 0 deletions tools/normalize_cproject.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import re
import sys
import json
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(obj, 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"):
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_compact(
copied_files
)

if "cppBuildConfig.projectBuiltInState" in storage_module.attrib:
project_built_in_state = json.loads(
storage_module.attrib["cppBuildConfig.projectBuiltInState"]
)

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_compact(resolved_options)

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(" />", "/>")

# Only touch the filesystem if we need to
if processing_instructions + xml_text != cproject:
cproject_path.write_text(processing_instructions + xml_text)

0 comments on commit c446ab1

Please sign in to comment.