Skip to content

Commit 42f9ffe

Browse files
Merge pull request #3541 from SwiftPackageIndex/issue-3469-dependency-transition-9
Issue 3469 dependency transition 9
2 parents f526e68 + 45a4797 commit 42f9ffe

File tree

7 files changed

+141
-123
lines changed

7 files changed

+141
-123
lines changed

Sources/App/Controllers/PackageController+routes.swift

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -74,19 +74,19 @@ enum PackageController {
7474
)
7575

7676
case .css, .data, .faviconIco, .faviconSvg, .images, .img, .index, .js, .linkablePaths, .themeSettings, .svgImages, .svgImg, .videos:
77-
return try await res.encodeResponse(
77+
return try await ClientResponse(
7878
status: .ok,
7979
headers: req.headers
8080
.replacingOrAdding(name: .contentType, value: route.fragment.contentType)
8181
.replacingOrAdding(name: .cacheControl, value: "no-transform"),
82-
for: req
83-
)
82+
body: res.body
83+
).encodeResponse(for: req)
8484
}
8585
}
8686

8787
static func documentationResponse(req: Request,
8888
route: DocRoute,
89-
awsResponse: ClientResponse,
89+
awsResponse: HTTPClient.Response,
9090
documentationMetadata: DocumentationMetadata) async throws -> Response {
9191
guard let documentation = documentationMetadata.versions[reference: route.docVersion.reference]
9292
else {
@@ -146,12 +146,12 @@ enum PackageController {
146146
updatedAt: documentation.updatedAt,
147147
rawHtml: body.asString())
148148
else {
149-
return try await awsResponse.encodeResponse(
149+
return try await ClientResponse(
150150
status: .ok,
151151
headers: req.headers.replacingOrAdding(name: .contentType,
152152
value: route.contentType),
153-
for: req
154-
)
153+
body: awsResponse.body
154+
).encodeResponse(for: req)
155155
}
156156

157157
return try await processor.processedPage.encodeResponse(
@@ -162,9 +162,11 @@ enum PackageController {
162162
)
163163
}
164164

165-
static func awsResponse(client: Client, route: DocRoute) async throws -> ClientResponse {
165+
static func awsResponse(client: Client, route: DocRoute) async throws -> HTTPClient.Response {
166+
@Dependency(\.httpClient) var httpClient
167+
166168
let url = try Self.awsDocumentationURL(route: route)
167-
guard let response = try? await Current.fetchDocumentation(client, url) else {
169+
guard let response = try? await httpClient.fetchDocumentation(url) else {
168170
throw Abort(.notFound)
169171
}
170172
guard (200..<399).contains(response.status.code) else {

Sources/App/Core/AppEnvironment.swift

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ import FoundationNetworking
2323

2424

2525
struct AppEnvironment: Sendable {
26-
var fetchDocumentation: @Sendable (_ client: Client, _ url: URI) async throws -> ClientResponse
2726
var fetchHTTPStatusCode: @Sendable (_ url: String) async throws -> HTTPStatus
2827
var fetchLicense: @Sendable (_ client: Client, _ owner: String, _ repository: String) async -> Github.License?
2928
var fetchMetadata: @Sendable (_ client: Client, _ owner: String, _ repository: String) async throws -> Github.Metadata
@@ -85,7 +84,6 @@ extension AppEnvironment {
8584
nonisolated(unsafe) static var logger: Logger!
8685

8786
static let live = AppEnvironment(
88-
fetchDocumentation: { client, url in try await client.get(url) },
8987
fetchHTTPStatusCode: { url in try await Networking.fetchHTTPStatusCode(url) },
9088
fetchLicense: { client, owner, repo in await Github.fetchLicense(client:client, owner: owner, repository: repo) },
9189
fetchMetadata: { client, owner, repo in try await Github.fetchMetadata(client:client, owner: owner, repository: repo) },
@@ -152,11 +150,11 @@ extension AppEnvironment {
152150

153151
private enum Networking {
154152
static func fetchHTTPStatusCode(_ url: String) async throws -> HTTPStatus {
155-
var config = HTTPClient.Configuration()
153+
var config = Vapor.HTTPClient.Configuration()
156154
// We're forcing HTTP/1 due to a bug in Github's HEAD request handling
157155
// https://github.com/SwiftPackageIndex/SwiftPackageIndex-Server/issues/1676
158156
config.httpVersion = .http1Only
159-
let client = HTTPClient(eventLoopGroupProvider: .singleton, configuration: config)
157+
let client = Vapor.HTTPClient(eventLoopGroupProvider: .singleton, configuration: config)
160158
return try await run {
161159
var req = HTTPClientRequest(url: url)
162160
req.method = .HEAD
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
// Copyright Dave Verwer, Sven A. Schmidt, and other contributors.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
import Dependencies
16+
import DependenciesMacros
17+
import Vapor
18+
19+
20+
@DependencyClient
21+
struct HTTPClient {
22+
typealias Response = Vapor.HTTPClient.Response
23+
24+
var fetchDocumentation: @Sendable (_ url: URI) async throws -> Response
25+
}
26+
27+
extension HTTPClient: DependencyKey {
28+
static var liveValue: HTTPClient {
29+
.init(
30+
fetchDocumentation: { url in
31+
try await Vapor.HTTPClient.shared.get(url: url.string).get()
32+
}
33+
)
34+
}
35+
}
36+
37+
38+
extension HTTPClient: TestDependencyKey {
39+
static var testValue: Self { Self() }
40+
}
41+
42+
43+
extension DependencyValues {
44+
var httpClient: HTTPClient {
45+
get { self[HTTPClient.self] }
46+
set { self[HTTPClient.self] = newValue }
47+
}
48+
}
49+
50+
51+
#if DEBUG
52+
// Convenience initialisers to make testing easier
53+
54+
extension HTTPClient {
55+
static func echoURL(headers: HTTPHeaders = .init()) -> @Sendable (_ url: URI) async throws -> Response {
56+
{ url in
57+
// echo url.path in the body as a simple way to test the requested url
58+
.init(status: .ok, headers: headers, body: .init(string: url.path))
59+
}
60+
}
61+
}
62+
63+
extension HTTPClient.Response {
64+
init(status: HTTPResponseStatus,
65+
version: HTTPVersion = .http1_1,
66+
headers: HTTPHeaders = .init(),
67+
body: ByteBuffer? = nil) {
68+
self.init(host: "host", status: status, version: version, headers: headers, body: body)
69+
}
70+
71+
static var ok: Self { .init(status: .ok) }
72+
static var notFound: Self { .init(status: .notFound) }
73+
static var badRequest: Self { .init(status: .badRequest) }
74+
}
75+
#endif

Tests/AppTests/Mocks/AppEnvironment+mock.swift

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ import Vapor
2222
extension AppEnvironment {
2323
static func mock(eventLoop: EventLoop) -> Self {
2424
.init(
25-
fetchDocumentation: { _, _ in .init(status: .ok) },
2625
fetchHTTPStatusCode: { _ in .ok },
2726
fetchLicense: { _, _, _ in .init(htmlUrl: "https://github.com/foo/bar/blob/main/LICENSE") },
2827
fetchMetadata: { _, _, _ in .mock },

0 commit comments

Comments
 (0)