scripts: utils: add include migration script
All includes are now prefixed with <zephyr/...>, even though the old
include paths can still be used when CONFIG_LEGACY_INCLUDE_PATH=y, an
option still enabled by default. Migrating large projects can be tedious
and time consuming. This patch provides a script that can be used to
migrate any Zephyr-based project to the new include path. It is used
like this:
python $ZEPHYR_BASE/scripts/utils/migrate_includes.py \
-p path/to/zephyr-based-project
Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
diff --git a/scripts/utils/migrate_includes.py b/scripts/utils/migrate_includes.py
new file mode 100644
index 0000000..557ee2c
--- /dev/null
+++ b/scripts/utils/migrate_includes.py
@@ -0,0 +1,73 @@
+"""
+Utility script to migrate Zephyr-based projects to the new <zephyr/...> include
+prefix.
+
+Usage::
+
+ python $ZEPHYR_BASE/scripts/utils/migrate_includes.py \
+ -p path/to/zephyr-based-project
+
+Copyright (c) 2022 Nordic Semiconductor ASA
+SPDX-License-Identifier: Apache-2.0
+"""
+
+import argparse
+from pathlib import Path
+import re
+import sys
+
+
+ZEPHYR_BASE = Path(__file__).parents[2]
+
+EXTENSIONS = ("c", "cpp", "h", "dts", "dtsi", "rst", "S", "overlay", "ld")
+
+
+def update_includes(project, dry_run):
+ for p in project.glob("**/*"):
+ if not p.is_file() or not p.suffix or p.suffix[1:] not in EXTENSIONS:
+ continue
+
+ try:
+ with open(p) as f:
+ lines = f.readlines()
+ except UnicodeDecodeError:
+ print(f"File with invalid encoding: {p}, skipping", file=sys.stderr)
+ continue
+
+ content = ""
+ migrate = False
+ for line in lines:
+ m = re.match(r"^(.*)#include <(.*\.h)>(.*)$", line)
+ if (
+ m
+ and not m.group(2).startswith("zephyr/")
+ and (ZEPHYR_BASE / "include" / "zephyr" / m.group(2)).exists()
+ ):
+ content += (
+ m.group(1)
+ + "#include <zephyr/"
+ + m.group(2)
+ + ">"
+ + m.group(3)
+ + "\n"
+ )
+ migrate = True
+ else:
+ content += line
+
+ if migrate:
+ print(f"Updating {p}{' (dry run)' if dry_run else ''}")
+ if not dry_run:
+ with open(p, "w") as f:
+ f.write(content)
+
+
+if __name__ == "__main__":
+ parser = argparse.ArgumentParser()
+ parser.add_argument(
+ "-p", "--project", type=Path, required=True, help="Zephyr-based project path"
+ )
+ parser.add_argument("--dry-run", action="store_true", help="Dry run")
+ args = parser.parse_args()
+
+ update_includes(args.project, args.dry_run)