Skip to content

Create xcodeproj_extra_files aspect hint #3150

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

Open
wants to merge 4 commits into
base: main
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
7 changes: 6 additions & 1 deletion docs/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ load("@io_bazel_stardoc//stardoc:stardoc.bzl", "stardoc")
# Generating

_DOC_COMPONENTS = [
"aspect_hints",
"project_options",
"providers",
"top_level_target",
Expand All @@ -20,7 +21,10 @@ _DOC_COMPONENTS = [
out = "{}.md".format(component),
input = "//xcodeproj/internal/docs:{}.bzl".format(component),
tags = ["manual"],
deps = ["//xcodeproj/internal"],
deps = [
"//xcodeproj",
"//xcodeproj/internal",
],
)
for component in _DOC_COMPONENTS
]
Expand All @@ -36,6 +40,7 @@ genrule(
":xcode_schemes",
":xcode_build_settings",
":providers",
":aspect_hints",
],
outs = ["bazel.generated.md"],
cmd = """\
Expand Down
48 changes: 48 additions & 0 deletions docs/bazel.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ load("@rules_xcodeproj//xcodeproj:defs.bzl", "xcodeproj")
- [Providers](#providers)
- [`XcodeProjAutomaticTargetProcessingInfo`](#XcodeProjAutomaticTargetProcessingInfo)
- [`XcodeProjInfo`](#XcodeProjInfo)
- [Aspect Hints](#aspect-hints)
- [`xcodeproj_extra_files`](#xcodeproj_extra_files)

# Core

Expand Down Expand Up @@ -1095,3 +1097,49 @@ Provides information needed to generate an Xcode project.
| <a id="XcodeProjInfo-xcode_targets"></a>xcode_targets | A `depset` of values from `xcode_targets.make`, which potentially will become targets in the Xcode project. |


# Aspect Hints

Aspect hints that can be used to provide additional information during project generation.

<a id="xcodeproj_extra_files"></a>

## xcodeproj_extra_files

<pre>
xcodeproj_extra_files(<a href="#xcodeproj_extra_files-name">name</a>, <a href="#xcodeproj_extra_files-files">files</a>)
</pre>

This rule is used to surface extra files that should be included in the Xcode
project navigator, but otherwise aren't inputs to a target. The provider
created by this rule should be attached to the related target via an aspect
hint.

This is only used when xcodeproj.generation_mode = "incremental" is set.

**EXAMPLE**

```starlark
load("@rules_xcodeproj//xcodeproj:xcodeproj_extra_files.bzl", "xcodeproj_extra_files")

swift_library(
...
aspect_hints = [":library_extra_files"],
...
)

# Display the README.md file located alongside the Swift library in Xcode
xcodeproj_extra_files(
name = "library_extra_files",
files = ["README.md"],
)
```

**ATTRIBUTES**


| Name | Description | Type | Mandatory | Default |
| :------------- | :------------- | :------------- | :------------- | :------------- |
| <a id="xcodeproj_extra_files-name"></a>name | A unique name for this target. | <a href="https://bazel.build/concepts/labels#target-names">Name</a> | required | |
| <a id="xcodeproj_extra_files-files"></a>files | The list of extra files to surface in the Xcode navigator. | <a href="https://bazel.build/concepts/labels">List of labels</a> | optional | `[]` |


2 changes: 2 additions & 0 deletions test/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ test_suite(
"//test/internal/target_id",
"//test/internal/targets",
"//test/internal/xcode_schemes",
"//test/internal/xcodeproj_extra_files",
"//test/internal/xcschemes",
],
)
Expand All @@ -31,6 +32,7 @@ bzl_library(
"//test/internal/target_id:bzls",
"//test/internal/targets:bzls",
"//test/internal/xcode_schemes:bzls",
"//test/internal/xcodeproj_extra_files:bzls",
"//test/internal/xcschemes:bzls",
],
)
Expand Down
15 changes: 15 additions & 0 deletions test/internal/xcodeproj_extra_files/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
load("@bazel_skylib//:bzl_library.bzl", "bzl_library")
load(":xcodeproj_extra_files_tests.bzl", "xcodeproj_extra_files_test_suite")

xcodeproj_extra_files_test_suite(name = "xcodeproj_extra_files_test")

test_suite(name = "xcodeproj_extra_files")

bzl_library(
name = "bzls",
srcs = glob(
["*.bzl"],
exclude = ["utils.bzl"],
),
visibility = ["//test:__pkg__"],
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
load("@bazel_skylib//lib:unittest.bzl", "analysistest", "asserts")
load("//xcodeproj:xcodeproj_extra_files.bzl", "xcodeproj_extra_files")
load("//xcodeproj/internal:providers.bzl", "XcodeProjExtraFilesHintInfo")

def _provider_contents_test_impl(ctx):
env = analysistest.begin(ctx)

target_under_test = analysistest.target_under_test(env)

files_list = target_under_test[XcodeProjExtraFilesHintInfo].files.to_list()

asserts.equals(env, len(files_list), 1)
asserts.equals(env, files_list[0].path, "test/internal/xcodeproj_extra_files/BUILD")

return analysistest.end(env)

provider_contents_test = analysistest.make(_provider_contents_test_impl)

def _test_provider_contents():
xcodeproj_extra_files(
name = "xcodeproj_extra_files_subject",
files = ["BUILD"],
tags = ["manual"],
)

provider_contents_test(
name = "provider_contents_test",
target_under_test = ":xcodeproj_extra_files_subject",
)

def xcodeproj_extra_files_test_suite(name):
_test_provider_contents()

native.test_suite(
name = name,
tests = [
":provider_contents_test",
],
)
8 changes: 8 additions & 0 deletions xcodeproj/internal/docs/aspect_hints.bzl
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
"""# Aspect Hints

Aspect hints that can be used to provide additional information during project generation.
"""

load("//xcodeproj:xcodeproj_extra_files.bzl", _xcodeproj_extra_files = "xcodeproj_extra_files")

xcodeproj_extra_files = _xcodeproj_extra_files
2 changes: 2 additions & 0 deletions xcodeproj/internal/docs/bazel.header.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,5 +50,7 @@ load("@rules_xcodeproj//xcodeproj:defs.bzl", "xcodeproj")
- [Providers](#providers)
- [`XcodeProjAutomaticTargetProcessingInfo`](#XcodeProjAutomaticTargetProcessingInfo)
- [`XcodeProjInfo`](#XcodeProjInfo)
- [Aspect Hints](#aspect-hints)
- [`xcodeproj_extra_files`](#xcodeproj_extra_files)

# Core
8 changes: 8 additions & 0 deletions xcodeproj/internal/files/incremental_input_files.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ load(
"EMPTY_LIST",
"memory_efficient_depset",
)
load("//xcodeproj/internal:providers.bzl", "XcodeProjExtraFilesHintInfo")
load("//xcodeproj/internal:xcodeprojinfo.bzl", "XcodeProjInfo")
load(":incremental_resources.bzl", resources_module = "incremental_resources")
load(":linker_input_files.bzl", "linker_input_files")
Expand Down Expand Up @@ -408,6 +409,13 @@ def _collect_incremental_input_files(
rule_files = ctx.rule.files,
)

# Collect any extra fila provided via the `xcodeproj_extra_files` aspect hint
for hint in rule_attr.aspect_hints:
if XcodeProjExtraFilesHintInfo in hint:
hint_extra_files = hint[XcodeProjExtraFilesHintInfo].files
if hint_extra_files:
extra_files.extend(hint_extra_files.to_list())

product_framework_files = memory_efficient_depset(
transitive = [
info.inputs._product_framework_files
Expand Down
7 changes: 7 additions & 0 deletions xcodeproj/internal/providers.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,10 @@ XcodeProjRunnerOutputInfo = provider(
"runner": "The xcodeproj runner.",
},
)

XcodeProjExtraFilesHintInfo = provider(
doc = "Provides a list of extra files to include during project generation",
fields = {
"files": "List of files to include in the extra files.",
},
)
50 changes: 50 additions & 0 deletions xcodeproj/xcodeproj_extra_files.bzl
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
"""Rule for providing extra files from targets to the project generator"""

load("//xcodeproj/internal:providers.bzl", "XcodeProjExtraFilesHintInfo")

def _xcodeproj_extra_files_impl(ctx):
"""Create a provider to surface extra files via an aspect hint.

Args:
ctx: The rule context.

Returns:
A `XcodeProjExtraFilesHintInfo` provider.
"""
return [XcodeProjExtraFilesHintInfo(files = depset(ctx.files.files))]

xcodeproj_extra_files = rule(
doc = """\
This rule is used to surface extra files that should be included in the Xcode
project navigator, but otherwise aren't inputs to a target. The provider
created by this rule should be attached to the related target via an aspect
hint.

This is only used when xcodeproj.generation_mode = "incremental" is set.

**EXAMPLE**

```starlark
load("@rules_xcodeproj//xcodeproj:xcodeproj_extra_files.bzl", "xcodeproj_extra_files")

swift_library(
...
aspect_hints = [":library_extra_files"],
...
)

# Display the README.md file located alongside the Swift library in Xcode
xcodeproj_extra_files(
name = "library_extra_files",
files = ["README.md"],
)
```
""",
implementation = _xcodeproj_extra_files_impl,
attrs = {
"files": attr.label_list(
doc = "The list of extra files to surface in the Xcode navigator.",
allow_files = True,
),
},
)