Skip to content

Commit 8df9065

Browse files
committed
Convert calculate_output_groups.py into a Swift binary
Signed-off-by: Matt Pennig <[email protected]>
1 parent 0e610af commit 8df9065

File tree

18 files changed

+68
-484
lines changed

18 files changed

+68
-484
lines changed

distribution/BUILD

+3
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,9 @@ pkg_tar(
5959
remap_paths = dicts.add(
6060
{
6161
"MODULE.release.bazel": "MODULE.bazel",
62+
"tools/calculate_output_groups/BUILD.release.bazel": (
63+
"tools/calculate_output_groups/BUILD"
64+
),
6265
"tools/import_indexstores/BUILD.release.bazel": (
6366
"tools/import_indexstores/BUILD"
6467
),

examples/integration/test/fixtures/bwb.xcodeproj/project.pbxproj

-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

examples/integration/test/fixtures/bwx.xcodeproj/project.pbxproj

-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

examples/rules_ios/test/fixtures/bwb.xcodeproj/project.pbxproj

-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tools/calculate_output_groups/CalculateOutputGroups.swift

+5-3
Original file line numberDiff line numberDiff line change
@@ -14,16 +14,18 @@ struct CalculateOutputGroups: AsyncParsableCommand {
1414
@OptionGroup var arguments: OutputGroupsCalculator.Arguments
1515

1616
func run() async throws {
17+
var output = StdoutOutputStream()
1718
let logger = DefaultLogger(
1819
standardError: StderrOutputStream(),
19-
standardOutput: StdoutOutputStream(),
20+
standardOutput: output,
2021
colorize: colorDiagnostics
2122
)
2223

23-
let calculator = OutputGroupsCalculator()
24+
let calculator = OutputGroupsCalculator(logger: logger)
2425

2526
do {
26-
try await calculator.calculateOutputGroups(arguments: arguments)
27+
let groups = try await calculator.calculateOutputGroups(arguments: arguments)
28+
print(groups, to: &output)
2729
} catch {
2830
logger.logError(error.localizedDescription)
2931
Darwin.exit(1)

tools/calculate_output_groups/Errors.swift

+3-3
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import ToolCommon
33
extension UsageError {
44
static func buildMarker(_ path: String) -> Self {
55
.init(message: """
6-
error: Build marker (\(path)) doesn't exist. If you manually cleared Derived \
6+
Build marker (\(path)) doesn't exist. If you manually cleared Derived \
77
Data, you need to close and re-open the project for the file to be created \
88
again. Using the "Clean Build Folder" command instead (⇧ ⌘ K) won't trigger \
99
this error. If this error still happens after re-opening the project, please \
@@ -14,7 +14,7 @@ https://github.com/MobileNativeFoundation/rules_xcodeproj/issues/new?template=bu
1414

1515
static func pifCache(_ path: String) -> Self {
1616
.init(message: """
17-
error: PIFCache (\(path)) doesn't exist. If you manually cleared Derived \
17+
PIFCache (\(path)) doesn't exist. If you manually cleared Derived \
1818
Data, you need to close and re-open the project for the PIFCache to be created \
1919
again. Using the "Clean Build Folder" command instead (⇧ ⌘ K) won't trigger \
2020
this error. If this error still happens after re-opening the project, please \
@@ -25,7 +25,7 @@ https://github.com/MobileNativeFoundation/rules_xcodeproj/issues/new?template=bu
2525

2626
static func buildRequest(_ path: String) -> Self {
2727
.init(message: """
28-
error: Couldn't find a build-request.json file inside \(path)". Please file a bug \
28+
Couldn't find latest build-request.json file after 30 seconds. Please file a bug \
2929
report here: https://github.com/MobileNativeFoundation/rules_xcodeproj/issues/new?template=bug.md
3030
""")
3131
}

tools/calculate_output_groups/OutputGroupsCalculator.swift

+27-15
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@ import ToolCommon
33
import ZippyJSON
44

55
struct OutputGroupsCalculator {
6-
func calculateOutputGroups(arguments: Arguments) async throws {
6+
let logger: Logger
7+
8+
func calculateOutputGroups(arguments: Arguments) async throws -> String {
79
let pifCache = arguments.baseObjRoot.appendingPathComponent("XCBuildData/PIFCache")
810
let projectCache = pifCache.appendingPathComponent("project")
911
let targetCache = pifCache.appendingPathComponent("target")
@@ -30,12 +32,11 @@ struct OutputGroupsCalculator {
3032
targetCache: targetCache
3133
)
3234

33-
let output = try await outputGroups(
35+
return try await outputGroups(
3436
buildRequest: buildRequest,
3537
targets: targetMap,
3638
prefixes: arguments.outputGroupPrefixes
3739
)
38-
print(output)
3940
}
4041

4142
private func loadBuildRequestFile(inPath path: URL, since: Date) async throws -> BuildRequest {
@@ -54,22 +55,33 @@ struct OutputGroupsCalculator {
5455
}
5556

5657
// If the file was not immediately found, kick off a process to wait for the file to be created (or time out).
57-
let findTask = Task {
58-
while true {
59-
try Task.checkCancellation()
60-
try await Task.sleep(for: .seconds(1))
61-
if let buildRequestURL = findBuildRequestURL() {
62-
return buildRequestURL
58+
do {
59+
let findTask = Task {
60+
logger.logWarning("The latest build-request.json file has not been updated yet. Waiting…")
61+
while true {
62+
try Task.checkCancellation()
63+
try await Task.sleep(for: .seconds(1))
64+
if let buildRequestURL = findBuildRequestURL() {
65+
return buildRequestURL
66+
}
6367
}
6468
}
65-
}
66-
let timeoutTask = Task {
67-
try await Task.sleep(for: .seconds(10))
68-
findTask.cancel()
69-
}
69+
let waitingTask = Task {
70+
try await Task.sleep(for: .seconds(10))
71+
try Task.checkCancellation()
72+
logger.logWarning("""
73+
The latest build-request.json file has still not been updated after 10 seconds. If this happens frequently, please file a bug report here:
74+
https://github.com/MobileNativeFoundation/rules_xcodeproj/issues/new?template=bug.md
75+
""")
76+
}
77+
let timeoutTask = Task {
78+
try await Task.sleep(for: .seconds(30))
79+
guard !Task.isCancelled else { return }
80+
findTask.cancel()
81+
}
7082

71-
do {
7283
let result = try await findTask.value
84+
waitingTask.cancel()
7385
timeoutTask.cancel()
7486
return try result.decode(BuildRequest.self)
7587
} catch {

tools/generators/legacy/src/Generator/AddBazelDependenciesTarget.swift

-3
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,6 @@ extension Generator {
3535

3636
var buildSettings: BuildSettings = [
3737
"BAZEL_PACKAGE_BIN_DIR": "rules_xcodeproj",
38-
"CALCULATE_OUTPUT_GROUPS_SCRIPT": """
39-
$(BAZEL_INTEGRATION_DIR)/calculate_output_groups.py
40-
""",
4138
"INDEXING_SUPPORTED_PLATFORMS__": """
4239
$(INDEXING_SUPPORTED_PLATFORMS__NO)
4340
""",

tools/generators/legacy/src/Generator/SetTargetConfigurations.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -283,7 +283,7 @@ $(BAZEL_OUT)\#(linkParams.path.string.dropFirst(9))
283283
buildSettings.set("TARGET_NAME", to: target.name)
284284

285285
if !target.product.isResourceBundle {
286-
// This is used in `calculate_output_groups.py`. We only want to set
286+
// This is used in `calculate_output_groups`. We only want to set
287287
// it on buildable targets
288288
buildSettings.set("BAZEL_LABEL", to: target.label.description)
289289
}

tools/generators/pbxnativetargets/src/Generator/CalculateSharedBuildSettings.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ extension Generator.CalculateSharedBuildSettings {
114114
}
115115

116116
if productType != .resourceBundle {
117-
// This is used in `calculate_output_groups.py`. We only want to set
117+
// This is used in `calculate_output_groups`. We only want to set
118118
// it on buildable targets.
119119
buildSettings.append(
120120
.init(

tools/generators/pbxproj_prefix/README.md

-2
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,6 @@ Here is an example output:
121121
isa = XCBuildConfiguration;
122122
buildSettings = {
123123
BAZEL_PACKAGE_BIN_DIR = rules_xcodeproj;
124-
CALCULATE_OUTPUT_GROUPS_SCRIPT = "$(BAZEL_INTEGRATION_DIR)/calculate_output_groups.py";
125124
CC = "";
126125
CXX = "";
127126
INDEXING_SUPPORTED_PLATFORMS__ = "$(INDEXING_SUPPORTED_PLATFORMS__NO)";
@@ -144,7 +143,6 @@ Here is an example output:
144143
isa = XCBuildConfiguration;
145144
buildSettings = {
146145
BAZEL_PACKAGE_BIN_DIR = rules_xcodeproj;
147-
CALCULATE_OUTPUT_GROUPS_SCRIPT = "$(BAZEL_INTEGRATION_DIR)/calculate_output_groups.py";
148146
CC = "";
149147
CXX = "";
150148
INDEXING_SUPPORTED_PLATFORMS__ = "$(INDEXING_SUPPORTED_PLATFORMS__NO)";

tools/generators/pbxproj_prefix/src/Generator/BazelDependenciesBuildSettings.swift

-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ extension Generator {
2424
return #"""
2525
{
2626
BAZEL_PACKAGE_BIN_DIR = rules_xcodeproj;
27-
CALCULATE_OUTPUT_GROUPS_SCRIPT = "$(BAZEL_INTEGRATION_DIR)/calculate_output_groups.py";
2827
CC = "";
2928
CXX = "";
3029
INDEXING_SUPPORTED_PLATFORMS__ = "$(INDEXING_SUPPORTED_PLATFORMS__NO)";

tools/generators/pbxproj_prefix/test/BazelDependenciesBuildSettingsTests.swift

-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ class BazelDependenciesBuildSettingsTests: XCTestCase {
2020
let expectedBuildSettings = #"""
2121
{
2222
BAZEL_PACKAGE_BIN_DIR = rules_xcodeproj;
23-
CALCULATE_OUTPUT_GROUPS_SCRIPT = "$(BAZEL_INTEGRATION_DIR)/calculate_output_groups.py";
2423
CC = "";
2524
CXX = "";
2625
INDEXING_SUPPORTED_PLATFORMS__ = "$(INDEXING_SUPPORTED_PLATFORMS__NO)";

xcodeproj/internal/bazel_integration_files/BUILD

+25-17
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
_BASE_FILES = [
2-
"calculate_output_groups.py",
32
"copy_dsyms.sh",
43
"create_lldbinit.sh",
54
"generate_bazel_dependencies.sh",
6-
":renamed_import_indexstores",
75
"process_bazel_build_log.py",
6+
":renamed_calculate_output_groups",
7+
":renamed_import_indexstores",
88
]
99

1010
filegroup(
@@ -92,19 +92,34 @@ echo '/*.framework/SwiftUIPreviewsFrameworks/***' >> "framework.exclude.rsynclis
9292
tags = ["manual"],
9393
)
9494

95-
genrule(
96-
name = "renamed_import_indexstores",
97-
srcs = ["//tools/import_indexstores:universal_import_indexstores"],
98-
outs = ["import_indexstores"],
99-
# Make `import_indexstores` have the right name
100-
cmd = """\
95+
rename_command = """\
10196
readonly output="$@"
10297
if [[ $$(stat -f '%d' "$<") == $$(stat -f '%d' "$${output%/*}") ]]; then
10398
cp -c "$<" "$@"
10499
else
105100
cp "$<" "$@"
106101
fi
107-
""",
102+
"""
103+
104+
genrule(
105+
name = "renamed_calculate_output_groups",
106+
srcs = ["//tools/calculate_output_groups:universal_calculate_output_groups"],
107+
outs = ["calculate_output_groups"],
108+
# Make `calculate_output_groups` have the right name
109+
cmd = rename_command,
110+
message = "Renaming calculate_output_groups",
111+
tags = [
112+
"manual",
113+
"no-sandbox",
114+
],
115+
)
116+
117+
genrule(
118+
name = "renamed_import_indexstores",
119+
srcs = ["//tools/import_indexstores:universal_import_indexstores"],
120+
outs = ["import_indexstores"],
121+
# Make `import_indexstores` have the right name
122+
cmd = rename_command,
108123
message = "Renaming import_indexstores",
109124
tags = [
110125
"manual",
@@ -117,14 +132,7 @@ genrule(
117132
srcs = ["//tools/swiftc_stub:universal_swiftc_stub"],
118133
outs = ["swiftc"],
119134
# Make `swiftc_stub` have the right name
120-
cmd = """\
121-
readonly output="$@"
122-
if [[ $$(stat -f '%d' "$<") == $$(stat -f '%d' "$${output%/*}") ]]; then
123-
cp -c "$<" "$@"
124-
else
125-
cp "$<" "$@"
126-
fi
127-
""",
135+
cmd = rename_command,
128136
message = "Renaming swiftc_stub",
129137
tags = [
130138
"manual",

0 commit comments

Comments
 (0)