Skip to content

[PackageLoading] Make sure JSON-encoded rule keys are stable #1802

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

Merged
merged 1 commit into from
Oct 6, 2018

Conversation

lorentey
Copy link
Member

@lorentey lorentey commented Oct 6, 2018

JSONEncoder does not guarantee stable element ordering unless we specifically ask for the keys to be sorted.

This gets especially important as we plan to enable per-instance hash seeding for Dictionary, which breaks llbuild's rule keys on Linux without this change.

@lorentey
Copy link
Member Author

lorentey commented Oct 6, 2018

@swift-ci please test

@aciidgh
Copy link
Contributor

aciidgh commented Oct 6, 2018

@swift-ci smoke test

@aciidgh
Copy link
Contributor

aciidgh commented Oct 6, 2018

@swift-ci test with toolchain

@lorentey
Copy link
Member Author

lorentey commented Oct 6, 2018

/Users/buildnode/jenkins/workspace/swift-package-manager-with-xcode-PR-osx/swiftpm/Sources/SPMLLBuild/llbuild.swift:201:34: error: 'sortedKeys' is only available on OS X 10.13 or newer

Oops, yeah, this needs an availability check on macOS. (Sorting is only critical for Linux, where JSONEncoder uses native Swift dictionaries.)

@aciidgh
Copy link
Contributor

aciidgh commented Oct 6, 2018

Yep. And sorry for stomping on your commit 😅

JSONEncoder does not guarantee stable element ordering unless the keys are sorted.
@aciidgh
Copy link
Contributor

aciidgh commented Oct 6, 2018

@swift-ci smoke test

@aciidgh
Copy link
Contributor

aciidgh commented Oct 6, 2018

@swift-ci test with toolchain

@aciidgh aciidgh merged commit b9698e7 into swiftlang:master Oct 6, 2018
@@ -197,6 +197,14 @@ private func fromBytes<T: Decodable>(_ bytes: [UInt8]) throws -> T {
}

private func toBytes<T: Encodable>(_ value: T) throws -> [UInt8] {
let encoded = try JSONEncoder().encode(value)
let encoder = JSONEncoder()
#if os(macOS)
Copy link
Contributor

Choose a reason for hiding this comment

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

Are you sure this #if os(macOS) is necessary?

The way #available works is that the '*' indicates that the code path inside the if body will be taken on any platforms not listed. So this by itself:

if #available(OSX 10.13, *) {
    encoder.outputFormatting = [.sortedKeys]
}

should be entirely equivalent to:

#if os(macOS)
if #available(OSX 10.13, *) {
    encoder.outputFormatting = [.sortedKeys]
}
#else
encoder.outputFormatting = [.sortedKeys]
#endif

Copy link
Contributor

Choose a reason for hiding this comment

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

You're right. IDK why I thought that was required 🤷‍♂️. Fixed here #1803

@lorentey lorentey deleted the stable-rule-keys branch February 16, 2021 23:41
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.

3 participants