diff --git a/apple/internal/aspects/resource_aspect.bzl b/apple/internal/aspects/resource_aspect.bzl index cefa971ea0..41f7597da2 100644 --- a/apple/internal/aspects/resource_aspect.bzl +++ b/apple/internal/aspects/resource_aspect.bzl @@ -286,15 +286,15 @@ def _apple_resource_aspect_impl(target, ctx): **collect_structured_args ) if structured_files: - if bundle_name: - structured_parent_dir_param = partial.make( - resources.structured_resources_parent_dir, - parent_dir = bundle_name, - ) - else: - structured_parent_dir_param = partial.make( - resources.structured_resources_parent_dir, - ) + structured_parent_dir_param = partial.make( + resources.structured_resources_parent_dir, + parent_dir = bundle_name, + strip_prefixes = getattr( + ctx.rule.attr, + "strip_structured_resources_prefixes", + [], + ), + ) # Avoid processing PNG files that are referenced through the structured_resources # attribute. This is mostly for legacy reasons and should get cleaned up in the future. diff --git a/apple/internal/resource_rules/apple_precompiled_resource_bundle.bzl b/apple/internal/resource_rules/apple_precompiled_resource_bundle.bzl index 723fda8fd7..6d67eb217b 100644 --- a/apple/internal/resource_rules/apple_precompiled_resource_bundle.bzl +++ b/apple/internal/resource_rules/apple_precompiled_resource_bundle.bzl @@ -146,6 +146,11 @@ def _apple_precompiled_resource_bundle_impl(ctx): structured_parent_dir_param = partial.make( resources.structured_resources_parent_dir, parent_dir = bundle_name, + strip_prefixes = getattr( + ctx.attr, + "strip_structured_resources_prefixes", + [], + ), ) # Avoid processing PNG files that are referenced through the structured_resources @@ -265,6 +270,19 @@ they will be placed in a directory of the same name in the app bundle. You can also add other `apple_precompiled_resource_bundle` and `apple_bundle_import` targets into `resources`, and the resource bundle structures will be propagated into the final bundle. +""", + ), + "strip_structured_resources_prefixes": attr.string_list( + doc = """ +A list of prefixes to strip from the paths of structured resources. For each +structured resource, if the path starts with one of these prefixes, the first +matching prefix will be removed from the path when the resource is placed in +the bundle root. This is useful for removing intermediate directories from the +resource paths. + +For example, if `structured_resources` contains `["intermediate/res/foo.png"]`, +and `strip_structured_resources_prefixes` contains `["intermediate"]`, +`res/foo.png` will end up inside the bundle. """, ), "structured_resources": attr.label_list( diff --git a/apple/internal/resource_rules/apple_resource_bundle.bzl b/apple/internal/resource_rules/apple_resource_bundle.bzl index d9d0549df8..b3a31498c1 100644 --- a/apple/internal/resource_rules/apple_resource_bundle.bzl +++ b/apple/internal/resource_rules/apple_resource_bundle.bzl @@ -80,6 +80,19 @@ they will be placed in a directory of the same name in the app bundle. You can also add other `apple_resource_bundle` and `apple_bundle_import` targets into `resources`, and the resource bundle structures will be propagated into the final bundle. +""", + ), + "strip_structured_resources_prefixes": attr.string_list( + doc = """ +A list of prefixes to strip from the paths of structured resources. For each +structured resource, if the path starts with one of these prefixes, the first +matching prefix will be removed from the path when the resource is placed in +the bundle root. This is useful for removing intermediate directories from the +resource paths. + +For example, if `structured_resources` contains `["intermediate/res/foo.png"]`, +and `strip_structured_resources_prefixes` contains `["intermediate"]`, +`res/foo.png` will end up inside the bundle. """, ), "structured_resources": attr.label_list( diff --git a/apple/internal/resource_rules/apple_resource_group.bzl b/apple/internal/resource_rules/apple_resource_group.bzl index 59b7169dc5..9eed9df51d 100644 --- a/apple/internal/resource_rules/apple_resource_group.bzl +++ b/apple/internal/resource_rules/apple_resource_group.bzl @@ -37,6 +37,19 @@ directory called *.lproj), they will be placed in a directory of the same name i You can also add apple_resource_bundle and apple_bundle_import targets into `resources`, and the resource bundle structures will be propagated into the final bundle. +""", + ), + "strip_structured_resources_prefixes": attr.string_list( + doc = """ +A list of prefixes to strip from the paths of structured resources. For each +structured resource, if the path starts with one of these prefixes, the first +matching prefix will be removed from the path when the resource is placed in +the bundle root. This is useful for removing intermediate directories from the +resource paths. + +For example, if `structured_resources` contains `["intermediate/res/foo.png"]`, +and `strip_structured_resources_prefixes` contains `["intermediate"]`, +`res/foo.png` will end up inside the bundle. """, ), "structured_resources": attr.label_list( diff --git a/apple/internal/resources.bzl b/apple/internal/resources.bzl index a9e9ac57a6..368ba89749 100644 --- a/apple/internal/resources.bzl +++ b/apple/internal/resources.bzl @@ -786,12 +786,18 @@ def _populated_resource_fields(provider): if f not in ["owners", "unowned_resources", "processed_origins", "to_json", "to_proto"] ] -def _structured_resources_parent_dir(*, parent_dir = None, resource): +def _structured_resources_parent_dir( + *, + parent_dir = None, + resource, + strip_prefixes = []): """Returns the package relative path for the parent directory of a resource. Args: parent_dir: Parent directory to prepend to the package relative path. resource: The resource for which to calculate the package relative path. + strip_prefixes: A list of prefixes to strip from the package relative + path. The first prefix that matches will be used. Returns: The package relative path to the parent directory of the resource. @@ -801,6 +807,12 @@ def _structured_resources_parent_dir(*, parent_dir = None, resource): path = package_relative else: path = paths.dirname(package_relative).rstrip("/") + + for prefix in strip_prefixes: + if path.startswith(prefix): + path = path[(len(prefix) + 1):] + break + return paths.join(parent_dir or "", path or "") or None def _runfiles_resources_parent_dir(*, resource): diff --git a/doc/rules-resources.md b/doc/rules-resources.md index 8473a11644..622d00f723 100644 --- a/doc/rules-resources.md +++ b/doc/rules-resources.md @@ -106,7 +106,7 @@ Compiles Metal shader language sources into a Metal library.
apple_precompiled_resource_bundle(name, resources, bundle_id, bundle_name, infoplists, - structured_resources) + strip_structured_resources_prefixes, structured_resources)This rule encapsulates a target which is provided to dependers as a bundle. An @@ -124,6 +124,7 @@ library targets through the `data` attribute. | bundle_id | The bundle ID for this target. It will replace `$(PRODUCT_BUNDLE_IDENTIFIER)` found in the files from defined in the `infoplists` paramter. | String | optional | `""` | | bundle_name | The desired name of the bundle (without the `.bundle` extension). If this attribute is not set, then the `name` of the target will be used instead. | String | optional | `""` | | infoplists | A list of `.plist` files that will be merged to form the `Info.plist` that represents the extension. At least one file must be specified. Please see [Info.plist Handling](/doc/common_info.md#infoplist-handling") for what is supported.
-apple_resource_bundle(name, resources, bundle_id, bundle_name, infoplists, structured_resources) +apple_resource_bundle(name, resources, bundle_id, bundle_name, infoplists, + strip_structured_resources_prefixes, structured_resources)This rule encapsulates a target which is provided to dependers as a bundle. An @@ -150,6 +152,7 @@ library targets through the `data` attribute. | bundle_id | The bundle ID for this target. It will replace `$(PRODUCT_BUNDLE_IDENTIFIER)` found in the files from defined in the `infoplists` paramter. | String | optional | `""` | | bundle_name | The desired name of the bundle (without the `.bundle` extension). If this attribute is not set, then the `name` of the target will be used instead. | String | optional | `""` | | infoplists | A list of `.plist` files that will be merged to form the `Info.plist` that represents the extension. At least one file must be specified. Please see [Info.plist Handling](/doc/common_info.md#infoplist-handling") for what is supported.
-apple_resource_group(name, resources, structured_resources) +apple_resource_group(name, resources, strip_structured_resources_prefixes, structured_resources)This rule encapsulates a target which provides resources to dependents. An @@ -175,6 +178,7 @@ to library targets through the `data` attribute, or to other | :------------- | :------------- | :------------- | :------------- | :------------- | | name | A unique name for this target. | Name | required | | | resources | Files to include in the final bundle that depends on this target. Files that are processable resources, like .xib, .storyboard, .strings, .png, and others, will be processed by the Apple bundling rules that have those files as dependencies. Other file types that are not processed will be copied verbatim. These files are placed in the root of the final bundle (e.g. Payload/foo.app/...) in most cases. However, if they appear to be localized (i.e. are contained in a directory called *.lproj), they will be placed in a directory of the same name in the app bundle.
-resources_common.structured_resources_parent_dir(parent_dir, resource) +resources_common.structured_resources_parent_dir(parent_dir, resource, strip_prefixes)Returns the package relative path for the parent directory of a resource. @@ -619,6 +623,7 @@ Returns the package relative path for the parent directory of a resource. | :------------- | :------------- | :------------- | | parent_dir | Parent directory to prepend to the package relative path. | `None` | | resource | The resource for which to calculate the package relative path. | none | +| strip_prefixes | A list of prefixes to strip from the package relative path. The first prefix that matches will be used. | `[]` | **RETURNS**