Skip to content

Commit

Permalink
Wire up Swift6 data race safety info
Browse files Browse the repository at this point in the history
  • Loading branch information
finestructure committed May 24, 2024
1 parent c26b4c4 commit 6ddf4d6
Show file tree
Hide file tree
Showing 8 changed files with 66 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,11 @@ extension API.PackageController {
typealias NamedBuildResults = GetRoute.Model.NamedBuildResults
typealias PlatformResults = GetRoute.Model.PlatformResults
typealias SwiftVersionResults = GetRoute.Model.SwiftVersionResults
typealias Swift6Readiness = GetRoute.Model.Swift6Readiness

var platform: ModelBuildInfo<PlatformResults>?
var swiftVersion: ModelBuildInfo<SwiftVersionResults>?
var swift6Readiness: Swift6Readiness

static func query(on database: Database, owner: String, repository: String) async throws -> Self {
// FIXME: move up from PackageController.BuildsRoute into API.PackageController.BuildsRoute
Expand All @@ -32,7 +34,8 @@ extension API.PackageController {
repository: repository)
return Self.init(
platform: platformBuildInfo(builds: builds),
swiftVersion: swiftVersionBuildInfo(builds: builds)
swiftVersion: swiftVersionBuildInfo(builds: builds),
swift6Readiness: swift6Readiness(builds: builds)
)
}

Expand Down Expand Up @@ -111,6 +114,14 @@ extension API.PackageController {
status5_10: v5_10.buildStatus)
)
}

static func swift6Readiness(builds: [PackageController.BuildsRoute.BuildInfo]) -> Swift6Readiness {
var readiness = Swift6Readiness()
for build in builds where build.swiftVersion == .v6_0 {
readiness.errorCounts[build.platform] = build.buildErrors?.numSwift6Errors
}
return readiness
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ extension API.PackageController.GetRoute {
var weightedKeywords: [WeightedKeyword]
var releaseReferences: [App.Version.Kind: App.Reference]
var fundingLinks: [FundingLink]
var swift6Readiness: Swift6Readiness?

internal init(packageId: Package.Id,
repositoryOwner: String,
Expand Down Expand Up @@ -79,7 +80,8 @@ extension API.PackageController.GetRoute {
defaultBranchReference: App.Reference,
releaseReference: App.Reference?,
preReleaseReference: App.Reference?,
fundingLinks: [FundingLink] = []
fundingLinks: [FundingLink] = [],
swift6Readiness: Swift6Readiness?
) {
self.packageId = packageId
self.repositoryOwner = repositoryOwner
Expand Down Expand Up @@ -120,6 +122,7 @@ extension API.PackageController.GetRoute {
return refs
}()
self.fundingLinks = fundingLinks
self.swift6Readiness = swift6Readiness
}

init?(result: API.PackageController.PackageResult,
Expand All @@ -128,7 +131,8 @@ extension API.PackageController.GetRoute {
targets: [Target],
swiftVersionBuildInfo: BuildInfo<SwiftVersionResults>?,
platformBuildInfo: BuildInfo<PlatformResults>?,
weightedKeywords: [WeightedKeyword] = []) {
weightedKeywords: [WeightedKeyword] = [],
swift6Readiness: Swift6Readiness?) {
// we consider certain attributes as essential and return nil (raising .notFound)
let repository = result.repository
guard
Expand Down Expand Up @@ -172,7 +176,8 @@ extension API.PackageController.GetRoute {
defaultBranchReference: result.defaultBranchVersion.reference,
releaseReference: result.releaseVersion?.reference,
preReleaseReference: result.preReleaseVersion?.reference,
fundingLinks: result.repository.fundingLinks
fundingLinks: result.repository.fundingLinks,
swift6Readiness: swift6Readiness
)

}
Expand Down Expand Up @@ -398,6 +403,25 @@ extension API.PackageController.GetRoute.Model {
var status: BuildStatus
}

struct Swift6Readiness: Codable, Equatable {
var errorCounts: [Build.Platform: Int?] = [:]

enum DataRaceSafety {
case safe
case unsafe
case unknown
}

var dataRaceSafety: DataRaceSafety {
let results = errorCounts.values.compacted()
if results.isEmpty {
return .unknown
} else {
return results.first(where: { $0 == 0 }) != nil ? .safe : .unsafe
}
}
}

}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,8 @@ extension API.PackageController {
targets: targets.compactMap(Model.Target.init(name:targetType:)),
swiftVersionBuildInfo: buildInfo.swiftVersion,
platformBuildInfo: buildInfo.platform,
weightedKeywords: weightedKeywords
weightedKeywords: weightedKeywords,
swift6Readiness: buildInfo.swift6Readiness
),
let schema = API.PackageSchema(result: packageResult)
else {
Expand Down
3 changes: 2 additions & 1 deletion Sources/App/Controllers/API/Types+WithExample.swift
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,8 @@ extension API.PackageController.GetRoute.Model: WithExample {
isArchived: false,
defaultBranchReference: .branch("main"),
releaseReference: .tag(1, 2, 3, "1.2.3"),
preReleaseReference: nil)
preReleaseReference: nil,
swift6Readiness: nil)
}
}

Expand Down
5 changes: 4 additions & 1 deletion Sources/App/Controllers/PackageController+BuildsRoute.swift
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ extension PackageController {
var platform: Build.Platform
var status: Build.Status
var docStatus: DocUpload.Status?
var buildErrors: BuildErrors?

static func query(on database: Database, owner: String, repository: String) async throws -> [BuildInfo] {
try await Joined5<Build, Version, Package, Repository, DocUpload>
Expand All @@ -62,6 +63,7 @@ extension PackageController {
.field(\.$swiftVersion)
.field(\.$platform)
.field(\.$status)
.field(\.$buildErrors)
.field(Version.self, \.$latest)
.field(Version.self, \.$packageName)
.field(Version.self, \.$reference)
Expand All @@ -79,7 +81,8 @@ extension PackageController {
swiftVersion: build.swiftVersion,
platform: build.platform,
status: build.status,
docStatus: res.docUpload?.status)
docStatus: res.docUpload?.status,
buildErrors: build.buildErrors)
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions Sources/App/Views/PackageController/GetRoute.Model+ext.swift
Original file line number Diff line number Diff line change
Expand Up @@ -310,8 +310,8 @@ extension API.PackageController.GetRoute.Model {
}

func dataRaceSafeListItem() -> Node<HTML.ListContext> {
guard Current.environment() != .production
else { return .empty }
guard Current.environment() != .production else { return .empty }
guard let swift6Readiness, swift6Readiness.dataRaceSafety == .safe else { return .empty }

return .li(
.class("data-race-safe"),
Expand Down
19 changes: 15 additions & 4 deletions Tests/AppTests/API+PackageController+GetRoute+ModelTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ class API_PackageController_GetRoute_ModelTests: SnapshotTestCase {
targets: [],
swiftVersionBuildInfo: nil,
platformBuildInfo: nil,
weightedKeywords: [])
weightedKeywords: [],
swift6Readiness: nil)

// validate
XCTAssertNotNil(m)
Expand All @@ -62,7 +63,8 @@ class API_PackageController_GetRoute_ModelTests: SnapshotTestCase {
targets: [],
swiftVersionBuildInfo: nil,
platformBuildInfo: nil,
weightedKeywords: []))
weightedKeywords: [],
swift6Readiness: nil))

// validate
XCTAssertEqual(model.packageIdentity, "swift-bar")
Expand All @@ -83,7 +85,8 @@ class API_PackageController_GetRoute_ModelTests: SnapshotTestCase {
targets: [],
swiftVersionBuildInfo: nil,
platformBuildInfo: nil,
weightedKeywords: []))
weightedKeywords: [],
swift6Readiness: nil))

// validate
XCTAssertEqual(model.documentationTarget, .internal(docVersion: .reference("main"), archive: "archive1"))
Expand All @@ -108,7 +111,8 @@ class API_PackageController_GetRoute_ModelTests: SnapshotTestCase {
targets: [],
swiftVersionBuildInfo: nil,
platformBuildInfo: nil,
weightedKeywords: []))
weightedKeywords: [],
swift6Readiness: nil))

// validate
XCTAssertEqual(model.documentationTarget, .external(url: "https://example.com/package/documentation"))
Expand Down Expand Up @@ -542,9 +546,16 @@ class API_PackageController_GetRoute_ModelTests: SnapshotTestCase {
)
}

func test_Swift6Readiness_dataRaceSafety() {
XCTAssertEqual(Swift6Readiness(errorCounts: [:]).dataRaceSafety, .unknown)
XCTAssertEqual(Swift6Readiness(errorCounts: [.iOS: 1]).dataRaceSafety, .unsafe)
XCTAssertEqual(Swift6Readiness(errorCounts: [.iOS: 1, .linux: 0]).dataRaceSafety, .safe)
}

}


// local typealiases / references to make tests more readable
fileprivate typealias BuildInfo = API.PackageController.GetRoute.Model.BuildInfo
fileprivate typealias BuildResults = API.PackageController.GetRoute.Model.SwiftVersionResults
fileprivate typealias Swift6Readiness = API.PackageController.GetRoute.Model.Swift6Readiness
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,8 @@ extension API.PackageController.GetRoute.Model {
isArchived: false,
defaultBranchReference: .branch("main"),
releaseReference: .tag(5, 2, 0),
preReleaseReference: .tag(5, 3, 0, "beta.1")
preReleaseReference: .tag(5, 3, 0, "beta.1"),
swift6Readiness: nil
)
}
}

0 comments on commit 6ddf4d6

Please sign in to comment.