Skip to content

Commit c07c93e

Browse files
Ability to explicitly specify output files in apple_core_data_model rule (#2727)
This PR contains one of the two fixes mentioned in #2726. This change makes it possible to explicitly specify the output files that are expected to be generated from the provided core data models. This causes the rule to return a provider containing these individual Swift files rather than just the containing folder.
1 parent 765049b commit c07c93e

File tree

5 files changed

+72
-13
lines changed

5 files changed

+72
-13
lines changed

apple/internal/resource_actions/datamodel.bzl

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ def generate_datamodels(
109109
datamodel_path,
110110
input_files,
111111
output_dir,
112+
outputs,
112113
platform_prerequisites,
113114
xctoolrunner,
114115
swift_version = None):
@@ -119,6 +120,7 @@ def generate_datamodels(
119120
datamodel_path: The path to the directory containing the datamodels.
120121
input_files: The list of files to process for the given datamodel.
121122
output_dir: The output directory reference where generated datamodel classes will be.
123+
outputs: The list of generated datamodel files or the directory containing those files.
122124
platform_prerequisites: Struct containing information on the platform being targeted.
123125
xctoolrunner: A files_to_run for the wrapper around the "xcrun" tool.
124126
swift_version: (optional) Target Swift version for generated datamodel classes.
@@ -136,9 +138,9 @@ def generate_datamodels(
136138
args.add("--swift-version", swift_version)
137139

138140
args.add(xctoolrunner_support.prefixed_path(datamodel_path))
139-
args.add(xctoolrunner_support.prefixed_path(output_dir.path))
141+
args.add(xctoolrunner_support.prefixed_path(output_dir))
140142

141-
args.add("--xctoolrunner_assert_nonempty_dir", output_dir.path)
143+
args.add("--xctoolrunner_assert_nonempty_dir", output_dir)
142144

143145
apple_support.run(
144146
actions = actions,
@@ -147,6 +149,6 @@ def generate_datamodels(
147149
executable = xctoolrunner,
148150
inputs = input_files,
149151
mnemonic = "MomGenerate",
150-
outputs = [output_dir],
152+
outputs = outputs,
151153
xcode_config = platform_prerequisites.xcode_version_config,
152154
)

apple/internal/resource_rules/apple_core_data_model.bzl

Lines changed: 37 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ def _apple_core_data_model_impl(ctx):
8686
attr = "datamodels",
8787
)
8888

89+
expected_outputs = ctx.attr.outs
8990
output_files = []
9091
for datamodel_path, files in datamodel_groups.items():
9192
datamodel_name = paths.replace_extension(
@@ -97,19 +98,30 @@ def _apple_core_data_model_impl(ctx):
9798
datamodel_name.lower(),
9899
ctx.label.name,
99100
)
100-
output_dir = actions.declare_directory(dir_name)
101+
output_dir_path = "{}/{}/{}".format(ctx.genfiles_dir.path, ctx.label.package, dir_name)
102+
expected_file_names = expected_outputs.get(datamodel_name, [])
103+
data_model_outputs = []
104+
if len(expected_file_names) > 0:
105+
for file_name in expected_file_names:
106+
file_path = "{}/{}".format(dir_name, file_name)
107+
file = actions.declare_file(file_path)
108+
data_model_outputs.append(file)
109+
else:
110+
output_dir = actions.declare_directory(dir_name)
111+
data_model_outputs.append(output_dir)
101112

102113
resource_actions.generate_datamodels(
103114
actions = actions,
104115
datamodel_path = datamodel_path,
105116
input_files = files.to_list(),
106-
output_dir = output_dir,
117+
output_dir = output_dir_path,
118+
outputs = data_model_outputs,
107119
platform_prerequisites = platform_prerequisites,
108120
swift_version = swift_version,
109121
xctoolrunner = apple_mac_toolchain_info.xctoolrunner,
110122
)
111123

112-
output_files.append(output_dir)
124+
output_files.extend(data_model_outputs)
113125

114126
return [DefaultInfo(files = depset(output_files))]
115127

@@ -127,12 +139,31 @@ apple_core_data_model = rule(
127139
"swift_version": attr.string(
128140
doc = "Target Swift version for generated classes.",
129141
),
142+
"outs": attr.string_list_dict(
143+
doc = """
144+
A dictionary where the key is the name of a data model and the value is a
145+
list of source files expected to be generated from that data model. For
146+
example, if srcs contains one data model called "Taxonomy.xcdatamodeld" with
147+
a single entity called "Animal," you might provide this value:
148+
```
149+
outs = {
150+
"Taxonomy": [
151+
"taxonomy+CoreDataModel.swift",
152+
"Animal+CoreDataProperties.swift",
153+
],
154+
},
155+
```
156+
If one or more files are provided for a data model, the rule will return these
157+
files individually as outputs. Otherwise, the rule will return the directory
158+
containing the sources for the data model.
159+
""",
160+
),
130161
},
131162
),
132163
fragments = ["apple"],
133164
doc = """
134-
This rule takes a Core Data model definition from a .xcdatamodeld bundle
135-
and generates Swift or Objective-C source files that can be added as a
136-
dependency to a swift_library target.
165+
This rule takes one or more Core Data model definitions from .xcdatamodeld
166+
bundles and generates Swift or Objective-C source files that can be added
167+
as srcs of a swift_library target.
137168
""",
138169
)

doc/rules-resources.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,12 @@ targets (i.e. `apple_resource_bundle` and `apple_resource_group`) through the
3030
## apple_core_data_model
3131

3232
<pre>
33-
apple_core_data_model(<a href="#apple_core_data_model-name">name</a>, <a href="#apple_core_data_model-srcs">srcs</a>, <a href="#apple_core_data_model-swift_version">swift_version</a>)
33+
apple_core_data_model(<a href="#apple_core_data_model-name">name</a>, <a href="#apple_core_data_model-srcs">srcs</a>, <a href="#apple_core_data_model-outs">outs</a>, <a href="#apple_core_data_model-swift_version">swift_version</a>)
3434
</pre>
3535

36-
This rule takes a Core Data model definition from a .xcdatamodeld bundle
37-
and generates Swift or Objective-C source files that can be added as a
38-
dependency to a swift_library target.
36+
This rule takes one or more Core Data model definitions from .xcdatamodeld
37+
bundles and generates Swift or Objective-C source files that can be added
38+
as srcs of a swift_library target.
3939

4040
**ATTRIBUTES**
4141

@@ -44,6 +44,7 @@ dependency to a swift_library target.
4444
| :------------- | :------------- | :------------- | :------------- | :------------- |
4545
| <a id="apple_core_data_model-name"></a>name | A unique name for this target. | <a href="https://bazel.build/concepts/labels#target-names">Name</a> | required | |
4646
| <a id="apple_core_data_model-srcs"></a>srcs | - | <a href="https://bazel.build/concepts/labels">List of labels</a> | required | |
47+
| <a id="apple_core_data_model-outs"></a>outs | A dictionary where the key is the name of a data model and the value is a list of source files expected to be generated from that data model. For example, if srcs contains one data model called "Taxonomy.xcdatamodeld" with a single entity called "Animal," you might provide this value: <pre><code>outs = {&#10; "Taxonomy": [&#10; "taxonomy+CoreDataModel.swift",&#10; "Animal+CoreDataProperties.swift",&#10; ],&#10;},</code></pre> If one or more files are provided for a data model, the rule will return these files individually as outputs. Otherwise, the rule will return the directory containing the sources for the data model. | <a href="https://bazel.build/rules/lib/dict">Dictionary: String -> List of strings</a> | optional | `{}` |
4748
| <a id="apple_core_data_model-swift_version"></a>swift_version | Target Swift version for generated classes. | String | optional | `""` |
4849

4950

test/starlark_tests/apple_core_data_model_tests.bzl

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,17 @@ def apple_core_data_model_test_suite(name):
6161
tags = [name],
6262
)
6363

64+
# Test outputs a list of files rather than directories
65+
analysis_target_outputs_test(
66+
name = "{}_outputs_explicit_swift_files_test".format(name),
67+
target_under_test = "//test/starlark_tests/targets_under_test/apple:explicit_outs_data_model",
68+
expected_outputs = [
69+
"swift_datamodel.explicit_outs_data_model.coredata.sources/swift_datamodel+CoreDataModel.swift",
70+
"swift_datamodel.explicit_outs_data_model.coredata.sources/Item+CoreDataProperties.swift",
71+
],
72+
tags = [name],
73+
)
74+
6475
# Test registered actions and mnemonics for Obj-C and Swift data models.
6576
analysis_target_actions_test(
6677
name = "{}_actions_swift_test".format(name),

test/starlark_tests/targets_under_test/apple/BUILD

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,20 @@ apple_core_data_model(
254254
tags = common.fixture_tags,
255255
)
256256

257+
apple_core_data_model(
258+
name = "explicit_outs_data_model",
259+
srcs = [
260+
"//test/starlark_tests/resources:swift_datamodel",
261+
],
262+
outs = {
263+
"swift_datamodel": [
264+
"swift_datamodel+CoreDataModel.swift",
265+
"Item+CoreDataProperties.swift",
266+
],
267+
},
268+
tags = common.fixture_tags,
269+
)
270+
257271
objc_library(
258272
name = "fmwk_lib",
259273
srcs = [

0 commit comments

Comments
 (0)