Skip to content

Commit 4c0a71b

Browse files
authored
Support StoreKit Configuration setting in xcscheme Run action (#3245)
Fixes #3130. Redoes #3182 (and potentially fixes unresolved comments on #3185). The StoreKit Testing configuration file has a peculiar requirement that has no precedent in the rules. The file's path in the scheme must be relative to the `xcshareddata/xcschemes` directory the scheme is under, not the scheme itself (so one level shallower than you'd expect). Making the path relative to the project fails, and making it absolute crashes Xcode. A prior iteration of this PR attempted to relativize the path in Starlark, but exposed some safety shortcomings. In knowing the absolute path of both the scheme directory and the configuration file, doing this work in the generator gives us slightly improved safety guarantees at the cost of performance. To this author, there is too much ambiguity between the paths of either location without this information, since the files can potentially exist in independent file trees under a workspace. --------- Signed-off-by: Aaron Sky <aaronsky@skyaaron.com>
1 parent 9008225 commit 4c0a71b

28 files changed

+307
-16
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ END_UNRELEASED_TEMPLATE
5050

5151
* Added `--@rules_xcodeproj//xcodeproj:separate_index_build_output_base` flag to configure the generator to use a separate output base for index builds: [#3243](https://github.com/MobileNativeFoundation/rules_xcodeproj/pull/3243)
5252
* Add support for viewing and edit xcmappingmodel files: [#3242](https://github.com/MobileNativeFoundation/rules_xcodeproj/pull/3242)
53+
* Added support for StoreKit configuration files to `xcschemes.run`, for use with [StoreKit Testing](https://developer.apple.com/documentation/xcode/setting-up-storekit-testing-in-xcode). [#3242](https://github.com/MobileNativeFoundation/rules_xcodeproj/pull/3245)
5354

5455
### Adjusted
5556

docs/bazel.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -464,7 +464,7 @@ Defines the Profile action.
464464

465465
<pre>
466466
xcschemes.run(<a href="#xcschemes.run-args">args</a>, <a href="#xcschemes.run-build_targets">build_targets</a>, <a href="#xcschemes.run-diagnostics">diagnostics</a>, <a href="#xcschemes.run-env">env</a>, <a href="#xcschemes.run-env_include_defaults">env_include_defaults</a>, <a href="#xcschemes.run-launch_target">launch_target</a>,
467-
<a href="#xcschemes.run-xcode_configuration">xcode_configuration</a>)
467+
<a href="#xcschemes.run-storekit_configuration">storekit_configuration</a>, <a href="#xcschemes.run-xcode_configuration">xcode_configuration</a>)
468468
</pre>
469469

470470
Defines the Run action.
@@ -480,6 +480,7 @@ Defines the Run action.
480480
| <a id="xcschemes.run-env"></a>env | Environment variables to use when running the launch target.<br><br>If set to `"inherit"`, then the environment variables will be supplied by the launch target (e.g. [`cc_binary.env`](https://bazel.build/reference/be/common-definitions#binary.env)). Otherwise, the `dict` of environment variables will be set as provided, and `None` or `{}` will result in no environment variables.<br><br>Each value of the `dict` can either be a string or a value returned by [`xcschemes.env_value`](#xcschemes.env_value). If a value is a string, it will be transformed into `xcschemes.env_value(value)`. For example, <pre><code>xcschemes.run(&#10; env = {&#10; "VAR1": "value 1",&#10; "VAR 2": xcschemes.env_value("value2", enabled = False),&#10; },&#10;)</code></pre> will be transformed into: <pre><code>xcschemes.run(&#10; env = {&#10; "VAR1": xcschemes.env_value("value 1"),&#10; "VAR 2": xcschemes.env_value("value2", enabled = False),&#10; },&#10;)</code></pre> | `"inherit"` |
481481
| <a id="xcschemes.run-env_include_defaults"></a>env_include_defaults | Whether to include the rules_xcodeproj provided default Bazel environment variables (e.g. `BUILD_WORKING_DIRECTORY` and `BUILD_WORKSPACE_DIRECTORY`), in addition to any set by [`env`](#xcschemes.run-env). This does not apply to [`xcschemes.launch_path`](#xcschemes.launch_path)s. | `True` |
482482
| <a id="xcschemes.run-launch_target"></a>launch_target | The target to launch when running.<br><br>Can be `None`, a label string, a value returned by [`xcschemes.launch_target`](#xcschemes.launch_target), or a value returned by [`xcschemes.launch_path`](#xcschemes.launch_path). If a label string, `xcschemes.launch_target(label_str)` will be used. If `None`, `xcschemes.launch_target()` will be used, which means no launch target will be set (i.e. the `Executable` dropdown will be set to `None`). | `None` |
483+
| <a id="xcschemes.run-storekit_configuration"></a>storekit_configuration | A StoreKit configuration file for use with [StoreKit Testing](https://developer.apple.com/documentation/xcode/setting-up-storekit-testing-in-xcode).<br><br>Can be `None`, or a label string referring to a single configuration file. | `None` |
483484
| <a id="xcschemes.run-xcode_configuration"></a>xcode_configuration | The name of the Xcode configuration to use to build the targets referenced in the Run action (i.e in the [`build_targets`](#xcschemes.run-build_targets) and [`launch_target`](#xcschemes.run-launch_target) attributes).<br><br>If not set, the value of [`xcodeproj.default_xcode_configuration`](#xcodeproj-default_xcode_configuration) is used. | `None` |
484485

485486

examples/integration/Lib/BUILD

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,10 @@ load("@build_bazel_rules_apple//apple:tvos.bzl", "tvos_framework")
77
load("@build_bazel_rules_apple//apple:watchos.bzl", "watchos_framework")
88
load("@build_bazel_rules_swift//swift:swift.bzl", "swift_library")
99

10-
exports_files(["README.md"])
10+
exports_files([
11+
"README.md",
12+
"Resources/Configuration.storekit",
13+
])
1114

1215
exports_files(
1316
["Info.plist"],
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
{
2+
"appPolicies" : {
3+
"eula" : "",
4+
"policies" : [
5+
{
6+
"locale" : "en_US",
7+
"policyText" : "",
8+
"policyURL" : ""
9+
}
10+
]
11+
},
12+
"identifier" : "",
13+
"nonRenewingSubscriptions" : [
14+
15+
],
16+
"products" : [
17+
18+
],
19+
"settings" : {
20+
"_failTransactionsEnabled" : false
21+
},
22+
"subscriptionGroups" : [
23+
24+
],
25+
"version" : {
26+
"major" : 4,
27+
"minor" : 0
28+
}
29+
}

examples/integration/xcodeproj_targets.bzl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,7 @@ XCSCHEMES = [
228228
],
229229
),
230230
],
231+
storekit_configuration = "//Lib:Resources/Configuration.storekit",
231232
),
232233
),
233234
]
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{}

test/internal/xcschemes/info_constructors_tests.bzl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -589,6 +589,7 @@ def info_constructors_test_suite(name):
589589
env = None,
590590
env_include_defaults = "1",
591591
launch_target = xcscheme_infos_testable.make_launch_target(),
592+
storekit_configuration = "",
592593
xcode_configuration = "",
593594
),
594595
)
@@ -621,6 +622,7 @@ def info_constructors_test_suite(name):
621622
},
622623
env_include_defaults = "0",
623624
launch_target = xcscheme_infos_testable.make_launch_target("L"),
625+
storekit_configuration = "",
624626
xcode_configuration = "Run",
625627
),
626628

@@ -651,6 +653,7 @@ def info_constructors_test_suite(name):
651653
launch_target = xcscheme_infos_testable.make_launch_target(
652654
id = "L",
653655
),
656+
storekit_configuration = "",
654657
xcode_configuration = "Run",
655658
),
656659
)

test/internal/xcschemes/infos_from_json_tests.bzl

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ def _infos_from_json_test_impl(ctx):
4242
infos = xcscheme_infos.from_json(
4343
ctx.attr.json_str,
4444
default_xcode_configuration = ctx.attr.default_xcode_configuration,
45+
storekit_configurations_map = ctx.attr.storekit_configurations_map,
4546
top_level_deps = _json_to_top_level_deps(ctx.attr.top_level_deps),
4647
)
4748

@@ -62,7 +63,9 @@ infos_from_json_test = unittest.make(
6263
attrs = {
6364
# Inputs
6465
"default_xcode_configuration": attr.string(mandatory = True),
66+
"install_path": attr.string(mandatory = True),
6567
"json_str": attr.string(mandatory = True),
68+
"storekit_configurations_map": attr.string_dict(mandatory = True),
6669
"top_level_deps": attr.string(mandatory = True),
6770

6871
# Expected
@@ -86,7 +89,9 @@ def infos_from_json_test_suite(name):
8689

8790
# Inputs
8891
default_xcode_configuration,
92+
install_path,
8993
json_str,
94+
storekit_configurations_map,
9095
top_level_deps,
9196

9297
# Expected
@@ -97,7 +102,9 @@ def infos_from_json_test_suite(name):
97102

98103
# Inputs
99104
default_xcode_configuration = default_xcode_configuration,
105+
install_path = install_path,
100106
json_str = json_str,
107+
storekit_configurations_map = storekit_configurations_map,
101108
top_level_deps = json.encode(top_level_deps),
102109

103110
# Expected
@@ -149,6 +156,7 @@ def infos_from_json_test_suite(name):
149156
},
150157
}
151158

159+
install_path = "test/internal/InfosFromJSONTests.xcodeproj"
152160
full_args = [
153161
"-a\nnewline",
154162
xcscheme_infos_testable.make_arg(
@@ -390,7 +398,9 @@ def infos_from_json_test_suite(name):
390398

391399
# Inputs
392400
default_xcode_configuration = "AppStore",
401+
install_path = install_path,
393402
json_str = json.encode([]),
403+
storekit_configurations_map = {},
394404
top_level_deps = {},
395405

396406
# Expected
@@ -404,6 +414,7 @@ def infos_from_json_test_suite(name):
404414

405415
# Inputs
406416
default_xcode_configuration = "AppStore",
417+
install_path = install_path,
407418
json_str = json.encode([
408419
{
409420
"name": "A scheme",
@@ -418,6 +429,7 @@ def infos_from_json_test_suite(name):
418429
"test": None,
419430
},
420431
]),
432+
storekit_configurations_map = {},
421433
top_level_deps = {},
422434

423435
# Expected
@@ -438,6 +450,7 @@ def infos_from_json_test_suite(name):
438450

439451
# Inputs
440452
default_xcode_configuration = "custom",
453+
install_path = install_path,
441454
json_str = json.encode([
442455
{
443456
"name": "A scheme",
@@ -485,6 +498,7 @@ def infos_from_json_test_suite(name):
485498
"test": None,
486499
},
487500
]),
501+
storekit_configurations_map = {},
488502
top_level_deps = top_level_deps,
489503

490504
# Expected
@@ -514,6 +528,7 @@ def infos_from_json_test_suite(name):
514528

515529
# Inputs
516530
default_xcode_configuration = "AppStore",
531+
install_path = install_path,
517532
json_str = json.encode([
518533
{
519534
"name": "A scheme",
@@ -530,6 +545,7 @@ def infos_from_json_test_suite(name):
530545
"test": None,
531546
},
532547
]),
548+
storekit_configurations_map = {},
533549
top_level_deps = top_level_deps,
534550

535551
# Expected
@@ -557,6 +573,7 @@ def infos_from_json_test_suite(name):
557573

558574
# Inputs
559575
default_xcode_configuration = "AppStore",
576+
install_path = install_path,
560577
json_str = json.encode([
561578
{
562579
"name": "A scheme",
@@ -565,6 +582,7 @@ def infos_from_json_test_suite(name):
565582
"test": None,
566583
},
567584
]),
585+
storekit_configurations_map = {},
568586
top_level_deps = {},
569587

570588
# Expected
@@ -581,6 +599,7 @@ def infos_from_json_test_suite(name):
581599

582600
# Inputs
583601
default_xcode_configuration = "AppStore",
602+
install_path = install_path,
584603
json_str = json.encode([
585604
{
586605
"name": "A scheme",
@@ -594,11 +613,13 @@ def infos_from_json_test_suite(name):
594613
env = {"A": "B"},
595614
env_include_defaults = "1",
596615
launch_target = full_launch_target,
616+
storekit_configuration = "",
597617
xcode_configuration = "custom",
598618
),
599619
"test": None,
600620
},
601621
]),
622+
storekit_configurations_map = {},
602623
top_level_deps = top_level_deps,
603624

604625
# Expected
@@ -626,6 +647,7 @@ def infos_from_json_test_suite(name):
626647
env = {"A": xcscheme_infos_testable.make_env("B")},
627648
env_include_defaults = "1",
628649
launch_target = expected_full_launch_target,
650+
storekit_configuration = "",
629651
xcode_configuration = "custom",
630652
),
631653
),
@@ -639,6 +661,7 @@ def infos_from_json_test_suite(name):
639661

640662
# Inputs
641663
default_xcode_configuration = "custom",
664+
install_path = install_path,
642665
json_str = json.encode([
643666
{
644667
"name": "A scheme",
@@ -681,11 +704,13 @@ def infos_from_json_test_suite(name):
681704
target_environment = "",
682705
working_directory = "",
683706
),
707+
storekit_configuration = "",
684708
xcode_configuration = "",
685709
),
686710
"test": None,
687711
},
688712
]),
713+
storekit_configurations_map = {},
689714
top_level_deps = top_level_deps,
690715

691716
# Expected
@@ -744,6 +769,7 @@ def infos_from_json_test_suite(name):
744769

745770
# Inputs
746771
default_xcode_configuration = "AppStore",
772+
install_path = install_path,
747773
json_str = json.encode([
748774
{
749775
"name": "A scheme",
@@ -781,11 +807,13 @@ def infos_from_json_test_suite(name):
781807
],
782808
working_directory = "wd",
783809
),
810+
storekit_configuration = "",
784811
xcode_configuration = "custom",
785812
),
786813
"test": None,
787814
},
788815
]),
816+
storekit_configurations_map = {},
789817
top_level_deps = top_level_deps,
790818

791819
# Expected
@@ -821,6 +849,7 @@ def infos_from_json_test_suite(name):
821849

822850
# Inputs
823851
default_xcode_configuration = "AppStore",
852+
install_path = install_path,
824853
json_str = json.encode([
825854
{
826855
"name": "A scheme",
@@ -839,11 +868,15 @@ def infos_from_json_test_suite(name):
839868
env_include_defaults = "0",
840869
launch_target = full_launch_target,
841870
use_run_args_and_env = "0",
871+
storekit_configuration = "//test/internal/xcschemes:fixture.storekit",
842872
xcode_configuration = "custom",
843873
),
844874
"test": None,
845875
},
846876
]),
877+
storekit_configurations_map = {
878+
"//test/internal/xcschemes:fixture.storekit": "test/internal/xcschemes/fixture.storekit",
879+
},
847880
top_level_deps = top_level_deps,
848881

849882
# Expected
@@ -866,6 +899,9 @@ def infos_from_json_test_suite(name):
866899
env = expected_full_env,
867900
env_include_defaults = "0",
868901
launch_target = expected_full_launch_target,
902+
# from the install path and two levels inside the project, up to the execution root
903+
# <install_path>/xcshareddata/xcschemes
904+
storekit_configuration = "test/internal/xcschemes/fixture.storekit",
869905
xcode_configuration = "custom",
870906
),
871907
),
@@ -879,6 +915,7 @@ def infos_from_json_test_suite(name):
879915

880916
# Inputs
881917
default_xcode_configuration = "custom",
918+
install_path = install_path,
882919
json_str = json.encode([
883920
{
884921
"name": "A scheme",
@@ -913,6 +950,7 @@ def infos_from_json_test_suite(name):
913950
),
914951
},
915952
]),
953+
storekit_configurations_map = {},
916954
top_level_deps = top_level_deps,
917955

918956
# Expected
@@ -938,6 +976,7 @@ def infos_from_json_test_suite(name):
938976

939977
# Inputs
940978
default_xcode_configuration = "AppStore",
979+
install_path = install_path,
941980
json_str = json.encode([
942981
{
943982
"name": "A scheme",
@@ -1009,6 +1048,7 @@ def infos_from_json_test_suite(name):
10091048
),
10101049
},
10111050
]),
1051+
storekit_configurations_map = {},
10121052
top_level_deps = top_level_deps,
10131053

10141054
# Expected

test/internal/xcschemes/utils.bzl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ def _dict_to_run_info(d):
6464
env = _dict_of_dicts_to_env_infos(d["env"]),
6565
env_include_defaults = d["env_include_defaults"],
6666
launch_target = _dict_to_launch_target_info(d["launch_target"]),
67+
storekit_configuration = d["storekit_configuration"],
6768
xcode_configuration = d["xcode_configuration"],
6869
)
6970

0 commit comments

Comments
 (0)