diff --git a/README.md b/README.md index e982aea..b7c6191 100644 --- a/README.md +++ b/README.md @@ -37,12 +37,12 @@ repo: # `repo sync` — `repo` merges every *.xml in that directory into the manifest # (adding projects, removing projects, overriding revisions, etc). # - # Each value is either: - # - a single URL string -> downloaded as-is to ".xml" - # - a YAML list of URLs -> all downloaded and merged into one ".xml", - # combining child elements and de-duplicating ones that share the same - # tag + name attribute (first occurrence wins). Handy for splitting a - # long list across a common file and a device-specific one. + # Every key's value is normally a single URL string, downloaded as-is to + # ".xml". The "remove_projects" key is the one exception: it may instead + # be a YAML list of URLs, all downloaded and merged into one "remove_projects.xml", + # combining child elements and de-duplicating ones that share the same tag + + # name attribute (first occurrence wins). Handy for splitting a long + # list across a common file and a device-specific one. local_manifests: device_manifest: "https://raw.githubusercontent.com/example/device-manifest/main/manifest.xml" vendor_manifest: "https://raw.githubusercontent.com/example/vendor-manifest/main/manifest.xml" @@ -60,10 +60,22 @@ patches: - patches # Optional: maps a patch subdirectory to a different AOSP project path, for - # layouts that don't/shouldn't mirror the AOSP tree directly (e.g. grouping - # patches by Android version instead of by project path). + # layouts that don't/shouldn't mirror the AOSP tree directly. Two forms: + # + # - Exact match -> replace the whole subdir: every patch found under it + # applies to the one given project. + # android/36: frameworks/base + # patches/android/36/*.patch -> applied at frameworks/base/ + # + # - Prefix match (map to "") -> strip the matched prefix and use the rest + # of the path as-is. Lets you group patches by Android version while + # still targeting multiple different AOSP projects underneath: + # android/37: "" + # patches/android/37/frameworks/base/*.patch -> applied at frameworks/base/ + # patches/android/37/packages/apps/Settings/*.patch -> applied at packages/apps/Settings/ mappings: android/36: frameworks/base + android/37: "" ``` ### Command Line Options diff --git a/environ.py b/environ.py index 9c7010d..9d7863d 100755 --- a/environ.py +++ b/environ.py @@ -212,18 +212,30 @@ def find_patches(patch_dirs, mappings=None): Returns a list of (patch_path, target_subdir) tuples where target_subdir is the AOSP project path the patch should be applied into. - mappings (optional dict) translates patch subdirectory paths to AOSP paths, - e.g. {"android/36": "frameworks/base"}. Without a mapping the subdirectory - structure must mirror the AOSP project layout directly: + mappings (optional dict) translates patch subdirectory paths to AOSP paths. + Without a mapping the subdirectory structure must mirror the AOSP project + layout directly: patches/ frameworks/base/0001-sig-spoof.patch -> /frameworks/base/ 0001-root-level.patch -> / - With mappings from repo.yml: + A mapping key can match a subdirectory path exactly: + + mappings: {"android/36": "frameworks/base"} patches/ - android/36/android_frameworks_base-*.patch -> /frameworks/base/ + android/36/*.patch -> /frameworks/base/ (all patches in this dir go to one project) + + Or match as a *prefix*, stripping it and using the rest of the path as-is + (map to "" to strip with no replacement) - handy for grouping patches by + Android version while still targeting multiple different AOSP projects: + + mappings: {"android/36": ""} + + patches/ + android/36/frameworks/base/0001-sig-spoof.patch -> /frameworks/base/ + android/36/packages/apps/Settings/0001-toggle.patch -> /packages/apps/Settings/ """ if mappings is None: mappings = {} @@ -250,9 +262,17 @@ def find_patches(patch_dirs, mappings=None): rel_str = str(rel_parent).replace("\\", "/") # normalise on Windows target_subdir = rel_str if rel_str != "." else "." - # Apply mapping if one is configured for this subdirectory + # Apply mapping if one is configured for this subdirectory: exact + # match first, then fall back to a prefix match (e.g. a version + # folder like "android/36" containing multiple AOSP project paths). if target_subdir in mappings: target_subdir = mappings[target_subdir] + else: + for prefix, replacement in mappings.items(): + if target_subdir.startswith(prefix + "/"): + remainder = target_subdir[len(prefix) + 1:] + target_subdir = f"{replacement}/{remainder}" if replacement else remainder + break patches.append((patch_file, target_subdir)) diff --git a/example.repo.yml b/example.repo.yml index 511e8b6..6e930d8 100644 --- a/example.repo.yml +++ b/example.repo.yml @@ -17,12 +17,12 @@ repo: # `repo` reads every *.xml file in that directory and layers them on top of # the upstream manifest (adding projects, removing projects, overriding revisions). # - # Each value is either: - # - a single URL string -> downloaded as-is to ".xml" - # - a YAML list of URLs -> all downloaded and merged into one ".xml", - # combining their child elements and de-duplicating entries that share the - # same tag + name attribute (first occurrence wins). Useful for splitting a - # long list across a common file and a device-specific one. + # Every key's value is normally a single URL string, downloaded as-is to + # ".xml". The "remove_projects" key is the one exception: it may instead + # be a YAML list of URLs, all downloaded and merged into one "remove_projects.xml", + # combining their child elements and de-duplicating entries that share the + # same tag + name attribute (first occurrence wins). Useful for splitting a + # long list across a common file and a device-specific one. local_manifests: # Adds PawletOS's own repo/project definitions common to all devices. manifest_common_pawletos: "https://git.oxmc.me/PawletOS/android_local_manifest/raw/branch/android-16.0/common/pawletos.xml" @@ -51,8 +51,17 @@ patches: dirs: - vendor/pawlet/patches - # Optional: maps a patch subdirectory name to a different AOSP project path, - # for cases where the patch directory layout can't/shouldn't mirror the AOSP - # tree directly (e.g. grouping patches by Android version instead). + # Optional: maps a patch subdirectory to a different AOSP project path, for + # layouts that don't/shouldn't mirror the AOSP tree directly. Two forms: + # - Exact match -> replace the whole subdir; every patch under it applies + # to the one given project: + # android/36: frameworks/base + # - Prefix match (map to "") -> strip the matched prefix and use the rest + # of the path as-is; groups patches by Android version while still + # targeting multiple different AOSP projects underneath: + # android/37: "" + # vendor/pawlet/patches/android/37/frameworks/base/*.patch -> frameworks/base/ + # vendor/pawlet/patches/android/37/packages/apps/Settings/*.patch -> packages/apps/Settings/ # mappings: # android/36: frameworks/base + # android/37: ""