Skip to content

Commit f112177

Browse files
committed
Update hello example to use output from latest template
1 parent 6c015a8 commit f112177

File tree

9 files changed

+138
-69
lines changed

9 files changed

+138
-69
lines changed

hello/.github/workflows/ci.yml

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
paths:
8+
- '**.swift'
9+
- '**.yml'
10+
pull_request:
11+
workflow_dispatch:
12+
13+
jobs:
14+
linux:
15+
runs-on: ubuntu-latest
16+
strategy:
17+
matrix:
18+
image:
19+
- 'swift:latest'
20+
container:
21+
image: ${{ matrix.image }}
22+
steps:
23+
- name: Checkout
24+
uses: actions/checkout@v4
25+
- name: Test
26+
run: swift test

hello/.gitignore

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,10 @@
1-
public/
1+
.DS_Store
2+
/.build
3+
/.swiftpm
4+
/.devContainer
5+
/Packages
6+
/*.xcodeproj
7+
xcuserdata/
8+
/.vscode/*
9+
.env.*
10+
.env

hello/Dockerfile

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# ================================
22
# Build image
33
# ================================
4-
FROM swift:5.10-jammy as build
4+
FROM swift:6.1-noble AS build
55

66
# Install OS updates
77
RUN export DEBIAN_FRONTEND=noninteractive DEBCONF_NONINTERACTIVE_SEEN=true \
@@ -23,8 +23,9 @@ RUN swift package resolve
2323
# Copy entire repo into container
2424
COPY . .
2525

26-
# Build everything, with optimizations, with static linking, and using jemalloc
26+
# Build the application, with optimizations, with static linking, and using jemalloc
2727
RUN swift build -c release \
28+
--product "App" \
2829
--static-swift-stdlib \
2930
-Xlinker -ljemalloc
3031

@@ -47,20 +48,20 @@ RUN [ -d /build/public ] && { mv /build/public ./public && chmod -R a-w ./public
4748
# ================================
4849
# Run image
4950
# ================================
50-
FROM ubuntu:jammy
51+
FROM ubuntu:noble
5152

5253
# Make sure all system packages are up to date, and install only essential packages.
5354
RUN export DEBIAN_FRONTEND=noninteractive DEBCONF_NONINTERACTIVE_SEEN=true \
5455
&& apt-get -q update \
5556
&& apt-get -q dist-upgrade -y \
5657
&& apt-get -q install -y \
57-
libjemalloc2 \
58-
ca-certificates \
59-
tzdata \
60-
# If your app or its dependencies import FoundationNetworking, also install `libcurl4`.
61-
# libcurl4 \
62-
# If your app or its dependencies import FoundationXML, also install `libxml2`.
63-
# libxml2 \
58+
libjemalloc2 \
59+
ca-certificates \
60+
tzdata \
61+
# If your app or its dependencies import FoundationNetworking, also install `libcurl4`.
62+
# libcurl4 \
63+
# If your app or its dependencies import FoundationXML, also install `libxml2`.
64+
# libxml2 \
6465
&& rm -r /var/lib/apt/lists/*
6566

6667
# Create a hummingbird user and group with /app as its home directory

hello/Package.swift

Lines changed: 15 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,32 @@
1-
// swift-tools-version:5.9
1+
// swift-tools-version:6.2
2+
// The swift-tools-version declares the minimum version of Swift required to build this package.
3+
24
import PackageDescription
35

46
let package = Package(
57
name: "hello",
6-
platforms: [
7-
.macOS(.v14),
8+
platforms: [.macOS(.v15), .iOS(.v18), .tvOS(.v18)],
9+
products: [
10+
.executable(name: "App", targets: ["App"]),
811
],
912
dependencies: [
1013
.package(url: "https://github.com/hummingbird-project/hummingbird.git", from: "2.0.0"),
11-
.package(url: "https://github.com/apple/swift-argument-parser.git", from: "1.4.0"),
14+
.package(url: "https://github.com/apple/swift-configuration.git", from: "1.0.0", traits: [.defaults, "CommandLineArguments"]),
1215
],
1316
targets: [
14-
.executableTarget(
15-
name: "App",
17+
.executableTarget(name: "App",
1618
dependencies: [
17-
.product(name: "ArgumentParser", package: "swift-argument-parser"),
19+
.product(name: "Configuration", package: "swift-configuration"),
1820
.product(name: "Hummingbird", package: "hummingbird"),
1921
],
20-
swiftSettings: [
21-
// Enable better optimizations when building in Release configuration. Despite the use of
22-
// the `.unsafeFlags` construct required by SwiftPM, this flag is recommended for Release
23-
// builds. See <https://github.com/swift-server/guides#building-for-production> for details.
24-
.unsafeFlags(["-cross-module-optimization"], .when(configuration: .release)),
25-
]
22+
path: "Sources/App"
2623
),
27-
.testTarget(
28-
name: "AppTests",
24+
.testTarget(name: "AppTests",
2925
dependencies: [
3026
.byName(name: "App"),
31-
.product(name: "Hummingbird", package: "hummingbird"),
32-
.product(name: "HummingbirdTesting", package: "hummingbird"),
33-
]
34-
),
27+
.product(name: "HummingbirdTesting", package: "hummingbird")
28+
],
29+
path: "Tests/AppTests"
30+
)
3531
]
3632
)

hello/README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
# Hello
22

3-
This is a simple app that will responds with the word "hello". This example is here just to demonstrate how to start up a server.
3+
This is a simple app that will responds with the string "Hello!". This example is here just to demonstrate how to start up a server. The example code is exactly the same as the output from the template when you chose all the default options.
44

55
You can test the sample as follows
66
```sh
7-
curl localhost:8080/
7+
curl -i localhost:8080/
88
```
9-
It should return a response with status 200 and the body text "Hello".
9+
It should return a response with status 200 and the body text "Hello!".

hello/Sources/App/App+build.swift

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import Configuration
2+
import Hummingbird
3+
import Logging
4+
5+
// Request context used by application
6+
typealias AppRequestContext = BasicRequestContext
7+
8+
/// Build application
9+
/// - Parameter reader: configuration reader
10+
func buildApplication(reader: ConfigReader) async throws -> some ApplicationProtocol {
11+
let logger = {
12+
var logger = Logger(label: "hello")
13+
logger.logLevel = reader.string(forKey: "log.level", as: Logger.Level.self, default: .info)
14+
return logger
15+
}()
16+
let router = try buildRouter()
17+
let app = Application(
18+
router: router,
19+
configuration: ApplicationConfiguration(reader: reader.scoped(to: "http")),
20+
logger: logger
21+
)
22+
return app
23+
}
24+
25+
/// Build router
26+
func buildRouter() throws -> Router<AppRequestContext> {
27+
let router = Router(context: AppRequestContext.self)
28+
// Add middleware
29+
router.addMiddleware {
30+
// logging middleware
31+
LogRequestsMiddleware(.info)
32+
}
33+
// Add default endpoint
34+
router.get("/") { _,_ in
35+
return "Hello!"
36+
}
37+
return router
38+
}

hello/Sources/App/Application+build.swift

Lines changed: 0 additions & 14 deletions
This file was deleted.

hello/Sources/App/app.swift

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,21 @@
1-
import ArgumentParser
1+
import Configuration
2+
import Hummingbird
3+
import Logging
24

35
@main
4-
struct HummingbirdArguments: AsyncParsableCommand {
5-
@Option(name: .shortAndLong)
6-
var hostname: String = "127.0.0.1"
7-
8-
@Option(name: .shortAndLong)
9-
var port: Int = 8080
10-
11-
func run() async throws {
12-
let app = buildApplication(
13-
configuration: .init(
14-
address: .hostname(self.hostname, port: self.port),
15-
serverName: "Hummingbird"
16-
)
17-
)
6+
struct App {
7+
static func main() async throws {
8+
// Application will read configuration from the following in the order listed
9+
// Command line, Environment variables, dotEnv file, defaults provided in memory
10+
let reader = try await ConfigReader(providers: [
11+
CommandLineArgumentsProvider(),
12+
EnvironmentVariablesProvider(),
13+
EnvironmentVariablesProvider(environmentFilePath: ".env", allowMissing: true),
14+
InMemoryProvider(values: [
15+
"http.serverName": "hello"
16+
])
17+
])
18+
let app = try await buildApplication(reader: reader)
1819
try await app.runService()
1920
}
2021
}

hello/Tests/AppTests/AppTests.swift

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,27 @@
1-
@testable import App
1+
import Configuration
22
import Hummingbird
33
import HummingbirdTesting
4-
import XCTest
4+
import Logging
5+
import Testing
6+
7+
@testable import App
8+
9+
private let reader = ConfigReader(providers: [
10+
InMemoryProvider(values: [
11+
"host": "127.0.0.1",
12+
"port": "0",
13+
"log.level": "trace"
14+
])
15+
])
516

6-
final class AppTests: XCTestCase {
7-
func testApp() async throws {
8-
let app = buildApplication(configuration: .init())
17+
@Suite
18+
struct AppTests {
19+
@Test
20+
func app() async throws {
21+
let app = try await buildApplication(reader: reader)
922
try await app.test(.router) { client in
1023
try await client.execute(uri: "/", method: .get) { response in
11-
XCTAssertEqual(response.status, .ok)
12-
XCTAssertEqual(String(buffer: response.body), "Hello")
24+
#expect(response.body == ByteBuffer(string: "Hello!"))
1325
}
1426
}
1527
}

0 commit comments

Comments
 (0)