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

refactor: strongly typed values in BuildSettings and BuildFileSettings #903

Open
wants to merge 19 commits into
base: main
Choose a base branch
from

Conversation

waltflanagan
Copy link
Member

Short description 📝

Mostly work that was done on the 9.0.0 branch that shouldn't be coupled to Sendability changes.

This introduces the BuildSetting type that will allow safer manipulation of build settings and set us with more typesafety when working with build settings that have constraints.

Keys issues are that this introduces source breaking changes with the signature of the BuildSettings typealias.

@waltflanagan waltflanagan changed the title Strongly Typed values in BuildSettings refactor: Strongly Typed values in BuildSettings Feb 18, 2025
@waltflanagan waltflanagan changed the title refactor: Strongly Typed values in BuildSettings refactor: strongly typed values in BuildSettings and BuildFileSettings Feb 18, 2025
This was fun. `NSDictionary(buildSettings)` is not able to be compared because we wrap swift values so we must use `==` on the swift types since they are not concrete and equatable.
The settings here are constrained to two cases, one as a string and one as a string array as defined here: https://buck.build/javadoc/com/facebook/buck/apple/xcode/xcodeproj/PBXBuildFile.html

Given the narrow use case we should constraint the available types here to fit the need.
@waltflanagan waltflanagan force-pushed the waltflanagan/StrongTypes branch from 46ac0d6 to 791afe0 Compare February 18, 2025 14:25
@waltflanagan waltflanagan force-pushed the waltflanagan/StrongTypes branch from a28c2ff to bf96639 Compare February 19, 2025 01:48
kwridan added a commit to kwridan/xcdiff that referenced this pull request Feb 19, 2025
- Updates to xcdiff for compatibility with tuist/XcodeProj#903
- Build setting values are no longer type erased and instead can now either be a `String` or `[String]`
- This alleviates the need to casting values and throwing errors when dealing with build settings

Test Plan:

- Verify CI passes

Signed-off-by: Kassem Wridan <[email protected]>
Copy link
Collaborator

@kwridan kwridan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @waltflanagan this is a much needed change! 👌

Indeed this is source breaking and would likely need a major release

e.g. updates needed for xcdiff bloomberg/xcdiff#145

Comment on lines +445 to +450
// func XCTAssertEqual(_ lhs: BuildSettings, _ rhs: BuildSettings, file: StaticString = #file, line: UInt = #line) {
// XCTAssertEqual(lhs as NSDictionary,
// rhs as NSDictionary,
// file: file,
// line: line)
// }
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this still needed?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

probably not

@waltflanagan
Copy link
Member Author

@kwridan thats what i was afraid of. I'll see if i can find some time to put together a 9.0 checklist so we can identify anything else that we may want to break There are some other Any collections but those seem like they could follow a similar approach to these callsites.

Do you think it would be worth a transitional phase that preserves BuildSettings as [String: Any] but introduces strongly typed backing stores and parsing to ease into a 9.0 later? It could be something like typealias TypedBuildSettings = [String: BuildSetting] and we would have interfaces that expose the legacy BuildSetting type but convert to TypedBuildSettings.

@kwridan
Copy link
Collaborator

kwridan commented Feb 20, 2025

I wouldn't shy away from a a major release for this per se as there are already a few compatibility APIs lying around that could do with a clean up:

e.g.

https://github.com/tuist/XcodeProj/blob/main/Sources/XcodeProj/Scheme/XCScheme%2BTestableReference.swift#L10

You are right, there are other collections (e.g. attributes) that could do with a similar update, as such to incrementally tackle them deferring the breaking changes such that they are all done together for the next major release makes sense.

Another accessor could be exposed with the strong types typedBuildSettings: TypedBuildSettings that could then be renamed back to buildSettings once the breaking changes are made, that could offer some value till then but at the slightly inconvenience of introducing new public API that is very short lived and would requires clients to migrate of off.

XcodeGen introduced the ability to include whole `PBXObject` values within these dictionaries which end up being written to the project as their reference string value.  In order to simplify the attributes interface, i’m removing that capability and consumers will need to do their own unwrapping.
for (reference, value) in targetAttributeReferences {
plistTargetAttributes[reference.value] = value.mapValues { value in
(value as? PBXObject)?.reference.value ?? value
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was added as a feature for XcodeGen to be able to easily work with these values. This complicates support for strong types though and the migration due to the removal of this change would be to set the .string(object.reference.value) instead of just object at the callsites.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants