Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Alternate asset catalog icon #2291

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions apple/internal/ios_rules.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -348,13 +348,16 @@ def _ios_application_impl(ctx):
),
partials.resources_partial(
actions = actions,
alternate_app_icon_names = ctx.attr.alternate_app_icon_names,
app_icon_name = ctx.attr.app_icon_name,
apple_mac_toolchain_info = apple_mac_toolchain_info,
bundle_extension = bundle_extension,
bundle_id = bundle_id,
bundle_name = bundle_name,
executable_name = executable_name,
bundle_verification_targets = bundle_verification_targets,
environment_plist = ctx.file._environment_plist,
include_all_appicons = ctx.attr.include_all_appicons,
launch_storyboard = ctx.file.launch_storyboard,
platform_prerequisites = platform_prerequisites,
resource_deps = resource_deps,
Expand Down
15 changes: 15 additions & 0 deletions apple/internal/partials/resources.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -169,11 +169,14 @@ def _locales_excluded(*, config_vars):
def _resources_partial_impl(
*,
actions,
alternate_app_icon_names,
app_icon_name,
apple_mac_toolchain_info,
bundle_extension,
bundle_id,
bundle_name,
executable_name,
include_all_appicons,
include_executable_name,
bundle_verification_targets,
environment_plist,
Expand Down Expand Up @@ -279,9 +282,12 @@ def _resources_partial_impl(

processing_args = {
"actions": actions,
"alternate_app_icon_names": alternate_app_icon_names,
"app_icon_name": app_icon_name,
"apple_mac_toolchain_info": apple_mac_toolchain_info,
"bundle_id": bundle_id,
"files": files,
"include_all_appicons": include_all_appicons,
"output_discriminator": output_discriminator,
"parent_dir": parent_dir,
"platform_prerequisites": platform_prerequisites,
Expand Down Expand Up @@ -374,11 +380,14 @@ def _resources_partial_impl(
def resources_partial(
*,
actions,
alternate_app_icon_names = [],
app_icon_name = None,
apple_mac_toolchain_info,
bundle_extension,
bundle_id = None,
bundle_name,
executable_name,
include_all_appicons = False,
include_executable_name = True,
bundle_verification_targets = [],
environment_plist,
Expand Down Expand Up @@ -408,6 +417,8 @@ def resources_partial(
occur.
bundle_name: The name of the output bundle.
executable_name: The name of the output executable.
alternate_app_icon_names: A list of alternate app icon names to use.
app_icon_name: The name of the app icon to use. Use This name if you have multiple appiconset in your xcassets.
include_executable_name: If True, the executable name will be added to
the plist in the `CFBundleExecutable` key. This is mainly intended for
plists embedded in a command line tool which don't need this value.
Expand All @@ -420,6 +431,7 @@ def resources_partial(
correctly configured.
environment_plist: File referencing a plist with the required variables about the versions
the target is being built for and with.
include_all_appicons: If True, all app icons will be included in the bundle.
launch_storyboard: A file to be used as a launch screen for the application.
output_discriminator: A string to differentiate between different target intermediate files
or `None`.
Expand All @@ -443,11 +455,14 @@ def resources_partial(
return partial.make(
_resources_partial_impl,
actions = actions,
alternate_app_icon_names = alternate_app_icon_names,
app_icon_name = app_icon_name,
apple_mac_toolchain_info = apple_mac_toolchain_info,
bundle_extension = bundle_extension,
bundle_id = bundle_id,
bundle_name = bundle_name,
executable_name = executable_name,
include_all_appicons = include_all_appicons,
include_executable_name = include_executable_name,
bundle_verification_targets = bundle_verification_targets,
environment_plist = environment_plist,
Expand Down
6 changes: 6 additions & 0 deletions apple/internal/partials/support/resources_support.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -143,9 +143,12 @@ def _compile_mappingmodels(
def _asset_catalogs(
*,
actions,
alternate_app_icon_names,
app_icon_name,
apple_mac_toolchain_info,
bundle_id,
files,
include_all_appicons,
output_discriminator,
parent_dir,
platform_prerequisites,
Expand Down Expand Up @@ -204,9 +207,12 @@ def _asset_catalogs(

resource_actions.compile_asset_catalog(
actions = actions,
alternate_app_icon_names = alternate_app_icon_names,
alternate_icons = alternate_icons,
app_icon_name = app_icon_name,
asset_files = asset_files,
bundle_id = bundle_id,
include_all_appicons = include_all_appicons,
output_dir = assets_dir,
output_plist = assets_plist,
platform_prerequisites = platform_prerequisites,
Expand Down
55 changes: 49 additions & 6 deletions apple/internal/resource_actions/actool.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ load(

def _actool_args_for_special_file_types(
*,
alternate_app_icon_names,
app_icon_name,
asset_files,
bundle_id,
platform_prerequisites,
Expand Down Expand Up @@ -121,15 +123,45 @@ def _actool_args_for_special_file_types(
[appicon_extension],
attr = "app_icons",
).keys()
if len(icon_dirs) != 1:
formatted_dirs = "[\n %s\n]" % ",\n ".join(icon_dirs)
fail("The asset catalogs should contain exactly one directory named " +
"*.%s among its asset catalogs, " % appicon_extension +
"but found the following: " + formatted_dirs, "app_icons")

app_icon_name = paths.split_extension(paths.basename(icon_dirs[0]))[0]
icon_dir = ""

# if app_icon_name is specified by user, instead of guarding the number of appiconset, we will search from multiple appiconset
if app_icon_name and len(app_icon_name) > 0 :
_icon_dirs = [d for d in icon_dirs if paths.basename(d) == app_icon_name + ".appiconset"]

if len(_icon_dirs) != 1:
fail("could not find " + app_icon_name + ".appiconset")

icon_dir = _icon_dirs[0]
else:
if len(icon_dirs) != 1:
formatted_dirs = "[\n %s\n]" % ",\n ".join(icon_dirs)
fail("The asset catalogs should contain exactly one directory named " +
"*.%s among its asset catalogs, " % appicon_extension +
"but found the following: " + formatted_dirs, "app_icons")

icon_dir = icon_dirs[0]

app_icon_name = paths.split_extension(paths.basename(icon_dir))[0]
args += ["--app-icon", app_icon_name]

# Add arguments for alternate app icons, if there are any.
for alternate_app_icon_name in alternate_app_icon_names:
_icon_dirs = [d for d in icon_dirs if paths.basename(d) == alternate_app_icon_name + ".appiconset"]

if len(_icon_dirs) == 0:
fail("could not find alternate app icon " + app_icon_name + ".appiconset")
elif len(_icon_dirs) > 1:
fail("found multiple alternate app icon " + app_icon_name + ".appiconset")

app_icon_name = paths.split_extension(paths.basename(_icon_dirs[0]))[0]

args.extend([
"--alternate-app-icon",
app_icon_name
])

# Add arguments for watch extension complication, if there is one.
complication_files = [f for f in asset_files if ".complicationset/" in f.path]
if product_type == apple_product_type.watch2_extension and complication_files:
Expand Down Expand Up @@ -183,9 +215,12 @@ def _alticonstool_args(
def compile_asset_catalog(
*,
actions,
alternate_app_icon_names,
alternate_icons,
app_icon_name,
asset_files,
bundle_id,
include_all_appicons,
output_dir,
output_plist,
platform_prerequisites,
Expand All @@ -202,13 +237,16 @@ def compile_asset_catalog(

Args:
actions: The actions provider from `ctx.actions`.
alternate_app_icon_names: The alternate app icon names to use.
alternate_icons: Alternate icons files, organized in .alticon directories.
app_icon_name: The name of the app icon to use. Set this if you have multiple appiconset.
asset_files: An iterable of files in all asset catalogs that should be
packaged as part of this catalog. This should include transitive
dependencies (i.e., assets not just from the application target, but
from any other library targets it depends on) as well as resources like
app icons and launch images.
bundle_id: The bundle ID to configure for this target.
include_all_appicons: Whether to include all app icons.
output_dir: The directory where the compiled outputs should be placed.
output_plist: The file reference for the output plist that should be merged
into Info.plist. May be None if the output plist is not desired.
Expand All @@ -233,6 +271,8 @@ def compile_asset_catalog(
]

args.extend(_actool_args_for_special_file_types(
alternate_app_icon_names = alternate_app_icon_names,
app_icon_name = app_icon_name,
asset_files = asset_files,
bundle_id = bundle_id,
platform_prerequisites = platform_prerequisites,
Expand Down Expand Up @@ -264,6 +304,9 @@ def compile_asset_catalog(
xctoolrunner.prefixed_path(actool_output_plist.path),
])

if include_all_appicons:
args.extend(["--include-all-app-icons"])

xcassets = group_files_by_directory(
asset_files,
["xcassets", "xcstickers"],
Expand Down
16 changes: 16 additions & 0 deletions apple/internal/rule_attrs.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -662,6 +662,18 @@ def _app_icon_attrs(*, icon_extension = ".appiconset", icon_parent_extension = "
of the directory containing the app icon assets. Optional. Defaults to `.xcassets`.
"""
return {
"alternate_app_icon_names": attr.string_list(
default = [],
doc = """
List of names of alternate app icons to use for this target.
This is the name of the directory of `{icon_extension}` without the extension.""".format(icon_extension = icon_extension)
),
"app_icon_name": attr.string(
default = "",
doc = """
The name of the app icon to use for this target.
This is the name of the directory of `{icon_extension}` without the extension""".format(icon_extension = icon_extension)
),
"app_icons": attr.label_list(
allow_files = True,
doc = """
Expand All @@ -672,6 +684,10 @@ named `*.{app_icon_parent_extension}/*.{app_icon_extension}` and there may be on
app_icon_parent_extension = icon_parent_extension,
),
),
"include_all_appicons": attr.bool(
default = False,
doc = "Indicates if actool should include all `appiconset`. You should enable this to use `alternate_app_icons`",
),
}

def _launch_images_attrs():
Expand Down
10 changes: 6 additions & 4 deletions doc/rules-ios.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,10 @@ Builds and bundles an iOS App Clip.
## ios_application

<pre>
ios_application(<a href="#ios_application-name">name</a>, <a href="#ios_application-deps">deps</a>, <a href="#ios_application-resources">resources</a>, <a href="#ios_application-additional_linker_inputs">additional_linker_inputs</a>, <a href="#ios_application-alternate_icons">alternate_icons</a>, <a href="#ios_application-app_clips">app_clips</a>,
<a href="#ios_application-app_icons">app_icons</a>, <a href="#ios_application-app_intents">app_intents</a>, <a href="#ios_application-bundle_id">bundle_id</a>, <a href="#ios_application-bundle_id_suffix">bundle_id_suffix</a>, <a href="#ios_application-bundle_name">bundle_name</a>, <a href="#ios_application-codesign_inputs">codesign_inputs</a>,
ios_application(<a href="#ios_application-name">name</a>, <a href="#ios_application-deps">deps</a>, <a href="#ios_application-resources">resources</a>, <a href="#ios_application-additional_linker_inputs">additional_linker_inputs</a>, <a href="#ios_application-alternate_app_icon_names">alternate_app_icon_names</a>, <a href="#ios_application-alternate_icons">alternate_icons</a>, <a href="#ios_application-app_clips">app_clips</a>,
<a href="#ios_application-app_icon_name">app_icon_name</a>, <a href="#ios_application-app_icons">app_icons</a>, <a href="#ios_application-app_intents">app_intents</a>, <a href="#ios_application-bundle_id">bundle_id</a>, <a href="#ios_application-bundle_id_suffix">bundle_id_suffix</a>, <a href="#ios_application-bundle_name">bundle_name</a>, <a href="#ios_application-codesign_inputs">codesign_inputs</a>,
<a href="#ios_application-codesignopts">codesignopts</a>, <a href="#ios_application-entitlements">entitlements</a>, <a href="#ios_application-entitlements_validation">entitlements_validation</a>, <a href="#ios_application-executable_name">executable_name</a>,
<a href="#ios_application-exported_symbols_lists">exported_symbols_lists</a>, <a href="#ios_application-extensions">extensions</a>, <a href="#ios_application-families">families</a>, <a href="#ios_application-frameworks">frameworks</a>, <a href="#ios_application-include_symbols_in_bundle">include_symbols_in_bundle</a>,
<a href="#ios_application-exported_symbols_lists">exported_symbols_lists</a>, <a href="#ios_application-extensions">extensions</a>, <a href="#ios_application-families">families</a>, <a href="#ios_application-frameworks">frameworks</a>, <a href="#ios_application-include_all_appicons">include_all_appicons</a>, <a href="#ios_application-include_symbols_in_bundle">include_symbols_in_bundle</a>,
<a href="#ios_application-infoplists">infoplists</a>, <a href="#ios_application-ipa_post_processor">ipa_post_processor</a>, <a href="#ios_application-launch_images">launch_images</a>, <a href="#ios_application-launch_storyboard">launch_storyboard</a>, <a href="#ios_application-linkopts">linkopts</a>,
<a href="#ios_application-minimum_deployment_os_version">minimum_deployment_os_version</a>, <a href="#ios_application-minimum_os_version">minimum_os_version</a>, <a href="#ios_application-platform_type">platform_type</a>,
<a href="#ios_application-provisioning_profile">provisioning_profile</a>, <a href="#ios_application-sdk_frameworks">sdk_frameworks</a>, <a href="#ios_application-settings_bundle">settings_bundle</a>, <a href="#ios_application-shared_capabilities">shared_capabilities</a>, <a href="#ios_application-stamp">stamp</a>,
Expand All @@ -71,15 +71,16 @@ Builds and bundles an iOS Application.

**ATTRIBUTES**


| Name | Description | Type | Mandatory | Default |
| :------------- | :------------- | :------------- | :------------- | :------------- |
| <a id="ios_application-name"></a>name | A unique name for this target. | <a href="https://bazel.build/concepts/labels#target-names">Name</a> | required | |
| <a id="ios_application-deps"></a>deps | A list of dependent targets that will be linked into this target's binary(s). Any resources, such as asset catalogs, that are referenced by those targets will also be transitively included in the final bundle(s). | <a href="https://bazel.build/concepts/labels">List of labels</a> | optional | `[]` |
| <a id="ios_application-resources"></a>resources | A list of resources or files bundled with the bundle. The resources will be stored in the appropriate resources location within the bundle. | <a href="https://bazel.build/concepts/labels">List of labels</a> | optional | `[]` |
| <a id="ios_application-additional_linker_inputs"></a>additional_linker_inputs | A list of input files to be passed to the linker. | <a href="https://bazel.build/concepts/labels">List of labels</a> | optional | `[]` |
| <a id="ios_application-alternate_icons"></a>alternate_icons | Files that comprise the alternate app icons for the application. Each file must have a containing directory named after the alternate icon identifier. | <a href="https://bazel.build/concepts/labels">List of labels</a> | optional | `[]` |
| <a id="ios_application-alternate_app_icon_names"></a>alternate_app_icon_names | A list of appiconset name. The appiconset name must be exist inside xcassets <code>app_icons</vode>. | List of strings | optional | <code>[]</code> |
| <a id="ios_application-app_clips"></a>app_clips | A list of iOS app clips to include in the final application bundle. | <a href="https://bazel.build/concepts/labels">List of labels</a> | optional | `[]` |
| <a id="ios_application-app_icon_name"></a>app_icon_name | Only set this, if you use <code>alternate_app_icon_names</code>. | String | optional | <code>""</code> |
| <a id="ios_application-app_icons"></a>app_icons | Files that comprise the app icons for the application. Each file must have a containing directory named `*..xcassets/*..appiconset` and there may be only one such `..appiconset` directory in the list. | <a href="https://bazel.build/concepts/labels">List of labels</a> | optional | `[]` |
| <a id="ios_application-app_intents"></a>app_intents | List of dependencies implementing the AppIntents protocol. | <a href="https://bazel.build/concepts/labels">List of labels</a> | optional | `[]` |
| <a id="ios_application-bundle_id"></a>bundle_id | The bundle ID (reverse-DNS path followed by app name) for this target. Only use this attribute if the bundle ID is not intended to be composed through an assigned base bundle ID rule found within `signed_capabilities`. | String | optional | `""` |
Expand All @@ -94,6 +95,7 @@ Builds and bundles an iOS Application.
| <a id="ios_application-extensions"></a>extensions | A list of iOS application extensions to include in the final application bundle. | <a href="https://bazel.build/concepts/labels">List of labels</a> | optional | `[]` |
| <a id="ios_application-families"></a>families | A list of device families supported by this extension. Valid values are `iphone` and `ipad`; at least one must be specified. | List of strings | required | |
| <a id="ios_application-frameworks"></a>frameworks | A list of framework targets (see [`ios_framework`](https://github.com/bazelbuild/rules_apple/blob/master/doc/rules-ios.md#ios_framework)) that this target depends on. | <a href="https://bazel.build/concepts/labels">List of labels</a> | optional | `[]` |
| <a id="ios_application-include_all_appicons"></a>include_all_appicons | Set True to pass <code>--include-all-app-icons</code> to actool. You should enable this if you use <code>alternate_app_icon_names</code> | Boolean | optional | <code>False</code> |
| <a id="ios_application-include_symbols_in_bundle"></a>include_symbols_in_bundle | If true and --output_groups=+dsyms is specified, generates `$UUID.symbols` files from all `{binary: .dSYM, ...}` pairs for the application and its dependencies, then packages them under the `Symbols/` directory in the final application bundle. | Boolean | optional | `False` |
| <a id="ios_application-infoplists"></a>infoplists | A list of .plist files that will be merged to form the Info.plist for this target. At least one file must be specified. Please see [Info.plist Handling](https://github.com/bazelbuild/rules_apple/blob/master/doc/common_info.md#infoplist-handling) for what is supported. | <a href="https://bazel.build/concepts/labels">List of labels</a> | required | |
| <a id="ios_application-ipa_post_processor"></a>ipa_post_processor | A tool that edits this target's archive after it is assembled but before it is signed. The tool is invoked with a single command-line argument that denotes the path to a directory containing the unzipped contents of the archive; this target's bundle will be the directory's only contents.<br><br>Any changes made by the tool must be made in this directory, and the tool's execution must be hermetic given these inputs to ensure that the result can be safely cached. | <a href="https://bazel.build/concepts/labels">Label</a> | optional | `None` |
Expand Down