Added some more cases to the File enumeration in the library target.

This commit is contained in:
2025-01-18 13:32:59 +01:00
parent 0b69973537
commit c08dbe5602
12 changed files with 258 additions and 16 deletions
+20
View File
@@ -0,0 +1,20 @@
import AppLibrary
import ArgumentParser
@main
struct App: AsyncParsableCommand {
// MARK: Properties
@OptionGroup var options: Options
// MARK: Functions
mutating func run() async throws {
let builder = AppBuilder(name: "App")
let app = try await builder(options)
try await app.runService()
}
}
@@ -0,0 +1,20 @@
import AppLibrary
import ArgumentParser
import Logging
extension App {
struct Options: AppArguments, ParsableArguments {
// MARK: Properties
@Option(name: .shortAndLong)
var hostname: String = "127.0.0.1"
@Option(name: .shortAndLong)
var port: Int = 8080
@Option(name: .shortAndLong)
var logLevel: Logger.Level?
}
}
@@ -0,0 +1,11 @@
import Logging
public protocol AppArguments {
// MARK: Properties
var hostname: String { get }
var logLevel: Logger.Level? { get }
var port: Int { get }
}
@@ -0,0 +1,69 @@
import Hummingbird
import Logging
public struct AppBuilder {
// MARK: Properties
private let environment: Environment
private let name: String
// MARK: Initialisers
public init(name: String) {
self.environment = Environment()
self.name = name
}
// MARK: Functions
public func callAsFunction(
_ arguments: some AppArguments
) async throws -> some ApplicationProtocol {
let logger = {
var logger = Logger(label: name)
logger.logLevel = arguments.logLevel
?? environment.logLevel.flatMap { Logger.Level(rawValue: $0) ?? .info }
?? .info
return logger
}()
let router = router(logger: logger)
return Application(
router: router,
configuration: .init(
address: .hostname(arguments.hostname, port: arguments.port),
serverName: name
),
logger: logger
)
}
}
// MARK: - Helpers
private extension AppBuilder {
// MARK: Type aliases
typealias AppRequestContext = BasicRequestContext
// MARK: Functions
func router(logger: Logger) -> Router<AppRequestContext> {
let router = Router()
router.add(middleware: LogRequestsMiddleware(logger.logLevel))
router.get("/") { _,_ in
""
}
return router
}
}
@@ -0,0 +1,11 @@
import Hummingbird
extension Environment {
// MARK: Computed
public var logLevel: String? {
self.get("LOG_LEVEL")
}
}
@@ -0,0 +1,9 @@
import ArgumentParser
import Logging
/// Extend `Logger.Level` so it can be used as an argument
#if hasFeature(RetroactiveAttribute)
extension Logger.Level: @retroactive ExpressibleByArgument {}
#else
extension Logger.Level: ExpressibleByArgument {}
#endif
+1 -1
View File
@@ -5,7 +5,7 @@ import PackageDescription
let package = Package(
name: "App",
platforms: [
.macOS(.v10_15)
.macOS(.v14)
],
products: [
.executable(name: "App", targets: ["App"]),
@@ -0,0 +1,33 @@
import AppLibrary
import Hummingbird
import HummingbirdTesting
import Testing
struct AppTests {
// MARK: Properties
private let arguments = TestArguments()
private let builder = AppBuilder(name: "App")
// MARK: Route tests
@Test(arguments: ["/"])
func routes(_ uri: String) async throws {
let app = try await builder(arguments)
try await app.test(.router) { client in
try await client.execute(uri: uri, method: .get) { response in
#expect(response.status == .ok)
#expect(response.body == .empty)
}
}
}
}
// MARK: ByteBuffer+Constants
private extension ByteBuffer {
static let empty = ByteBuffer(string: "")
}
@@ -0,0 +1,12 @@
import AppLibrary
import Logging
struct TestArguments: AppArguments {
// MARK: Properties
let hostname = "127.0.0.1"
let port = 0
let logLevel: Logger.Level? = .trace
}