From 6b038679108f76d156417c89280e7521ecec9991 Mon Sep 17 00:00:00 2001 From: Coen ten Thije Boonkkamp Date: Sun, 2 Aug 2026 13:00:08 +0200 Subject: [PATCH 1/5] Converge traversal errors to C5 leaves --- Package.swift | 16 +++++++ ...Organization.Repositories.Client+all.swift | 23 +++++----- ...Hub.Organization.Repositories.Client.swift | 6 +-- ...Organization.Repositories.Page.Error.swift | 6 +++ ...tHub.Organization.Repositories.Page.swift} | 2 +- ...ization.Repositories.Traversal.Error.swift | 8 ++-- ...Hub.Repository.Stargazers.Client+all.swift | 21 ++++++---- .../GitHub.Repository.Stargazers.Client.swift | 6 +-- ...Hub.Repository.Stargazers.Page.Error.swift | 7 ++++ ...> GitHub.Repository.Stargazers.Page.swift} | 2 +- ...epository.Stargazers.Traversal.Error.swift | 8 ++-- .../GitHub.User.Repositories.Client+all.swift | 21 ++++++---- .../GitHub.User.Repositories.Client.swift | 6 +-- .../GitHub.User.Repositories.Page.Error.swift | 9 ++++ ...ft => GitHub.User.Repositories.Page.swift} | 2 +- ...ub.User.Repositories.Traversal.Error.swift | 8 ++-- Sources/GitHub/exports.swift | 2 + ...ganization.Repositories.Client Tests.swift | 27 +++++++----- ...b.Repository.Stargazers.Client Tests.swift | 42 ++++++++----------- ...itHub.User.Repositories.Client Tests.swift | 42 ++++++++----------- 20 files changed, 150 insertions(+), 114 deletions(-) create mode 100644 Sources/GitHub/GitHub.Organization.Repositories.Page.Error.swift rename Sources/GitHub/{GitHub.Organization.Repositories.Client.Page.swift => GitHub.Organization.Repositories.Page.swift} (89%) create mode 100644 Sources/GitHub/GitHub.Repository.Stargazers.Page.Error.swift rename Sources/GitHub/{GitHub.Repository.Stargazers.Client.Page.swift => GitHub.Repository.Stargazers.Page.swift} (89%) create mode 100644 Sources/GitHub/GitHub.User.Repositories.Page.Error.swift rename Sources/GitHub/{GitHub.User.Repositories.Client.Page.swift => GitHub.User.Repositories.Page.swift} (89%) diff --git a/Package.swift b/Package.swift index 5a76209..d80bb07 100644 --- a/Package.swift +++ b/Package.swift @@ -18,6 +18,14 @@ let package = Package( ) ], dependencies: [ + .package( + url: "https://github.com/swift-primitives/swift-async-primitives.git", + branch: "main" + ), + .package( + url: "https://github.com/swift-primitives/swift-either-primitives.git", + branch: "main" + ), .package( url: "https://github.com/swift-standards/swift-github-standard.git", branch: "main" @@ -27,6 +35,14 @@ let package = Package( .target( name: "GitHub", dependencies: [ + .product( + name: "Async Lifecycle Primitives", + package: "swift-async-primitives" + ), + .product( + name: "Either Primitives", + package: "swift-either-primitives" + ), .product( name: "GitHub Standard", package: "swift-github-standard" diff --git a/Sources/GitHub/GitHub.Organization.Repositories.Client+all.swift b/Sources/GitHub/GitHub.Organization.Repositories.Client+all.swift index 4318486..a56bb1e 100644 --- a/Sources/GitHub/GitHub.Organization.Repositories.Client+all.swift +++ b/Sources/GitHub/GitHub.Organization.Repositories.Client+all.swift @@ -4,7 +4,7 @@ extension GitHub.Organization.Repositories.Client { limit: GitHub.Organization.Repositories.Traversal.Limit, duplicate: GitHub.Organization.Repositories.Traversal.Duplicate, order: GitHub.Organization.Repositories.Traversal.Order - ) async throws(GitHub.Organization.Repositories.Traversal.Error) -> [GitHub.Repository + ) async throws(Either) -> [GitHub.Repository .Summary] { var repositories: [GitHub.Repository.Summary] = [] @@ -14,21 +14,24 @@ extension GitHub.Organization.Repositories.Client { var pages: UInt = 0 while let request = current { - guard !Task.isCancelled else { throw .cancellation } + guard !Task.isCancelled else { throw .left(.cancelled) } // swift-linter:disable:next raw value access // REASON: same-package implementation comparing against the // Traversal.Limit boundary type's own raw page count. - guard pages < limit.pages.rawValue else { throw .pages } - guard requests.insert(request).inserted else { throw .cycle } + guard pages < limit.pages.rawValue else { throw .right(.pages) } + guard requests.insert(request).inserted else { throw .right(.cycle) } - let page: Page - do throws(Failure) { + let page: GitHub.Organization.Repositories.Page + do throws(Either) { page = try await self.page(request) } catch { - throw .client(error) + switch error { + case .left(let error): throw .left(error) + case .right(let error): throw .right(.page(error)) + } } - guard !Task.isCancelled else { throw .cancellation } + guard !Task.isCancelled else { throw .left(.cancelled) } pages += 1 for repository in page.response.repositories { @@ -51,7 +54,7 @@ extension GitHub.Organization.Repositories.Client { case .reject: guard positions[repository.id] == nil else { - throw .duplicate(repository.id) + throw .right(.duplicate(repository.id)) } positions[repository.id] = repositories.endIndex repositories.append(repository) @@ -61,7 +64,7 @@ extension GitHub.Organization.Repositories.Client { // REASON: same-package implementation comparing against the // Traversal.Limit boundary type's own raw item count. guard UInt(repositories.count) <= limit.items.rawValue else { - throw .items + throw .right(.items) } } diff --git a/Sources/GitHub/GitHub.Organization.Repositories.Client.swift b/Sources/GitHub/GitHub.Organization.Repositories.Client.swift index 4ff1462..65c0b78 100644 --- a/Sources/GitHub/GitHub.Organization.Repositories.Client.swift +++ b/Sources/GitHub/GitHub.Organization.Repositories.Client.swift @@ -1,9 +1,9 @@ extension GitHub.Organization.Repositories { - public struct Client: Sendable { - public var page: @Sendable (Request) async throws(Failure) -> Page + public struct Client: Sendable { + public var page: @Sendable (Request) async throws(Either) -> Page public init( - page: @escaping @Sendable (Request) async throws(Failure) -> Page + page: @escaping @Sendable (Request) async throws(Either) -> Page ) { self.page = page } diff --git a/Sources/GitHub/GitHub.Organization.Repositories.Page.Error.swift b/Sources/GitHub/GitHub.Organization.Repositories.Page.Error.swift new file mode 100644 index 0000000..d3d0ecb --- /dev/null +++ b/Sources/GitHub/GitHub.Organization.Repositories.Page.Error.swift @@ -0,0 +1,6 @@ +extension GitHub.Organization.Repositories.Page { + public enum Error: Swift.Error, Sendable, Equatable, Hashable { + case transport + case malformedResponse + } +} diff --git a/Sources/GitHub/GitHub.Organization.Repositories.Client.Page.swift b/Sources/GitHub/GitHub.Organization.Repositories.Page.swift similarity index 89% rename from Sources/GitHub/GitHub.Organization.Repositories.Client.Page.swift rename to Sources/GitHub/GitHub.Organization.Repositories.Page.swift index 6104a5e..43837b5 100644 --- a/Sources/GitHub/GitHub.Organization.Repositories.Client.Page.swift +++ b/Sources/GitHub/GitHub.Organization.Repositories.Page.swift @@ -1,4 +1,4 @@ -extension GitHub.Organization.Repositories.Client { +extension GitHub.Organization.Repositories { public struct Page: Equatable, Sendable { public let response: GitHub.Organization.Repositories.Response public let next: GitHub.Organization.Repositories.Request? diff --git a/Sources/GitHub/GitHub.Organization.Repositories.Traversal.Error.swift b/Sources/GitHub/GitHub.Organization.Repositories.Traversal.Error.swift index 0ee25d3..bc37ada 100644 --- a/Sources/GitHub/GitHub.Organization.Repositories.Traversal.Error.swift +++ b/Sources/GitHub/GitHub.Organization.Repositories.Traversal.Error.swift @@ -1,13 +1,11 @@ extension GitHub.Organization.Repositories.Traversal { - public enum Error: Swift.Error, Sendable { - case cancellation - case client(Failure) + public enum Error: Swift.Error, Sendable { case cycle case duplicate(GitHub.Repository.ID) case items + case page(GitHub.Organization.Repositories.Page.Error) case pages } } -extension GitHub.Organization.Repositories.Traversal.Error: Equatable -where Failure: Equatable {} +extension GitHub.Organization.Repositories.Traversal.Error: Equatable {} diff --git a/Sources/GitHub/GitHub.Repository.Stargazers.Client+all.swift b/Sources/GitHub/GitHub.Repository.Stargazers.Client+all.swift index eaaf2c9..165b3be 100644 --- a/Sources/GitHub/GitHub.Repository.Stargazers.Client+all.swift +++ b/Sources/GitHub/GitHub.Repository.Stargazers.Client+all.swift @@ -2,7 +2,7 @@ extension GitHub.Repository.Stargazers.Client { public func all( _ request: GitHub.Repository.Stargazers.Request, limit: GitHub.Repository.Stargazers.Traversal.Limit - ) async throws(GitHub.Repository.Stargazers.Traversal.Error) + ) async throws(Either) -> [GitHub.Repository.Stargazers.Stargazer] { var stargazers: [GitHub.Repository.Stargazers.Stargazer] = [] @@ -11,21 +11,24 @@ extension GitHub.Repository.Stargazers.Client { var pages: UInt = 0 while let request = current { - guard !Task.isCancelled else { throw .cancellation } + guard !Task.isCancelled else { throw .left(.cancelled) } // swift-linter:disable:next raw value access // REASON: same-package traversal-limit boundary — the page counter // is compared against the limit newtype's own raw magnitude. - guard pages < limit.pages.rawValue else { throw .pages } - guard requests.insert(request).inserted else { throw .cycle } + guard pages < limit.pages.rawValue else { throw .right(.pages) } + guard requests.insert(request).inserted else { throw .right(.cycle) } - let page: Page - do throws(Failure) { + let page: GitHub.Repository.Stargazers.Page + do throws(Either) { page = try await self.page(request) } catch { - throw .client(error) + switch error { + case .left(let error): throw .left(error) + case .right(let error): throw .right(.page(error)) + } } - guard !Task.isCancelled else { throw .cancellation } + guard !Task.isCancelled else { throw .left(.cancelled) } pages += 1 stargazers.append(contentsOf: page.response.stargazers) @@ -33,7 +36,7 @@ extension GitHub.Repository.Stargazers.Client { // REASON: same-package traversal-limit boundary — the accumulated // item count is compared against the limit newtype's raw magnitude. guard UInt(stargazers.count) <= limit.items.rawValue else { - throw .items + throw .right(.items) } current = page.next } diff --git a/Sources/GitHub/GitHub.Repository.Stargazers.Client.swift b/Sources/GitHub/GitHub.Repository.Stargazers.Client.swift index 563edec..d75c0ef 100644 --- a/Sources/GitHub/GitHub.Repository.Stargazers.Client.swift +++ b/Sources/GitHub/GitHub.Repository.Stargazers.Client.swift @@ -1,9 +1,9 @@ extension GitHub.Repository.Stargazers { - public struct Client: Sendable { - public var page: @Sendable (Request) async throws(Failure) -> Page + public struct Client: Sendable { + public var page: @Sendable (Request) async throws(Either) -> Page public init( - page: @escaping @Sendable (Request) async throws(Failure) -> Page + page: @escaping @Sendable (Request) async throws(Either) -> Page ) { self.page = page } diff --git a/Sources/GitHub/GitHub.Repository.Stargazers.Page.Error.swift b/Sources/GitHub/GitHub.Repository.Stargazers.Page.Error.swift new file mode 100644 index 0000000..51cadbe --- /dev/null +++ b/Sources/GitHub/GitHub.Repository.Stargazers.Page.Error.swift @@ -0,0 +1,7 @@ +extension GitHub.Repository.Stargazers.Page { + public enum Error: Swift.Error, Sendable, Equatable, Hashable { + case transport + case rejected + case malformedResponse + } +} diff --git a/Sources/GitHub/GitHub.Repository.Stargazers.Client.Page.swift b/Sources/GitHub/GitHub.Repository.Stargazers.Page.swift similarity index 89% rename from Sources/GitHub/GitHub.Repository.Stargazers.Client.Page.swift rename to Sources/GitHub/GitHub.Repository.Stargazers.Page.swift index 6b92fb1..8bb1f80 100644 --- a/Sources/GitHub/GitHub.Repository.Stargazers.Client.Page.swift +++ b/Sources/GitHub/GitHub.Repository.Stargazers.Page.swift @@ -1,4 +1,4 @@ -extension GitHub.Repository.Stargazers.Client { +extension GitHub.Repository.Stargazers { public struct Page: Equatable, Sendable { public let response: GitHub.Repository.Stargazers.Response public let next: GitHub.Repository.Stargazers.Request? diff --git a/Sources/GitHub/GitHub.Repository.Stargazers.Traversal.Error.swift b/Sources/GitHub/GitHub.Repository.Stargazers.Traversal.Error.swift index 6367c94..7e5a99c 100644 --- a/Sources/GitHub/GitHub.Repository.Stargazers.Traversal.Error.swift +++ b/Sources/GitHub/GitHub.Repository.Stargazers.Traversal.Error.swift @@ -1,12 +1,10 @@ extension GitHub.Repository.Stargazers.Traversal { - public enum Error: Swift.Error, Sendable { - case cancellation - case client(Failure) + public enum Error: Swift.Error, Sendable { case cycle case items + case page(GitHub.Repository.Stargazers.Page.Error) case pages } } -extension GitHub.Repository.Stargazers.Traversal.Error: Equatable -where Failure: Equatable {} +extension GitHub.Repository.Stargazers.Traversal.Error: Equatable {} diff --git a/Sources/GitHub/GitHub.User.Repositories.Client+all.swift b/Sources/GitHub/GitHub.User.Repositories.Client+all.swift index 3db5a3f..6ef8d61 100644 --- a/Sources/GitHub/GitHub.User.Repositories.Client+all.swift +++ b/Sources/GitHub/GitHub.User.Repositories.Client+all.swift @@ -2,7 +2,7 @@ extension GitHub.User.Repositories.Client { public func all( _ request: GitHub.User.Repositories.Request, limit: GitHub.User.Repositories.Traversal.Limit - ) async throws(GitHub.User.Repositories.Traversal.Error) + ) async throws(Either) -> [GitHub.Repository.Metadata] { var repositories: [GitHub.Repository.Metadata] = [] @@ -11,21 +11,24 @@ extension GitHub.User.Repositories.Client { var pages: UInt = 0 while let request = current { - guard !Task.isCancelled else { throw .cancellation } + guard !Task.isCancelled else { throw .left(.cancelled) } // swift-linter:disable:next raw value access // REASON: same-package traversal-limit boundary — the page counter // is compared against the limit newtype's own raw magnitude. - guard pages < limit.pages.rawValue else { throw .pages } - guard requests.insert(request).inserted else { throw .cycle } + guard pages < limit.pages.rawValue else { throw .right(.pages) } + guard requests.insert(request).inserted else { throw .right(.cycle) } - let page: Page - do throws(Failure) { + let page: GitHub.User.Repositories.Page + do throws(Either) { page = try await self.page(request) } catch { - throw .client(error) + switch error { + case .left(let error): throw .left(error) + case .right(let error): throw .right(.page(error)) + } } - guard !Task.isCancelled else { throw .cancellation } + guard !Task.isCancelled else { throw .left(.cancelled) } pages += 1 repositories.append(contentsOf: page.response.repositories) @@ -33,7 +36,7 @@ extension GitHub.User.Repositories.Client { // REASON: same-package traversal-limit boundary — the accumulated // item count is compared against the limit newtype's raw magnitude. guard UInt(repositories.count) <= limit.items.rawValue else { - throw .items + throw .right(.items) } current = page.next } diff --git a/Sources/GitHub/GitHub.User.Repositories.Client.swift b/Sources/GitHub/GitHub.User.Repositories.Client.swift index 61702d6..1453edb 100644 --- a/Sources/GitHub/GitHub.User.Repositories.Client.swift +++ b/Sources/GitHub/GitHub.User.Repositories.Client.swift @@ -1,9 +1,9 @@ extension GitHub.User.Repositories { - public struct Client: Sendable { - public var page: @Sendable (Request) async throws(Failure) -> Page + public struct Client: Sendable { + public var page: @Sendable (Request) async throws(Either) -> Page public init( - page: @escaping @Sendable (Request) async throws(Failure) -> Page + page: @escaping @Sendable (Request) async throws(Either) -> Page ) { self.page = page } diff --git a/Sources/GitHub/GitHub.User.Repositories.Page.Error.swift b/Sources/GitHub/GitHub.User.Repositories.Page.Error.swift new file mode 100644 index 0000000..51c4536 --- /dev/null +++ b/Sources/GitHub/GitHub.User.Repositories.Page.Error.swift @@ -0,0 +1,9 @@ +extension GitHub.User.Repositories.Page { + public enum Error: Swift.Error, Sendable, Equatable, Hashable { + case transport + case authentication + case forbidden + case rejected + case malformedResponse + } +} diff --git a/Sources/GitHub/GitHub.User.Repositories.Client.Page.swift b/Sources/GitHub/GitHub.User.Repositories.Page.swift similarity index 89% rename from Sources/GitHub/GitHub.User.Repositories.Client.Page.swift rename to Sources/GitHub/GitHub.User.Repositories.Page.swift index ae6738e..29a3154 100644 --- a/Sources/GitHub/GitHub.User.Repositories.Client.Page.swift +++ b/Sources/GitHub/GitHub.User.Repositories.Page.swift @@ -1,4 +1,4 @@ -extension GitHub.User.Repositories.Client { +extension GitHub.User.Repositories { public struct Page: Equatable, Sendable { public let response: GitHub.User.Repositories.Response public let next: GitHub.User.Repositories.Request? diff --git a/Sources/GitHub/GitHub.User.Repositories.Traversal.Error.swift b/Sources/GitHub/GitHub.User.Repositories.Traversal.Error.swift index 5f1ab7f..8090bfc 100644 --- a/Sources/GitHub/GitHub.User.Repositories.Traversal.Error.swift +++ b/Sources/GitHub/GitHub.User.Repositories.Traversal.Error.swift @@ -1,12 +1,10 @@ extension GitHub.User.Repositories.Traversal { - public enum Error: Swift.Error, Sendable { - case cancellation - case client(Failure) + public enum Error: Swift.Error, Sendable { case cycle case items + case page(GitHub.User.Repositories.Page.Error) case pages } } -extension GitHub.User.Repositories.Traversal.Error: Equatable -where Failure: Equatable {} +extension GitHub.User.Repositories.Traversal.Error: Equatable {} diff --git a/Sources/GitHub/exports.swift b/Sources/GitHub/exports.swift index a24ac5e..0a13c58 100644 --- a/Sources/GitHub/exports.swift +++ b/Sources/GitHub/exports.swift @@ -1 +1,3 @@ +@_exported public import Async_Lifecycle_Primitives +@_exported public import Either_Primitives @_exported public import GitHub_Standard diff --git a/Tests/GitHub Core Tests/GitHub.Organization.Repositories.Client Tests.swift b/Tests/GitHub Core Tests/GitHub.Organization.Repositories.Client Tests.swift index 83c5471..c5a3179 100644 --- a/Tests/GitHub Core Tests/GitHub.Organization.Repositories.Client Tests.swift +++ b/Tests/GitHub Core Tests/GitHub.Organization.Repositories.Client Tests.swift @@ -37,9 +37,9 @@ extension GitHub.Organization.Repositories { #expect(repositories.map(\.id.underlying) == [2, 1, 3]) await #expect( - throws: GitHub.Organization.Repositories.Traversal.Error.duplicate( - .init(1) - ) + throws: + Either + .right(.duplicate(.init(1))) ) { try await client.all( request, @@ -54,7 +54,9 @@ extension GitHub.Organization.Repositories { func limit() async throws { let client = try self.client() await #expect( - throws: GitHub.Organization.Repositories.Traversal.Error.pages + throws: + Either + .right(.pages) ) { try await client.all( request(page: .first), @@ -79,23 +81,26 @@ extension GitHub.Organization.Repositories { task.cancel() await #expect( - throws: GitHub.Organization.Repositories.Traversal.Error - .cancellation + throws: + Either + .left(.cancelled) ) { try await task.value } } - private func client() throws(Fixture.Failure) -> Client { + private func client() throws(Fixture.Failure) -> Client { let second = try self.page(2) return Client { - (request: GitHub.Organization.Repositories.Request) async throws(Fixture.Failure) in + (request: GitHub.Organization.Repositories.Request) async throws( + Either + ) in // swift-linter:disable:next raw value access // REASON: test-only fixture switching on the request's raw // page number to script per-page responses. switch request.page.rawValue { case 1: - return Client.Page( + return Page( response: .init( repositories: [ repository(id: 2, name: "beta"), @@ -106,7 +111,7 @@ extension GitHub.Organization.Repositories { ) case 2: - return Client.Page( + return Page( response: .init( repositories: [ repository(id: 1, name: "alpha-later"), @@ -117,7 +122,7 @@ extension GitHub.Organization.Repositories { ) default: - throw .unexpected + throw .right(.transport) } } } diff --git a/Tests/GitHub Core Tests/GitHub.Repository.Stargazers.Client Tests.swift b/Tests/GitHub Core Tests/GitHub.Repository.Stargazers.Client Tests.swift index 0715466..c6ada30 100644 --- a/Tests/GitHub Core Tests/GitHub.Repository.Stargazers.Client Tests.swift +++ b/Tests/GitHub Core Tests/GitHub.Repository.Stargazers.Client Tests.swift @@ -6,16 +6,16 @@ extension GitHub.Repository.Stargazers { @Suite("GitHub.Repository.Stargazers.Client.Unit") struct Core { @Test("Traversal follows stargazer pages") - func traversal() async throws(Traversal.Error) { + func traversal() async throws { guard let second = GitHub.Page.Number(rawValue: 2) else { Issue.record("invalid page fixture") return } let owner = GitHub.Owner.Login("swiftlang") let repository = GitHub.Repository.Name("swift") - let client = Client { - (request: Request) async throws(GitHub.Repository.Fixture.Failure) - -> Client.Page in + let client = Client { + (request: Request) async throws(Either) + -> Page in // swift-linter:disable:next raw value access // REASON: the fixture pages by the newtype's raw wire number — // the test's purpose is the paging boundary itself. @@ -35,7 +35,7 @@ extension GitHub.Repository.Stargazers { return .init(response: .init(stargazers: []), next: nil) default: - throw .unexpected + throw .right(.transport) } } @@ -64,16 +64,14 @@ extension GitHub.Repository.Stargazers { page: .first, size: .maximum ) - let failing = Client { - (_: Request) async throws(GitHub.Repository.Fixture.Failure) - -> Client.Page in - throw .expected + let failing = Client { + (_: Request) async throws(Either) -> Page in + throw .right(.transport) } await #expect( throws: - GitHub.Repository.Stargazers.Traversal.Error< - GitHub.Repository.Fixture.Failure - >.client(.expected) + Either + .right(.page(.transport)) ) { try await failing.all( request, @@ -81,16 +79,14 @@ extension GitHub.Repository.Stargazers { ) } - let cycling = Client { - (_: Request) async throws(GitHub.Repository.Fixture.Failure) - -> Client.Page in + let cycling = Client { + (_: Request) async throws(Either) -> Page in .init(response: .init(stargazers: []), next: request) } await #expect( throws: - GitHub.Repository.Stargazers.Traversal.Error< - GitHub.Repository.Fixture.Failure - >.cycle + Either + .right(.cycle) ) { try await cycling.all( request, @@ -99,9 +95,8 @@ extension GitHub.Repository.Stargazers { } await #expect( throws: - GitHub.Repository.Stargazers.Traversal.Error< - GitHub.Repository.Fixture.Failure - >.pages + Either + .right(.pages) ) { try await cycling.all( request, @@ -118,9 +113,8 @@ extension GitHub.Repository.Stargazers { task.cancel() await #expect( throws: - GitHub.Repository.Stargazers.Traversal.Error< - GitHub.Repository.Fixture.Failure - >.cancellation + Either + .left(.cancelled) ) { try await task.value } diff --git a/Tests/GitHub Core Tests/GitHub.User.Repositories.Client Tests.swift b/Tests/GitHub Core Tests/GitHub.User.Repositories.Client Tests.swift index 7ae7779..08872fa 100644 --- a/Tests/GitHub Core Tests/GitHub.User.Repositories.Client Tests.swift +++ b/Tests/GitHub Core Tests/GitHub.User.Repositories.Client Tests.swift @@ -6,14 +6,14 @@ extension GitHub.User.Repositories { @Suite("GitHub.User.Repositories.Client.Unit") struct Core { @Test("Traversal follows authenticated-user repository pages") - func traversal() async throws(Traversal.Error) { + func traversal() async throws { guard let second = GitHub.Page.Number(rawValue: 2) else { Issue.record("invalid page fixture") return } - let client = Client { - (request: Request) async throws(GitHub.Repository.Fixture.Failure) - -> Client.Page in + let client = Client { + (request: Request) async throws(Either) + -> Page in // swift-linter:disable:next raw value access // REASON: the fixture pages by the newtype's raw wire number — // the test's purpose is the paging boundary itself. @@ -28,7 +28,7 @@ extension GitHub.User.Repositories { return .init(response: .init(repositories: []), next: nil) default: - throw .unexpected + throw .right(.transport) } } @@ -50,16 +50,14 @@ extension GitHub.User.Repositories { page: .first, size: .maximum ) - let failing = Client { - (_: Request) async throws(GitHub.Repository.Fixture.Failure) - -> Client.Page in - throw .expected + let failing = Client { + (_: Request) async throws(Either) -> Page in + throw .right(.transport) } await #expect( throws: - GitHub.User.Repositories.Traversal.Error< - GitHub.Repository.Fixture.Failure - >.client(.expected) + Either + .right(.page(.transport)) ) { try await failing.all( request, @@ -67,16 +65,14 @@ extension GitHub.User.Repositories { ) } - let cycling = Client { - (_: Request) async throws(GitHub.Repository.Fixture.Failure) - -> Client.Page in + let cycling = Client { + (_: Request) async throws(Either) -> Page in .init(response: .init(repositories: []), next: request) } await #expect( throws: - GitHub.User.Repositories.Traversal.Error< - GitHub.Repository.Fixture.Failure - >.cycle + Either + .right(.cycle) ) { try await cycling.all( request, @@ -85,9 +81,8 @@ extension GitHub.User.Repositories { } await #expect( throws: - GitHub.User.Repositories.Traversal.Error< - GitHub.Repository.Fixture.Failure - >.pages + Either + .right(.pages) ) { try await cycling.all( request, @@ -104,9 +99,8 @@ extension GitHub.User.Repositories { task.cancel() await #expect( throws: - GitHub.User.Repositories.Traversal.Error< - GitHub.Repository.Fixture.Failure - >.cancellation + Either + .left(.cancelled) ) { try await task.value } From 0f49fa7f4a4ca30cde29d81f5c7b7522574cddac Mon Sep 17 00:00:00 2001 From: Coen ten Thije Boonkkamp Date: Sun, 2 Aug 2026 13:16:24 +0200 Subject: [PATCH 2/5] Apply Swift 6.3.3 formatting --- .../GitHub.Organization.Repositories.Client+all.swift | 3 ++- .../GitHub/GitHub.Organization.Repositories.Client.swift | 8 ++++++-- Sources/GitHub/GitHub.Repository.Stargazers.Client.swift | 8 ++++++-- Sources/GitHub/GitHub.User.Repositories.Client.swift | 8 ++++++-- .../GitHub.Organization.Repositories.Client Tests.swift | 6 +++--- .../GitHub.Repository.Stargazers.Client Tests.swift | 8 ++++---- .../GitHub.User.Repositories.Client Tests.swift | 8 ++++---- 7 files changed, 31 insertions(+), 18 deletions(-) diff --git a/Sources/GitHub/GitHub.Organization.Repositories.Client+all.swift b/Sources/GitHub/GitHub.Organization.Repositories.Client+all.swift index a56bb1e..4d950b1 100644 --- a/Sources/GitHub/GitHub.Organization.Repositories.Client+all.swift +++ b/Sources/GitHub/GitHub.Organization.Repositories.Client+all.swift @@ -4,7 +4,8 @@ extension GitHub.Organization.Repositories.Client { limit: GitHub.Organization.Repositories.Traversal.Limit, duplicate: GitHub.Organization.Repositories.Traversal.Duplicate, order: GitHub.Organization.Repositories.Traversal.Order - ) async throws(Either) -> [GitHub.Repository + ) async throws(Either) + -> [GitHub.Repository .Summary] { var repositories: [GitHub.Repository.Summary] = [] diff --git a/Sources/GitHub/GitHub.Organization.Repositories.Client.swift b/Sources/GitHub/GitHub.Organization.Repositories.Client.swift index 65c0b78..14e0dcd 100644 --- a/Sources/GitHub/GitHub.Organization.Repositories.Client.swift +++ b/Sources/GitHub/GitHub.Organization.Repositories.Client.swift @@ -1,9 +1,13 @@ extension GitHub.Organization.Repositories { public struct Client: Sendable { - public var page: @Sendable (Request) async throws(Either) -> Page + public var page: + @Sendable (Request) async throws(Either) -> Page public init( - page: @escaping @Sendable (Request) async throws(Either) -> Page + page: + @escaping @Sendable (Request) async throws(Either< + Async.Lifecycle.Error, Page.Error + >) -> Page ) { self.page = page } diff --git a/Sources/GitHub/GitHub.Repository.Stargazers.Client.swift b/Sources/GitHub/GitHub.Repository.Stargazers.Client.swift index d75c0ef..45afe9d 100644 --- a/Sources/GitHub/GitHub.Repository.Stargazers.Client.swift +++ b/Sources/GitHub/GitHub.Repository.Stargazers.Client.swift @@ -1,9 +1,13 @@ extension GitHub.Repository.Stargazers { public struct Client: Sendable { - public var page: @Sendable (Request) async throws(Either) -> Page + public var page: + @Sendable (Request) async throws(Either) -> Page public init( - page: @escaping @Sendable (Request) async throws(Either) -> Page + page: + @escaping @Sendable (Request) async throws(Either< + Async.Lifecycle.Error, Page.Error + >) -> Page ) { self.page = page } diff --git a/Sources/GitHub/GitHub.User.Repositories.Client.swift b/Sources/GitHub/GitHub.User.Repositories.Client.swift index 1453edb..98fda49 100644 --- a/Sources/GitHub/GitHub.User.Repositories.Client.swift +++ b/Sources/GitHub/GitHub.User.Repositories.Client.swift @@ -1,9 +1,13 @@ extension GitHub.User.Repositories { public struct Client: Sendable { - public var page: @Sendable (Request) async throws(Either) -> Page + public var page: + @Sendable (Request) async throws(Either) -> Page public init( - page: @escaping @Sendable (Request) async throws(Either) -> Page + page: + @escaping @Sendable (Request) async throws(Either< + Async.Lifecycle.Error, Page.Error + >) -> Page ) { self.page = page } diff --git a/Tests/GitHub Core Tests/GitHub.Organization.Repositories.Client Tests.swift b/Tests/GitHub Core Tests/GitHub.Organization.Repositories.Client Tests.swift index c5a3179..719ebdd 100644 --- a/Tests/GitHub Core Tests/GitHub.Organization.Repositories.Client Tests.swift +++ b/Tests/GitHub Core Tests/GitHub.Organization.Repositories.Client Tests.swift @@ -92,9 +92,9 @@ extension GitHub.Organization.Repositories { private func client() throws(Fixture.Failure) -> Client { let second = try self.page(2) return Client { - (request: GitHub.Organization.Repositories.Request) async throws( - Either - ) in + (request: GitHub.Organization.Repositories.Request) async throws(Either< + Async.Lifecycle.Error, Page.Error + >) in // swift-linter:disable:next raw value access // REASON: test-only fixture switching on the request's raw // page number to script per-page responses. diff --git a/Tests/GitHub Core Tests/GitHub.Repository.Stargazers.Client Tests.swift b/Tests/GitHub Core Tests/GitHub.Repository.Stargazers.Client Tests.swift index c6ada30..7347c5d 100644 --- a/Tests/GitHub Core Tests/GitHub.Repository.Stargazers.Client Tests.swift +++ b/Tests/GitHub Core Tests/GitHub.Repository.Stargazers.Client Tests.swift @@ -71,7 +71,7 @@ extension GitHub.Repository.Stargazers { await #expect( throws: Either - .right(.page(.transport)) + .right(.page(.transport)) ) { try await failing.all( request, @@ -86,7 +86,7 @@ extension GitHub.Repository.Stargazers { await #expect( throws: Either - .right(.cycle) + .right(.cycle) ) { try await cycling.all( request, @@ -96,7 +96,7 @@ extension GitHub.Repository.Stargazers { await #expect( throws: Either - .right(.pages) + .right(.pages) ) { try await cycling.all( request, @@ -114,7 +114,7 @@ extension GitHub.Repository.Stargazers { await #expect( throws: Either - .left(.cancelled) + .left(.cancelled) ) { try await task.value } diff --git a/Tests/GitHub Core Tests/GitHub.User.Repositories.Client Tests.swift b/Tests/GitHub Core Tests/GitHub.User.Repositories.Client Tests.swift index 08872fa..e2116c8 100644 --- a/Tests/GitHub Core Tests/GitHub.User.Repositories.Client Tests.swift +++ b/Tests/GitHub Core Tests/GitHub.User.Repositories.Client Tests.swift @@ -57,7 +57,7 @@ extension GitHub.User.Repositories { await #expect( throws: Either - .right(.page(.transport)) + .right(.page(.transport)) ) { try await failing.all( request, @@ -72,7 +72,7 @@ extension GitHub.User.Repositories { await #expect( throws: Either - .right(.cycle) + .right(.cycle) ) { try await cycling.all( request, @@ -82,7 +82,7 @@ extension GitHub.User.Repositories { await #expect( throws: Either - .right(.pages) + .right(.pages) ) { try await cycling.all( request, @@ -100,7 +100,7 @@ extension GitHub.User.Repositories { await #expect( throws: Either - .left(.cancelled) + .left(.cancelled) ) { try await task.value } From 7fb24ee40ce83ed5ed0ec549cf74f08ba0016176 Mon Sep 17 00:00:00 2001 From: Coen ten Thije Boonkkamp Date: Sun, 2 Aug 2026 14:30:54 +0200 Subject: [PATCH 3/5] Decompose GitHub resources into products --- Package.swift | 124 +++++++++++++++++- .../GitHub.OAuth.Authorization.Client.swift | 0 .../GitHub.OAuth.Token.Exchange.Client.swift | 0 Sources/GitHub OAuth/exports.swift | 1 + ...Organization.Repositories.Client+all.swift | 0 ...Hub.Organization.Repositories.Client.swift | 0 ...Organization.Repositories.Page.Error.swift | 0 ...itHub.Organization.Repositories.Page.swift | 0 ...ion.Repositories.Traversal.Duplicate.swift | 0 ...ization.Repositories.Traversal.Error.swift | 0 ...n.Repositories.Traversal.Limit.Items.swift | 0 ...n.Repositories.Traversal.Limit.Pages.swift | 0 ...ization.Repositories.Traversal.Limit.swift | 0 ...ization.Repositories.Traversal.Order.swift | 0 ....Organization.Repositories.Traversal.swift | 0 Sources/GitHub Organizations/exports.swift | 3 + .../GitHub.Repository.Content.Client.swift | 0 .../GitHub.Repository.Get.Client.swift | 0 Sources/GitHub Repositories/exports.swift | 3 +- ...Hub.Repository.Stargazers.Client+all.swift | 0 .../GitHub.Repository.Stargazers.Client.swift | 0 ...Hub.Repository.Stargazers.Page.Error.swift | 0 .../GitHub.Repository.Stargazers.Page.swift | 0 ...epository.Stargazers.Traversal.Error.swift | 0 ...ory.Stargazers.Traversal.Limit.Items.swift | 0 ...ory.Stargazers.Traversal.Limit.Pages.swift | 0 ...epository.Stargazers.Traversal.Limit.swift | 0 ...tHub.Repository.Stargazers.Traversal.swift | 0 Sources/GitHub Stargazers/exports.swift | 3 + .../GitHub.Repository.Traffic.Client.swift | 0 Sources/GitHub Traffic/exports.swift | 1 + ...ser.Authenticated.Emails.List.Client.swift | 0 ...GitHub.User.Authenticated.Get.Client.swift | 0 .../GitHub.User.Repositories.Client+all.swift | 0 .../GitHub.User.Repositories.Client.swift | 0 .../GitHub.User.Repositories.Page.Error.swift | 0 .../GitHub.User.Repositories.Page.swift | 0 ...ub.User.Repositories.Traversal.Error.swift | 0 ...r.Repositories.Traversal.Limit.Items.swift | 0 ...r.Repositories.Traversal.Limit.Pages.swift | 0 ...ub.User.Repositories.Traversal.Limit.swift | 0 .../GitHub.User.Repositories.Traversal.swift | 0 Sources/GitHub Users/exports.swift | 3 + Sources/GitHub/exports.swift | 9 +- .../GitHub.OAuth.Client Tests.swift | 2 +- .../GitHub.OAuth.Fixture.Failure.swift | 2 +- .../GitHub.OAuth.Fixture.swift | 2 +- ...ganization.Repositories.Client Tests.swift | 2 +- ...ization.Repositories.Fixture.Failure.swift | 2 +- ...ub.Organization.Repositories.Fixture.swift | 2 +- ...tHub.Repository.Content.Client Tests.swift | 2 +- .../GitHub.Repository.Fixture.Failure.swift | 2 +- .../GitHub.Repository.Fixture.swift | 2 +- .../GitHub.Repository.Get.Client Tests.swift | 2 +- ...b.Repository.Stargazers.Client Tests.swift | 6 +- ...epository.Stargazers.Fixture.Failure.swift | 7 + ...GitHub.Repository.Stargazers.Fixture.swift | 5 + ...tHub.Repository.Traffic.Client Tests.swift | 32 ++--- ...b.Repository.Traffic.Fixture.Failure.swift | 7 + .../GitHub.Repository.Traffic.Fixture.swift | 5 + ...tHub.User.Authenticated.Client Tests.swift | 14 +- .../GitHub.User.Fixture.Failure.swift | 8 ++ .../GitHub.User.Fixture.swift | 5 + ...itHub.User.Repositories.Client Tests.swift | 6 +- 64 files changed, 214 insertions(+), 48 deletions(-) rename Sources/{GitHub => GitHub OAuth}/GitHub.OAuth.Authorization.Client.swift (100%) rename Sources/{GitHub => GitHub OAuth}/GitHub.OAuth.Token.Exchange.Client.swift (100%) create mode 100644 Sources/GitHub OAuth/exports.swift rename Sources/{GitHub => GitHub Organizations}/GitHub.Organization.Repositories.Client+all.swift (100%) rename Sources/{GitHub => GitHub Organizations}/GitHub.Organization.Repositories.Client.swift (100%) rename Sources/{GitHub => GitHub Organizations}/GitHub.Organization.Repositories.Page.Error.swift (100%) rename Sources/{GitHub => GitHub Organizations}/GitHub.Organization.Repositories.Page.swift (100%) rename Sources/{GitHub => GitHub Organizations}/GitHub.Organization.Repositories.Traversal.Duplicate.swift (100%) rename Sources/{GitHub => GitHub Organizations}/GitHub.Organization.Repositories.Traversal.Error.swift (100%) rename Sources/{GitHub => GitHub Organizations}/GitHub.Organization.Repositories.Traversal.Limit.Items.swift (100%) rename Sources/{GitHub => GitHub Organizations}/GitHub.Organization.Repositories.Traversal.Limit.Pages.swift (100%) rename Sources/{GitHub => GitHub Organizations}/GitHub.Organization.Repositories.Traversal.Limit.swift (100%) rename Sources/{GitHub => GitHub Organizations}/GitHub.Organization.Repositories.Traversal.Order.swift (100%) rename Sources/{GitHub => GitHub Organizations}/GitHub.Organization.Repositories.Traversal.swift (100%) create mode 100644 Sources/GitHub Organizations/exports.swift rename Sources/{GitHub => GitHub Repositories}/GitHub.Repository.Content.Client.swift (100%) rename Sources/{GitHub => GitHub Repositories}/GitHub.Repository.Get.Client.swift (100%) rename Sources/{GitHub => GitHub Stargazers}/GitHub.Repository.Stargazers.Client+all.swift (100%) rename Sources/{GitHub => GitHub Stargazers}/GitHub.Repository.Stargazers.Client.swift (100%) rename Sources/{GitHub => GitHub Stargazers}/GitHub.Repository.Stargazers.Page.Error.swift (100%) rename Sources/{GitHub => GitHub Stargazers}/GitHub.Repository.Stargazers.Page.swift (100%) rename Sources/{GitHub => GitHub Stargazers}/GitHub.Repository.Stargazers.Traversal.Error.swift (100%) rename Sources/{GitHub => GitHub Stargazers}/GitHub.Repository.Stargazers.Traversal.Limit.Items.swift (100%) rename Sources/{GitHub => GitHub Stargazers}/GitHub.Repository.Stargazers.Traversal.Limit.Pages.swift (100%) rename Sources/{GitHub => GitHub Stargazers}/GitHub.Repository.Stargazers.Traversal.Limit.swift (100%) rename Sources/{GitHub => GitHub Stargazers}/GitHub.Repository.Stargazers.Traversal.swift (100%) create mode 100644 Sources/GitHub Stargazers/exports.swift rename Sources/{GitHub => GitHub Traffic}/GitHub.Repository.Traffic.Client.swift (100%) create mode 100644 Sources/GitHub Traffic/exports.swift rename Sources/{GitHub => GitHub Users}/GitHub.User.Authenticated.Emails.List.Client.swift (100%) rename Sources/{GitHub => GitHub Users}/GitHub.User.Authenticated.Get.Client.swift (100%) rename Sources/{GitHub => GitHub Users}/GitHub.User.Repositories.Client+all.swift (100%) rename Sources/{GitHub => GitHub Users}/GitHub.User.Repositories.Client.swift (100%) rename Sources/{GitHub => GitHub Users}/GitHub.User.Repositories.Page.Error.swift (100%) rename Sources/{GitHub => GitHub Users}/GitHub.User.Repositories.Page.swift (100%) rename Sources/{GitHub => GitHub Users}/GitHub.User.Repositories.Traversal.Error.swift (100%) rename Sources/{GitHub => GitHub Users}/GitHub.User.Repositories.Traversal.Limit.Items.swift (100%) rename Sources/{GitHub => GitHub Users}/GitHub.User.Repositories.Traversal.Limit.Pages.swift (100%) rename Sources/{GitHub => GitHub Users}/GitHub.User.Repositories.Traversal.Limit.swift (100%) rename Sources/{GitHub => GitHub Users}/GitHub.User.Repositories.Traversal.swift (100%) create mode 100644 Sources/GitHub Users/exports.swift rename Tests/{GitHub Core Tests => GitHub OAuth Core Tests}/GitHub.OAuth.Client Tests.swift (98%) rename Tests/{GitHub Core Tests => GitHub OAuth Core Tests}/GitHub.OAuth.Fixture.Failure.swift (79%) rename Tests/{GitHub Core Tests => GitHub OAuth Core Tests}/GitHub.OAuth.Fixture.swift (61%) rename Tests/{GitHub Core Tests => GitHub Organizations Core Tests}/GitHub.Organization.Repositories.Client Tests.swift (99%) rename Tests/{GitHub Core Tests => GitHub Organizations Core Tests}/GitHub.Organization.Repositories.Fixture.Failure.swift (78%) rename Tests/{GitHub Core Tests => GitHub Organizations Core Tests}/GitHub.Organization.Repositories.Fixture.swift (64%) rename Tests/{GitHub Core Tests => GitHub Repositories Core Tests}/GitHub.Repository.Content.Client Tests.swift (97%) rename Tests/{GitHub Core Tests => GitHub Repositories Core Tests}/GitHub.Repository.Fixture.Failure.swift (79%) rename Tests/{GitHub Core Tests => GitHub Repositories Core Tests}/GitHub.Repository.Fixture.swift (58%) rename Tests/{GitHub Core Tests => GitHub Repositories Core Tests}/GitHub.Repository.Get.Client Tests.swift (95%) rename Tests/{GitHub Core Tests => GitHub Stargazers Core Tests}/GitHub.Repository.Stargazers.Client Tests.swift (96%) create mode 100644 Tests/GitHub Stargazers Core Tests/GitHub.Repository.Stargazers.Fixture.Failure.swift create mode 100644 Tests/GitHub Stargazers Core Tests/GitHub.Repository.Stargazers.Fixture.swift rename Tests/{GitHub Core Tests => GitHub Traffic Core Tests}/GitHub.Repository.Traffic.Client Tests.swift (72%) create mode 100644 Tests/GitHub Traffic Core Tests/GitHub.Repository.Traffic.Fixture.Failure.swift create mode 100644 Tests/GitHub Traffic Core Tests/GitHub.Repository.Traffic.Fixture.swift rename Tests/{GitHub Core Tests => GitHub Users Core Tests}/GitHub.User.Authenticated.Client Tests.swift (65%) create mode 100644 Tests/GitHub Users Core Tests/GitHub.User.Fixture.Failure.swift create mode 100644 Tests/GitHub Users Core Tests/GitHub.User.Fixture.swift rename Tests/{GitHub Core Tests => GitHub Users Core Tests}/GitHub.User.Repositories.Client Tests.swift (97%) diff --git a/Package.swift b/Package.swift index d80bb07..92164b1 100644 --- a/Package.swift +++ b/Package.swift @@ -15,7 +15,31 @@ let package = Package( .library( name: "GitHub", targets: ["GitHub"] - ) + ), + .library( + name: "GitHub OAuth", + targets: ["GitHub OAuth"] + ), + .library( + name: "GitHub Organizations", + targets: ["GitHub Organizations"] + ), + .library( + name: "GitHub Repositories", + targets: ["GitHub Repositories"] + ), + .library( + name: "GitHub Stargazers", + targets: ["GitHub Stargazers"] + ), + .library( + name: "GitHub Traffic", + targets: ["GitHub Traffic"] + ), + .library( + name: "GitHub Users", + targets: ["GitHub Users"] + ), ], dependencies: [ .package( @@ -29,11 +53,69 @@ let package = Package( .package( url: "https://github.com/swift-standards/swift-github-standard.git", branch: "main" - ) + ), ], targets: [ .target( name: "GitHub", + dependencies: [ + .target(name: "GitHub OAuth"), + .target(name: "GitHub Organizations"), + .target(name: "GitHub Repositories"), + .target(name: "GitHub Stargazers"), + .target(name: "GitHub Traffic"), + .target(name: "GitHub Users"), + ] + ), + .target( + name: "GitHub OAuth", + dependencies: [ + .product( + name: "GitHub Standard", + package: "swift-github-standard" + ) + ] + ), + .testTarget( + name: "GitHub OAuth Core Tests", + dependencies: [.target(name: "GitHub OAuth")] + ), + .target( + name: "GitHub Organizations", + dependencies: [ + .product( + name: "Async Lifecycle Primitives", + package: "swift-async-primitives" + ), + .product( + name: "Either Primitives", + package: "swift-either-primitives" + ), + .product( + name: "GitHub Standard", + package: "swift-github-standard" + ), + ] + ), + .testTarget( + name: "GitHub Organizations Core Tests", + dependencies: [.target(name: "GitHub Organizations")] + ), + .target( + name: "GitHub Repositories", + dependencies: [ + .product( + name: "GitHub Standard", + package: "swift-github-standard" + ) + ] + ), + .testTarget( + name: "GitHub Repositories Core Tests", + dependencies: [.target(name: "GitHub Repositories")] + ), + .target( + name: "GitHub Stargazers", dependencies: [ .product( name: "Async Lifecycle Primitives", @@ -43,6 +125,19 @@ let package = Package( name: "Either Primitives", package: "swift-either-primitives" ), + .product( + name: "GitHub Standard", + package: "swift-github-standard" + ), + ] + ), + .testTarget( + name: "GitHub Stargazers Core Tests", + dependencies: [.target(name: "GitHub Stargazers")] + ), + .target( + name: "GitHub Traffic", + dependencies: [ .product( name: "GitHub Standard", package: "swift-github-standard" @@ -50,8 +145,29 @@ let package = Package( ] ), .testTarget( - name: "GitHub Core Tests", - dependencies: ["GitHub"] + name: "GitHub Traffic Core Tests", + dependencies: [.target(name: "GitHub Traffic")] + ), + .target( + name: "GitHub Users", + dependencies: [ + .product( + name: "Async Lifecycle Primitives", + package: "swift-async-primitives" + ), + .product( + name: "Either Primitives", + package: "swift-either-primitives" + ), + .product( + name: "GitHub Standard", + package: "swift-github-standard" + ), + ] + ), + .testTarget( + name: "GitHub Users Core Tests", + dependencies: [.target(name: "GitHub Users")] ), ], swiftLanguageModes: [.v6] diff --git a/Sources/GitHub/GitHub.OAuth.Authorization.Client.swift b/Sources/GitHub OAuth/GitHub.OAuth.Authorization.Client.swift similarity index 100% rename from Sources/GitHub/GitHub.OAuth.Authorization.Client.swift rename to Sources/GitHub OAuth/GitHub.OAuth.Authorization.Client.swift diff --git a/Sources/GitHub/GitHub.OAuth.Token.Exchange.Client.swift b/Sources/GitHub OAuth/GitHub.OAuth.Token.Exchange.Client.swift similarity index 100% rename from Sources/GitHub/GitHub.OAuth.Token.Exchange.Client.swift rename to Sources/GitHub OAuth/GitHub.OAuth.Token.Exchange.Client.swift diff --git a/Sources/GitHub OAuth/exports.swift b/Sources/GitHub OAuth/exports.swift new file mode 100644 index 0000000..a24ac5e --- /dev/null +++ b/Sources/GitHub OAuth/exports.swift @@ -0,0 +1 @@ +@_exported public import GitHub_Standard diff --git a/Sources/GitHub/GitHub.Organization.Repositories.Client+all.swift b/Sources/GitHub Organizations/GitHub.Organization.Repositories.Client+all.swift similarity index 100% rename from Sources/GitHub/GitHub.Organization.Repositories.Client+all.swift rename to Sources/GitHub Organizations/GitHub.Organization.Repositories.Client+all.swift diff --git a/Sources/GitHub/GitHub.Organization.Repositories.Client.swift b/Sources/GitHub Organizations/GitHub.Organization.Repositories.Client.swift similarity index 100% rename from Sources/GitHub/GitHub.Organization.Repositories.Client.swift rename to Sources/GitHub Organizations/GitHub.Organization.Repositories.Client.swift diff --git a/Sources/GitHub/GitHub.Organization.Repositories.Page.Error.swift b/Sources/GitHub Organizations/GitHub.Organization.Repositories.Page.Error.swift similarity index 100% rename from Sources/GitHub/GitHub.Organization.Repositories.Page.Error.swift rename to Sources/GitHub Organizations/GitHub.Organization.Repositories.Page.Error.swift diff --git a/Sources/GitHub/GitHub.Organization.Repositories.Page.swift b/Sources/GitHub Organizations/GitHub.Organization.Repositories.Page.swift similarity index 100% rename from Sources/GitHub/GitHub.Organization.Repositories.Page.swift rename to Sources/GitHub Organizations/GitHub.Organization.Repositories.Page.swift diff --git a/Sources/GitHub/GitHub.Organization.Repositories.Traversal.Duplicate.swift b/Sources/GitHub Organizations/GitHub.Organization.Repositories.Traversal.Duplicate.swift similarity index 100% rename from Sources/GitHub/GitHub.Organization.Repositories.Traversal.Duplicate.swift rename to Sources/GitHub Organizations/GitHub.Organization.Repositories.Traversal.Duplicate.swift diff --git a/Sources/GitHub/GitHub.Organization.Repositories.Traversal.Error.swift b/Sources/GitHub Organizations/GitHub.Organization.Repositories.Traversal.Error.swift similarity index 100% rename from Sources/GitHub/GitHub.Organization.Repositories.Traversal.Error.swift rename to Sources/GitHub Organizations/GitHub.Organization.Repositories.Traversal.Error.swift diff --git a/Sources/GitHub/GitHub.Organization.Repositories.Traversal.Limit.Items.swift b/Sources/GitHub Organizations/GitHub.Organization.Repositories.Traversal.Limit.Items.swift similarity index 100% rename from Sources/GitHub/GitHub.Organization.Repositories.Traversal.Limit.Items.swift rename to Sources/GitHub Organizations/GitHub.Organization.Repositories.Traversal.Limit.Items.swift diff --git a/Sources/GitHub/GitHub.Organization.Repositories.Traversal.Limit.Pages.swift b/Sources/GitHub Organizations/GitHub.Organization.Repositories.Traversal.Limit.Pages.swift similarity index 100% rename from Sources/GitHub/GitHub.Organization.Repositories.Traversal.Limit.Pages.swift rename to Sources/GitHub Organizations/GitHub.Organization.Repositories.Traversal.Limit.Pages.swift diff --git a/Sources/GitHub/GitHub.Organization.Repositories.Traversal.Limit.swift b/Sources/GitHub Organizations/GitHub.Organization.Repositories.Traversal.Limit.swift similarity index 100% rename from Sources/GitHub/GitHub.Organization.Repositories.Traversal.Limit.swift rename to Sources/GitHub Organizations/GitHub.Organization.Repositories.Traversal.Limit.swift diff --git a/Sources/GitHub/GitHub.Organization.Repositories.Traversal.Order.swift b/Sources/GitHub Organizations/GitHub.Organization.Repositories.Traversal.Order.swift similarity index 100% rename from Sources/GitHub/GitHub.Organization.Repositories.Traversal.Order.swift rename to Sources/GitHub Organizations/GitHub.Organization.Repositories.Traversal.Order.swift diff --git a/Sources/GitHub/GitHub.Organization.Repositories.Traversal.swift b/Sources/GitHub Organizations/GitHub.Organization.Repositories.Traversal.swift similarity index 100% rename from Sources/GitHub/GitHub.Organization.Repositories.Traversal.swift rename to Sources/GitHub Organizations/GitHub.Organization.Repositories.Traversal.swift diff --git a/Sources/GitHub Organizations/exports.swift b/Sources/GitHub Organizations/exports.swift new file mode 100644 index 0000000..0a13c58 --- /dev/null +++ b/Sources/GitHub Organizations/exports.swift @@ -0,0 +1,3 @@ +@_exported public import Async_Lifecycle_Primitives +@_exported public import Either_Primitives +@_exported public import GitHub_Standard diff --git a/Sources/GitHub/GitHub.Repository.Content.Client.swift b/Sources/GitHub Repositories/GitHub.Repository.Content.Client.swift similarity index 100% rename from Sources/GitHub/GitHub.Repository.Content.Client.swift rename to Sources/GitHub Repositories/GitHub.Repository.Content.Client.swift diff --git a/Sources/GitHub/GitHub.Repository.Get.Client.swift b/Sources/GitHub Repositories/GitHub.Repository.Get.Client.swift similarity index 100% rename from Sources/GitHub/GitHub.Repository.Get.Client.swift rename to Sources/GitHub Repositories/GitHub.Repository.Get.Client.swift diff --git a/Sources/GitHub Repositories/exports.swift b/Sources/GitHub Repositories/exports.swift index c1538fc..a24ac5e 100644 --- a/Sources/GitHub Repositories/exports.swift +++ b/Sources/GitHub Repositories/exports.swift @@ -1,2 +1 @@ -@_exported import GitHub_Repositories_Live -@_exported import GitHub_Shared +@_exported public import GitHub_Standard diff --git a/Sources/GitHub/GitHub.Repository.Stargazers.Client+all.swift b/Sources/GitHub Stargazers/GitHub.Repository.Stargazers.Client+all.swift similarity index 100% rename from Sources/GitHub/GitHub.Repository.Stargazers.Client+all.swift rename to Sources/GitHub Stargazers/GitHub.Repository.Stargazers.Client+all.swift diff --git a/Sources/GitHub/GitHub.Repository.Stargazers.Client.swift b/Sources/GitHub Stargazers/GitHub.Repository.Stargazers.Client.swift similarity index 100% rename from Sources/GitHub/GitHub.Repository.Stargazers.Client.swift rename to Sources/GitHub Stargazers/GitHub.Repository.Stargazers.Client.swift diff --git a/Sources/GitHub/GitHub.Repository.Stargazers.Page.Error.swift b/Sources/GitHub Stargazers/GitHub.Repository.Stargazers.Page.Error.swift similarity index 100% rename from Sources/GitHub/GitHub.Repository.Stargazers.Page.Error.swift rename to Sources/GitHub Stargazers/GitHub.Repository.Stargazers.Page.Error.swift diff --git a/Sources/GitHub/GitHub.Repository.Stargazers.Page.swift b/Sources/GitHub Stargazers/GitHub.Repository.Stargazers.Page.swift similarity index 100% rename from Sources/GitHub/GitHub.Repository.Stargazers.Page.swift rename to Sources/GitHub Stargazers/GitHub.Repository.Stargazers.Page.swift diff --git a/Sources/GitHub/GitHub.Repository.Stargazers.Traversal.Error.swift b/Sources/GitHub Stargazers/GitHub.Repository.Stargazers.Traversal.Error.swift similarity index 100% rename from Sources/GitHub/GitHub.Repository.Stargazers.Traversal.Error.swift rename to Sources/GitHub Stargazers/GitHub.Repository.Stargazers.Traversal.Error.swift diff --git a/Sources/GitHub/GitHub.Repository.Stargazers.Traversal.Limit.Items.swift b/Sources/GitHub Stargazers/GitHub.Repository.Stargazers.Traversal.Limit.Items.swift similarity index 100% rename from Sources/GitHub/GitHub.Repository.Stargazers.Traversal.Limit.Items.swift rename to Sources/GitHub Stargazers/GitHub.Repository.Stargazers.Traversal.Limit.Items.swift diff --git a/Sources/GitHub/GitHub.Repository.Stargazers.Traversal.Limit.Pages.swift b/Sources/GitHub Stargazers/GitHub.Repository.Stargazers.Traversal.Limit.Pages.swift similarity index 100% rename from Sources/GitHub/GitHub.Repository.Stargazers.Traversal.Limit.Pages.swift rename to Sources/GitHub Stargazers/GitHub.Repository.Stargazers.Traversal.Limit.Pages.swift diff --git a/Sources/GitHub/GitHub.Repository.Stargazers.Traversal.Limit.swift b/Sources/GitHub Stargazers/GitHub.Repository.Stargazers.Traversal.Limit.swift similarity index 100% rename from Sources/GitHub/GitHub.Repository.Stargazers.Traversal.Limit.swift rename to Sources/GitHub Stargazers/GitHub.Repository.Stargazers.Traversal.Limit.swift diff --git a/Sources/GitHub/GitHub.Repository.Stargazers.Traversal.swift b/Sources/GitHub Stargazers/GitHub.Repository.Stargazers.Traversal.swift similarity index 100% rename from Sources/GitHub/GitHub.Repository.Stargazers.Traversal.swift rename to Sources/GitHub Stargazers/GitHub.Repository.Stargazers.Traversal.swift diff --git a/Sources/GitHub Stargazers/exports.swift b/Sources/GitHub Stargazers/exports.swift new file mode 100644 index 0000000..0a13c58 --- /dev/null +++ b/Sources/GitHub Stargazers/exports.swift @@ -0,0 +1,3 @@ +@_exported public import Async_Lifecycle_Primitives +@_exported public import Either_Primitives +@_exported public import GitHub_Standard diff --git a/Sources/GitHub/GitHub.Repository.Traffic.Client.swift b/Sources/GitHub Traffic/GitHub.Repository.Traffic.Client.swift similarity index 100% rename from Sources/GitHub/GitHub.Repository.Traffic.Client.swift rename to Sources/GitHub Traffic/GitHub.Repository.Traffic.Client.swift diff --git a/Sources/GitHub Traffic/exports.swift b/Sources/GitHub Traffic/exports.swift new file mode 100644 index 0000000..a24ac5e --- /dev/null +++ b/Sources/GitHub Traffic/exports.swift @@ -0,0 +1 @@ +@_exported public import GitHub_Standard diff --git a/Sources/GitHub/GitHub.User.Authenticated.Emails.List.Client.swift b/Sources/GitHub Users/GitHub.User.Authenticated.Emails.List.Client.swift similarity index 100% rename from Sources/GitHub/GitHub.User.Authenticated.Emails.List.Client.swift rename to Sources/GitHub Users/GitHub.User.Authenticated.Emails.List.Client.swift diff --git a/Sources/GitHub/GitHub.User.Authenticated.Get.Client.swift b/Sources/GitHub Users/GitHub.User.Authenticated.Get.Client.swift similarity index 100% rename from Sources/GitHub/GitHub.User.Authenticated.Get.Client.swift rename to Sources/GitHub Users/GitHub.User.Authenticated.Get.Client.swift diff --git a/Sources/GitHub/GitHub.User.Repositories.Client+all.swift b/Sources/GitHub Users/GitHub.User.Repositories.Client+all.swift similarity index 100% rename from Sources/GitHub/GitHub.User.Repositories.Client+all.swift rename to Sources/GitHub Users/GitHub.User.Repositories.Client+all.swift diff --git a/Sources/GitHub/GitHub.User.Repositories.Client.swift b/Sources/GitHub Users/GitHub.User.Repositories.Client.swift similarity index 100% rename from Sources/GitHub/GitHub.User.Repositories.Client.swift rename to Sources/GitHub Users/GitHub.User.Repositories.Client.swift diff --git a/Sources/GitHub/GitHub.User.Repositories.Page.Error.swift b/Sources/GitHub Users/GitHub.User.Repositories.Page.Error.swift similarity index 100% rename from Sources/GitHub/GitHub.User.Repositories.Page.Error.swift rename to Sources/GitHub Users/GitHub.User.Repositories.Page.Error.swift diff --git a/Sources/GitHub/GitHub.User.Repositories.Page.swift b/Sources/GitHub Users/GitHub.User.Repositories.Page.swift similarity index 100% rename from Sources/GitHub/GitHub.User.Repositories.Page.swift rename to Sources/GitHub Users/GitHub.User.Repositories.Page.swift diff --git a/Sources/GitHub/GitHub.User.Repositories.Traversal.Error.swift b/Sources/GitHub Users/GitHub.User.Repositories.Traversal.Error.swift similarity index 100% rename from Sources/GitHub/GitHub.User.Repositories.Traversal.Error.swift rename to Sources/GitHub Users/GitHub.User.Repositories.Traversal.Error.swift diff --git a/Sources/GitHub/GitHub.User.Repositories.Traversal.Limit.Items.swift b/Sources/GitHub Users/GitHub.User.Repositories.Traversal.Limit.Items.swift similarity index 100% rename from Sources/GitHub/GitHub.User.Repositories.Traversal.Limit.Items.swift rename to Sources/GitHub Users/GitHub.User.Repositories.Traversal.Limit.Items.swift diff --git a/Sources/GitHub/GitHub.User.Repositories.Traversal.Limit.Pages.swift b/Sources/GitHub Users/GitHub.User.Repositories.Traversal.Limit.Pages.swift similarity index 100% rename from Sources/GitHub/GitHub.User.Repositories.Traversal.Limit.Pages.swift rename to Sources/GitHub Users/GitHub.User.Repositories.Traversal.Limit.Pages.swift diff --git a/Sources/GitHub/GitHub.User.Repositories.Traversal.Limit.swift b/Sources/GitHub Users/GitHub.User.Repositories.Traversal.Limit.swift similarity index 100% rename from Sources/GitHub/GitHub.User.Repositories.Traversal.Limit.swift rename to Sources/GitHub Users/GitHub.User.Repositories.Traversal.Limit.swift diff --git a/Sources/GitHub/GitHub.User.Repositories.Traversal.swift b/Sources/GitHub Users/GitHub.User.Repositories.Traversal.swift similarity index 100% rename from Sources/GitHub/GitHub.User.Repositories.Traversal.swift rename to Sources/GitHub Users/GitHub.User.Repositories.Traversal.swift diff --git a/Sources/GitHub Users/exports.swift b/Sources/GitHub Users/exports.swift new file mode 100644 index 0000000..0a13c58 --- /dev/null +++ b/Sources/GitHub Users/exports.swift @@ -0,0 +1,3 @@ +@_exported public import Async_Lifecycle_Primitives +@_exported public import Either_Primitives +@_exported public import GitHub_Standard diff --git a/Sources/GitHub/exports.swift b/Sources/GitHub/exports.swift index 0a13c58..9d00a10 100644 --- a/Sources/GitHub/exports.swift +++ b/Sources/GitHub/exports.swift @@ -1,3 +1,6 @@ -@_exported public import Async_Lifecycle_Primitives -@_exported public import Either_Primitives -@_exported public import GitHub_Standard +@_exported public import GitHub_OAuth +@_exported public import GitHub_Organizations +@_exported public import GitHub_Repositories +@_exported public import GitHub_Stargazers +@_exported public import GitHub_Traffic +@_exported public import GitHub_Users diff --git a/Tests/GitHub Core Tests/GitHub.OAuth.Client Tests.swift b/Tests/GitHub OAuth Core Tests/GitHub.OAuth.Client Tests.swift similarity index 98% rename from Tests/GitHub Core Tests/GitHub.OAuth.Client Tests.swift rename to Tests/GitHub OAuth Core Tests/GitHub.OAuth.Client Tests.swift index 8eb8784..7c57585 100644 --- a/Tests/GitHub Core Tests/GitHub.OAuth.Client Tests.swift +++ b/Tests/GitHub OAuth Core Tests/GitHub.OAuth.Client Tests.swift @@ -1,7 +1,7 @@ import RFC_3986 import Testing -@testable import GitHub +@testable import GitHub_OAuth extension GitHub.OAuth { @Suite("GitHub.OAuth.Client.Unit") diff --git a/Tests/GitHub Core Tests/GitHub.OAuth.Fixture.Failure.swift b/Tests/GitHub OAuth Core Tests/GitHub.OAuth.Fixture.Failure.swift similarity index 79% rename from Tests/GitHub Core Tests/GitHub.OAuth.Fixture.Failure.swift rename to Tests/GitHub OAuth Core Tests/GitHub.OAuth.Fixture.Failure.swift index d01addb..c051a43 100644 --- a/Tests/GitHub Core Tests/GitHub.OAuth.Fixture.Failure.swift +++ b/Tests/GitHub OAuth Core Tests/GitHub.OAuth.Fixture.Failure.swift @@ -1,4 +1,4 @@ -@testable import GitHub +@testable import GitHub_OAuth extension GitHub.OAuth.Fixture { enum Failure: Swift.Error, Equatable, Sendable { diff --git a/Tests/GitHub Core Tests/GitHub.OAuth.Fixture.swift b/Tests/GitHub OAuth Core Tests/GitHub.OAuth.Fixture.swift similarity index 61% rename from Tests/GitHub Core Tests/GitHub.OAuth.Fixture.swift rename to Tests/GitHub OAuth Core Tests/GitHub.OAuth.Fixture.swift index 30d9b58..9010a27 100644 --- a/Tests/GitHub Core Tests/GitHub.OAuth.Fixture.swift +++ b/Tests/GitHub OAuth Core Tests/GitHub.OAuth.Fixture.swift @@ -1,4 +1,4 @@ -@testable import GitHub +@testable import GitHub_OAuth extension GitHub.OAuth { enum Fixture {} diff --git a/Tests/GitHub Core Tests/GitHub.Organization.Repositories.Client Tests.swift b/Tests/GitHub Organizations Core Tests/GitHub.Organization.Repositories.Client Tests.swift similarity index 99% rename from Tests/GitHub Core Tests/GitHub.Organization.Repositories.Client Tests.swift rename to Tests/GitHub Organizations Core Tests/GitHub.Organization.Repositories.Client Tests.swift index 719ebdd..b805f2b 100644 --- a/Tests/GitHub Core Tests/GitHub.Organization.Repositories.Client Tests.swift +++ b/Tests/GitHub Organizations Core Tests/GitHub.Organization.Repositories.Client Tests.swift @@ -1,6 +1,6 @@ import Testing -@testable import GitHub +@testable import GitHub_Organizations extension GitHub.Organization.Repositories { @Suite("GitHub.Organization.Repositories.Client.Unit") diff --git a/Tests/GitHub Core Tests/GitHub.Organization.Repositories.Fixture.Failure.swift b/Tests/GitHub Organizations Core Tests/GitHub.Organization.Repositories.Fixture.Failure.swift similarity index 78% rename from Tests/GitHub Core Tests/GitHub.Organization.Repositories.Fixture.Failure.swift rename to Tests/GitHub Organizations Core Tests/GitHub.Organization.Repositories.Fixture.Failure.swift index 981e2a6..ced5e79 100644 --- a/Tests/GitHub Core Tests/GitHub.Organization.Repositories.Fixture.Failure.swift +++ b/Tests/GitHub Organizations Core Tests/GitHub.Organization.Repositories.Fixture.Failure.swift @@ -1,4 +1,4 @@ -@testable import GitHub +@testable import GitHub_Organizations extension GitHub.Organization.Repositories.Fixture { enum Failure: Swift.Error, Equatable, Sendable { diff --git a/Tests/GitHub Core Tests/GitHub.Organization.Repositories.Fixture.swift b/Tests/GitHub Organizations Core Tests/GitHub.Organization.Repositories.Fixture.swift similarity index 64% rename from Tests/GitHub Core Tests/GitHub.Organization.Repositories.Fixture.swift rename to Tests/GitHub Organizations Core Tests/GitHub.Organization.Repositories.Fixture.swift index 5da7410..6b122bc 100644 --- a/Tests/GitHub Core Tests/GitHub.Organization.Repositories.Fixture.swift +++ b/Tests/GitHub Organizations Core Tests/GitHub.Organization.Repositories.Fixture.swift @@ -1,4 +1,4 @@ -@testable import GitHub +@testable import GitHub_Organizations extension GitHub.Organization.Repositories { enum Fixture {} diff --git a/Tests/GitHub Core Tests/GitHub.Repository.Content.Client Tests.swift b/Tests/GitHub Repositories Core Tests/GitHub.Repository.Content.Client Tests.swift similarity index 97% rename from Tests/GitHub Core Tests/GitHub.Repository.Content.Client Tests.swift rename to Tests/GitHub Repositories Core Tests/GitHub.Repository.Content.Client Tests.swift index c56e3bd..fd9cafb 100644 --- a/Tests/GitHub Core Tests/GitHub.Repository.Content.Client Tests.swift +++ b/Tests/GitHub Repositories Core Tests/GitHub.Repository.Content.Client Tests.swift @@ -1,6 +1,6 @@ import Testing -@testable import GitHub +@testable import GitHub_Repositories extension GitHub.Repository.Content { @Suite("GitHub.Repository.Content.Client.Unit") diff --git a/Tests/GitHub Core Tests/GitHub.Repository.Fixture.Failure.swift b/Tests/GitHub Repositories Core Tests/GitHub.Repository.Fixture.Failure.swift similarity index 79% rename from Tests/GitHub Core Tests/GitHub.Repository.Fixture.Failure.swift rename to Tests/GitHub Repositories Core Tests/GitHub.Repository.Fixture.Failure.swift index a51ae1d..2f01bc9 100644 --- a/Tests/GitHub Core Tests/GitHub.Repository.Fixture.Failure.swift +++ b/Tests/GitHub Repositories Core Tests/GitHub.Repository.Fixture.Failure.swift @@ -1,4 +1,4 @@ -@testable import GitHub +@testable import GitHub_Repositories extension GitHub.Repository.Fixture { enum Failure: Swift.Error, Equatable, Sendable { diff --git a/Tests/GitHub Core Tests/GitHub.Repository.Fixture.swift b/Tests/GitHub Repositories Core Tests/GitHub.Repository.Fixture.swift similarity index 58% rename from Tests/GitHub Core Tests/GitHub.Repository.Fixture.swift rename to Tests/GitHub Repositories Core Tests/GitHub.Repository.Fixture.swift index 2d7db42..79ae1c9 100644 --- a/Tests/GitHub Core Tests/GitHub.Repository.Fixture.swift +++ b/Tests/GitHub Repositories Core Tests/GitHub.Repository.Fixture.swift @@ -1,4 +1,4 @@ -@testable import GitHub +@testable import GitHub_Repositories extension GitHub.Repository { enum Fixture {} diff --git a/Tests/GitHub Core Tests/GitHub.Repository.Get.Client Tests.swift b/Tests/GitHub Repositories Core Tests/GitHub.Repository.Get.Client Tests.swift similarity index 95% rename from Tests/GitHub Core Tests/GitHub.Repository.Get.Client Tests.swift rename to Tests/GitHub Repositories Core Tests/GitHub.Repository.Get.Client Tests.swift index bd1a070..5f4ca72 100644 --- a/Tests/GitHub Core Tests/GitHub.Repository.Get.Client Tests.swift +++ b/Tests/GitHub Repositories Core Tests/GitHub.Repository.Get.Client Tests.swift @@ -1,6 +1,6 @@ import Testing -@testable import GitHub +@testable import GitHub_Repositories extension GitHub.Repository.Get { @Suite("GitHub.Repository.Get.Client.Unit") diff --git a/Tests/GitHub Core Tests/GitHub.Repository.Stargazers.Client Tests.swift b/Tests/GitHub Stargazers Core Tests/GitHub.Repository.Stargazers.Client Tests.swift similarity index 96% rename from Tests/GitHub Core Tests/GitHub.Repository.Stargazers.Client Tests.swift rename to Tests/GitHub Stargazers Core Tests/GitHub.Repository.Stargazers.Client Tests.swift index 7347c5d..7787da0 100644 --- a/Tests/GitHub Core Tests/GitHub.Repository.Stargazers.Client Tests.swift +++ b/Tests/GitHub Stargazers Core Tests/GitHub.Repository.Stargazers.Client Tests.swift @@ -1,6 +1,6 @@ import Testing -@testable import GitHub +@testable import GitHub_Stargazers extension GitHub.Repository.Stargazers { @Suite("GitHub.Repository.Stargazers.Client.Unit") @@ -46,7 +46,7 @@ extension GitHub.Repository.Stargazers { size: .maximum ) let limit: GitHub.Repository.Stargazers.Traversal.Limit - do throws(GitHub.Repository.Fixture.Failure) { + do throws(GitHub.Repository.Stargazers.Fixture.Failure) { limit = try self.limit(pages: 2, items: 1) } catch { Issue.record("invalid traversal limit fixture: \(error)") @@ -123,7 +123,7 @@ extension GitHub.Repository.Stargazers { private func limit( pages: UInt, items: UInt - ) throws(GitHub.Repository.Fixture.Failure) + ) throws(GitHub.Repository.Stargazers.Fixture.Failure) -> GitHub.Repository.Stargazers.Traversal.Limit { guard diff --git a/Tests/GitHub Stargazers Core Tests/GitHub.Repository.Stargazers.Fixture.Failure.swift b/Tests/GitHub Stargazers Core Tests/GitHub.Repository.Stargazers.Fixture.Failure.swift new file mode 100644 index 0000000..b47f43b --- /dev/null +++ b/Tests/GitHub Stargazers Core Tests/GitHub.Repository.Stargazers.Fixture.Failure.swift @@ -0,0 +1,7 @@ +@testable import GitHub_Stargazers + +extension GitHub.Repository.Stargazers.Fixture { + enum Failure: Swift.Error, Equatable, Sendable { + case unexpected + } +} diff --git a/Tests/GitHub Stargazers Core Tests/GitHub.Repository.Stargazers.Fixture.swift b/Tests/GitHub Stargazers Core Tests/GitHub.Repository.Stargazers.Fixture.swift new file mode 100644 index 0000000..5e6def2 --- /dev/null +++ b/Tests/GitHub Stargazers Core Tests/GitHub.Repository.Stargazers.Fixture.swift @@ -0,0 +1,5 @@ +@testable import GitHub_Stargazers + +extension GitHub.Repository.Stargazers { + enum Fixture {} +} diff --git a/Tests/GitHub Core Tests/GitHub.Repository.Traffic.Client Tests.swift b/Tests/GitHub Traffic Core Tests/GitHub.Repository.Traffic.Client Tests.swift similarity index 72% rename from Tests/GitHub Core Tests/GitHub.Repository.Traffic.Client Tests.swift rename to Tests/GitHub Traffic Core Tests/GitHub.Repository.Traffic.Client Tests.swift index f4a5f06..1d25f6b 100644 --- a/Tests/GitHub Core Tests/GitHub.Repository.Traffic.Client Tests.swift +++ b/Tests/GitHub Traffic Core Tests/GitHub.Repository.Traffic.Client Tests.swift @@ -1,23 +1,23 @@ import Testing -@testable import GitHub +@testable import GitHub_Traffic extension GitHub.Repository.Traffic { @Suite("GitHub.Repository.Traffic.Client.Unit") struct Core { @Test("Each traffic endpoint is a typed one-call capability") - func capabilities() async throws(GitHub.Repository.Fixture.Failure) { - let client = Client( - views: { _ async throws(GitHub.Repository.Fixture.Failure) in + func capabilities() async throws(GitHub.Repository.Traffic.Fixture.Failure) { + let client = Client( + views: { _ async throws(GitHub.Repository.Traffic.Fixture.Failure) in .init(count: 1, uniques: 1, views: []) }, - clones: { _ async throws(GitHub.Repository.Fixture.Failure) in + clones: { _ async throws(GitHub.Repository.Traffic.Fixture.Failure) in .init(count: 2, uniques: 2, clones: []) }, - paths: { _ async throws(GitHub.Repository.Fixture.Failure) in + paths: { _ async throws(GitHub.Repository.Traffic.Fixture.Failure) in .init(paths: []) }, - referrers: { _ async throws(GitHub.Repository.Fixture.Failure) in + referrers: { _ async throws(GitHub.Repository.Traffic.Fixture.Failure) in .init(referrers: []) } ) @@ -45,24 +45,24 @@ extension GitHub.Repository.Traffic { @Test("Traffic endpoint failures remain typed") func failure() async { - let client = Client( + let client = Client( views: { - (_: Views.Request) async throws(GitHub.Repository.Fixture.Failure) + (_: Views.Request) async throws(GitHub.Repository.Traffic.Fixture.Failure) -> Views.Response in throw .expected }, clones: { - (_: Clones.Request) async throws(GitHub.Repository.Fixture.Failure) + (_: Clones.Request) async throws(GitHub.Repository.Traffic.Fixture.Failure) -> Clones.Response in throw .expected }, paths: { - (_: Paths.Request) async throws(GitHub.Repository.Fixture.Failure) + (_: Paths.Request) async throws(GitHub.Repository.Traffic.Fixture.Failure) -> Paths.Response in throw .expected }, referrers: { - (_: Referrers.Request) async throws(GitHub.Repository.Fixture.Failure) + (_: Referrers.Request) async throws(GitHub.Repository.Traffic.Fixture.Failure) -> Referrers.Response in throw .expected } @@ -74,16 +74,16 @@ extension GitHub.Repository.Traffic { let clones = Clones.Request(owner: owner, repository: repository) let paths = Paths.Request(owner: owner, repository: repository) let referrers = Referrers.Request(owner: owner, repository: repository) - await #expect(throws: GitHub.Repository.Fixture.Failure.expected) { + await #expect(throws: GitHub.Repository.Traffic.Fixture.Failure.expected) { try await client.views(views) } - await #expect(throws: GitHub.Repository.Fixture.Failure.expected) { + await #expect(throws: GitHub.Repository.Traffic.Fixture.Failure.expected) { try await client.clones(clones) } - await #expect(throws: GitHub.Repository.Fixture.Failure.expected) { + await #expect(throws: GitHub.Repository.Traffic.Fixture.Failure.expected) { try await client.paths(paths) } - await #expect(throws: GitHub.Repository.Fixture.Failure.expected) { + await #expect(throws: GitHub.Repository.Traffic.Fixture.Failure.expected) { try await client.referrers(referrers) } } diff --git a/Tests/GitHub Traffic Core Tests/GitHub.Repository.Traffic.Fixture.Failure.swift b/Tests/GitHub Traffic Core Tests/GitHub.Repository.Traffic.Fixture.Failure.swift new file mode 100644 index 0000000..7e9d763 --- /dev/null +++ b/Tests/GitHub Traffic Core Tests/GitHub.Repository.Traffic.Fixture.Failure.swift @@ -0,0 +1,7 @@ +@testable import GitHub_Traffic + +extension GitHub.Repository.Traffic.Fixture { + enum Failure: Swift.Error, Equatable, Sendable { + case expected + } +} diff --git a/Tests/GitHub Traffic Core Tests/GitHub.Repository.Traffic.Fixture.swift b/Tests/GitHub Traffic Core Tests/GitHub.Repository.Traffic.Fixture.swift new file mode 100644 index 0000000..95155eb --- /dev/null +++ b/Tests/GitHub Traffic Core Tests/GitHub.Repository.Traffic.Fixture.swift @@ -0,0 +1,5 @@ +@testable import GitHub_Traffic + +extension GitHub.Repository.Traffic { + enum Fixture {} +} diff --git a/Tests/GitHub Core Tests/GitHub.User.Authenticated.Client Tests.swift b/Tests/GitHub Users Core Tests/GitHub.User.Authenticated.Client Tests.swift similarity index 65% rename from Tests/GitHub Core Tests/GitHub.User.Authenticated.Client Tests.swift rename to Tests/GitHub Users Core Tests/GitHub.User.Authenticated.Client Tests.swift index af41ea8..90e0188 100644 --- a/Tests/GitHub Core Tests/GitHub.User.Authenticated.Client Tests.swift +++ b/Tests/GitHub Users Core Tests/GitHub.User.Authenticated.Client Tests.swift @@ -1,32 +1,32 @@ import Testing -@testable import GitHub +@testable import GitHub_Users extension GitHub.User.Authenticated { @Suite("GitHub.User.Authenticated.Client.Unit") struct Core { @Test("Authenticated-user lookup preserves its typed failure") func get() async { - let client = Get.Client { - (request: Get.Request) async throws(GitHub.OAuth.Fixture.Failure) in + let client = Get.Client { + (request: Get.Request) async throws(GitHub.User.Fixture.Failure) in #expect(request.accessToken == "access-token") throw .expected } - await #expect(throws: GitHub.OAuth.Fixture.Failure.expected) { + await #expect(throws: GitHub.User.Fixture.Failure.expected) { try await client.get(.init(accessToken: "access-token")) } } @Test("Authenticated-user email listing preserves its typed failure") func emails() async { - let client = Emails.List.Client { - (request: Emails.List.Request) async throws(GitHub.OAuth.Fixture.Failure) in + let client = Emails.List.Client { + (request: Emails.List.Request) async throws(GitHub.User.Fixture.Failure) in #expect(request.accessToken == "access-token") throw .expected } - await #expect(throws: GitHub.OAuth.Fixture.Failure.expected) { + await #expect(throws: GitHub.User.Fixture.Failure.expected) { try await client.list(.init(accessToken: "access-token")) } } diff --git a/Tests/GitHub Users Core Tests/GitHub.User.Fixture.Failure.swift b/Tests/GitHub Users Core Tests/GitHub.User.Fixture.Failure.swift new file mode 100644 index 0000000..293a28b --- /dev/null +++ b/Tests/GitHub Users Core Tests/GitHub.User.Fixture.Failure.swift @@ -0,0 +1,8 @@ +@testable import GitHub_Users + +extension GitHub.User.Fixture { + enum Failure: Swift.Error, Equatable, Sendable { + case expected + case unexpected + } +} diff --git a/Tests/GitHub Users Core Tests/GitHub.User.Fixture.swift b/Tests/GitHub Users Core Tests/GitHub.User.Fixture.swift new file mode 100644 index 0000000..41ef1fa --- /dev/null +++ b/Tests/GitHub Users Core Tests/GitHub.User.Fixture.swift @@ -0,0 +1,5 @@ +@testable import GitHub_Users + +extension GitHub.User { + enum Fixture {} +} diff --git a/Tests/GitHub Core Tests/GitHub.User.Repositories.Client Tests.swift b/Tests/GitHub Users Core Tests/GitHub.User.Repositories.Client Tests.swift similarity index 97% rename from Tests/GitHub Core Tests/GitHub.User.Repositories.Client Tests.swift rename to Tests/GitHub Users Core Tests/GitHub.User.Repositories.Client Tests.swift index e2116c8..a86fec7 100644 --- a/Tests/GitHub Core Tests/GitHub.User.Repositories.Client Tests.swift +++ b/Tests/GitHub Users Core Tests/GitHub.User.Repositories.Client Tests.swift @@ -1,6 +1,6 @@ import Testing -@testable import GitHub +@testable import GitHub_Users extension GitHub.User.Repositories { @Suite("GitHub.User.Repositories.Client.Unit") @@ -34,7 +34,7 @@ extension GitHub.User.Repositories { let first = Request(page: .first, size: .maximum) let limit: GitHub.User.Repositories.Traversal.Limit - do throws(GitHub.Repository.Fixture.Failure) { + do throws(GitHub.User.Fixture.Failure) { limit = try self.limit(pages: 2, items: 1) } catch { Issue.record("invalid traversal limit fixture: \(error)") @@ -109,7 +109,7 @@ extension GitHub.User.Repositories { private func limit( pages: UInt, items: UInt - ) throws(GitHub.Repository.Fixture.Failure) + ) throws(GitHub.User.Fixture.Failure) -> GitHub.User.Repositories.Traversal.Limit { guard From 8976310187809b1b418f98c4fe01847bedb4e04c Mon Sep 17 00:00:00 2001 From: Coen ten Thije Boonkkamp Date: Sun, 2 Aug 2026 14:49:42 +0200 Subject: [PATCH 4/5] Declare RFC 3986 for OAuth tests --- Package.swift | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/Package.swift b/Package.swift index 92164b1..cbcc498 100644 --- a/Package.swift +++ b/Package.swift @@ -50,6 +50,10 @@ let package = Package( url: "https://github.com/swift-primitives/swift-either-primitives.git", branch: "main" ), + .package( + url: "https://github.com/swift-ietf/swift-rfc-3986.git", + branch: "main" + ), .package( url: "https://github.com/swift-standards/swift-github-standard.git", branch: "main" @@ -78,7 +82,10 @@ let package = Package( ), .testTarget( name: "GitHub OAuth Core Tests", - dependencies: [.target(name: "GitHub OAuth")] + dependencies: [ + .target(name: "GitHub OAuth"), + .product(name: "RFC 3986", package: "swift-rfc-3986"), + ] ), .target( name: "GitHub Organizations", From fdf6637c58b24520afd897898c2145739a24a032 Mon Sep 17 00:00:00 2001 From: Coen ten Thije Boonkkamp Date: Mon, 3 Aug 2026 08:57:17 +0200 Subject: [PATCH 5/5] Document per-resource products; correct product availability note --- README.md | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index ac4ef49..24c1037 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,12 @@ persistence, or application policy. | Product | Module | Purpose | | --- | --- | --- | | GitHub | `GitHub` | Typed one-call clients and bounded paginated traversals | +| GitHub OAuth | `GitHub_OAuth` | Authorization and token exchange | +| GitHub Organizations | `GitHub_Organizations` | Organization repository listing and bounded traversal | +| GitHub Repositories | `GitHub_Repositories` | Repository lookup and content retrieval | +| GitHub Stargazers | `GitHub_Stargazers` | Timestamped stargazer listing and bounded traversal | +| GitHub Traffic | `GitHub_Traffic` | Repository views, clones, paths, and referrers | +| GitHub Users | `GitHub_Users` | Authenticated-user profile, emails, and repository listing | ## Installation @@ -38,6 +44,22 @@ dependencies: [ ) ``` +Each resource is also its own product, so a consumer that only needs one +resource can depend on it directly instead of the `GitHub` umbrella: + +```swift +.target( + name: "YourTarget", + dependencies: [ + .product(name: "GitHub Traffic", package: "swift-github") + ] +) +``` + +The six per-resource products are `GitHub OAuth`, `GitHub Organizations`, +`GitHub Repositories`, `GitHub Stargazers`, `GitHub Traffic`, and +`GitHub Users` — see Products above. + ## Usage Clients are generic over their typed failure: @@ -83,8 +105,10 @@ in Aggregating views, clones, paths, and referrers into an application snapshot is application policy and is intentionally outside this package. -No deprecated `GitHub Traffic`, `GitHub Stargazers`, or -`GitHub Repositories` compatibility products are provided. +`GitHub Traffic`, `GitHub Stargazers`, and `GitHub Repositories` are +first-class per-resource products (see Products above) that a consumer can +depend on directly. They are not deprecated compatibility shims for the +`GitHub` umbrella. ## Error Handling