Added some more cases to the File enumeration in the library target.
This commit is contained in:
parent
0b69973537
commit
c08dbe5602
20
Library/Resources/Files/Sources/App/App
Normal file
20
Library/Resources/Files/Sources/App/App
Normal 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()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
20
Library/Resources/Files/Sources/App/AppOptions
Normal file
20
Library/Resources/Files/Sources/App/AppOptions
Normal file
@ -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?
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
11
Library/Resources/Files/Sources/Library/AppArguments
Normal file
11
Library/Resources/Files/Sources/Library/AppArguments
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
import Logging
|
||||||
|
|
||||||
|
public protocol AppArguments {
|
||||||
|
|
||||||
|
// MARK: Properties
|
||||||
|
|
||||||
|
var hostname: String { get }
|
||||||
|
var logLevel: Logger.Level? { get }
|
||||||
|
var port: Int { get }
|
||||||
|
|
||||||
|
}
|
69
Library/Resources/Files/Sources/Library/AppBuilder
Normal file
69
Library/Resources/Files/Sources/Library/AppBuilder
Normal file
@ -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
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
11
Library/Resources/Files/Sources/Library/Environment
Normal file
11
Library/Resources/Files/Sources/Library/Environment
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
import Hummingbird
|
||||||
|
|
||||||
|
extension Environment {
|
||||||
|
|
||||||
|
// MARK: Computed
|
||||||
|
|
||||||
|
public var logLevel: String? {
|
||||||
|
self.get("LOG_LEVEL")
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
9
Library/Resources/Files/Sources/Library/LoggerLevel
Normal file
9
Library/Resources/Files/Sources/Library/LoggerLevel
Normal file
@ -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
|
@ -5,7 +5,7 @@ import PackageDescription
|
|||||||
let package = Package(
|
let package = Package(
|
||||||
name: "App",
|
name: "App",
|
||||||
platforms: [
|
platforms: [
|
||||||
.macOS(.v10_15)
|
.macOS(.v14)
|
||||||
],
|
],
|
||||||
products: [
|
products: [
|
||||||
.executable(name: "App", targets: ["App"]),
|
.executable(name: "App", targets: ["App"]),
|
||||||
|
33
Library/Resources/Files/Sources/Test/AppTests
Normal file
33
Library/Resources/Files/Sources/Test/AppTests
Normal file
@ -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: "")
|
||||||
|
}
|
12
Library/Resources/Files/Sources/Test/TestArguments
Normal file
12
Library/Resources/Files/Sources/Test/TestArguments
Normal file
@ -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
|
||||||
|
|
||||||
|
}
|
@ -1,10 +1,19 @@
|
|||||||
enum File: String {
|
enum File: String {
|
||||||
|
case app = "App"
|
||||||
|
case appArguments = "AppArguments"
|
||||||
|
case appBuilder = "AppBuilder"
|
||||||
|
case appOptions = "AppOptions"
|
||||||
|
case appTests = "AppTests"
|
||||||
case dockerFile = "DockerFile"
|
case dockerFile = "DockerFile"
|
||||||
case dockerIgnore = "DockerIgnore"
|
case dockerIgnore = "DockerIgnore"
|
||||||
|
case environment = "Environment"
|
||||||
case gitIgnore = "GitIgnore"
|
case gitIgnore = "GitIgnore"
|
||||||
case license = "License"
|
case license = "License"
|
||||||
|
case loggerLevel = "LoggerLevel"
|
||||||
case package = "Package"
|
case package = "Package"
|
||||||
case readme = "Readme"
|
case readme = "Readme"
|
||||||
|
case testArguments = "TestArguments"
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Properties
|
// MARK: - Properties
|
||||||
@ -15,30 +24,46 @@ extension File {
|
|||||||
|
|
||||||
var fileName: String {
|
var fileName: String {
|
||||||
switch self {
|
switch self {
|
||||||
|
case .app: "App.swift"
|
||||||
|
case .appArguments: "AppArguments.swift"
|
||||||
|
case .appBuilder: "AppBuilder.swift"
|
||||||
|
case .appOptions: "AppOptions.swift"
|
||||||
|
case .appTests: "AppTests.swift"
|
||||||
case .dockerFile: "Dockerfile"
|
case .dockerFile: "Dockerfile"
|
||||||
case .dockerIgnore: ".dockerignore"
|
case .dockerIgnore: ".dockerignore"
|
||||||
|
case .environment: "Environment+Properties.swift"
|
||||||
case .gitIgnore: ".gitignore"
|
case .gitIgnore: ".gitignore"
|
||||||
case .license: "LICENSE"
|
case .license: "LICENSE"
|
||||||
|
case .loggerLevel: "LoggerLevel+Conformances.swift"
|
||||||
case .readme: "README.md"
|
case .readme: "README.md"
|
||||||
case .package: "Package.swift"
|
case .package: "Package.swift"
|
||||||
|
case .testArguments: "TestArguments.swift"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var filePath: String {
|
var filePath: String {
|
||||||
switch self {
|
folder.path + fileName
|
||||||
default: folder.path + fileName
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var folder: Folder {
|
var folder: Folder {
|
||||||
switch self {
|
switch self {
|
||||||
|
case .app, .appOptions: .app
|
||||||
|
case .appArguments, .appBuilder: .libraryPublic
|
||||||
|
case .appTests: .testCasesPublic
|
||||||
|
case .environment, .loggerLevel: .libraryInternal
|
||||||
|
case .testArguments: .testHelpers
|
||||||
default: .root
|
default: .root
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var resourcePath: String {
|
var resourcePath: String {
|
||||||
switch self {
|
let basePath = "Resources/Files/Sources"
|
||||||
default: "Resources/Files/Sources"
|
|
||||||
|
return switch self {
|
||||||
|
case .app, .appOptions: "\(basePath)/App"
|
||||||
|
case .appArguments, .appBuilder, .environment, .loggerLevel: "\(basePath)/Library"
|
||||||
|
case .appTests, .testArguments: "\(basePath)/Test"
|
||||||
|
default: basePath
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,13 +16,13 @@ extension Folder {
|
|||||||
|
|
||||||
var path: String {
|
var path: String {
|
||||||
switch self {
|
switch self {
|
||||||
case .app: "App/Sources"
|
case .app: "App/Sources/"
|
||||||
case .libraryPublic: "Library/Sources/Public"
|
case .libraryPublic: "Library/Sources/Public/"
|
||||||
case .libraryInternal: "Library/Sources/Internal"
|
case .libraryInternal: "Library/Sources/Internal/"
|
||||||
case .root: ""
|
case .root: ""
|
||||||
case .testCasesPublic: "Test/Sources/Cases/Public"
|
case .testCasesPublic: "Test/Sources/Cases/Public/"
|
||||||
case .testCasesInternal: "Test/Sources/Cases/Internal"
|
case .testCasesInternal: "Test/Sources/Cases/Internal/"
|
||||||
case .testHelpers: "Test/Sources/Helpers"
|
case .testHelpers: "Test/Sources/Helpers/"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,40 +53,72 @@ struct FileTests {
|
|||||||
private extension FileTests {
|
private extension FileTests {
|
||||||
enum Expectation {
|
enum Expectation {
|
||||||
static let fileNames: [String] = [
|
static let fileNames: [String] = [
|
||||||
|
"App.swift",
|
||||||
|
"AppArguments.swift",
|
||||||
|
"AppBuilder.swift",
|
||||||
|
"AppOptions.swift",
|
||||||
|
"AppTests.swift",
|
||||||
"Dockerfile",
|
"Dockerfile",
|
||||||
".dockerignore",
|
".dockerignore",
|
||||||
|
"Environment+Properties.swift",
|
||||||
".gitignore",
|
".gitignore",
|
||||||
"LICENSE",
|
"LICENSE",
|
||||||
|
"LoggerLevel+Conformances.swift",
|
||||||
"Package.swift",
|
"Package.swift",
|
||||||
"README.md"
|
"README.md",
|
||||||
|
"TestArguments.swift"
|
||||||
]
|
]
|
||||||
|
|
||||||
static let filePaths: [String] = [
|
static let filePaths: [String] = [
|
||||||
|
"App/Sources/App.swift",
|
||||||
|
"Library/Sources/Public/AppArguments.swift",
|
||||||
|
"Library/Sources/Public/AppBuilder.swift",
|
||||||
|
"App/Sources/AppOptions.swift",
|
||||||
|
"Test/Sources/Cases/Public/AppTests.swift",
|
||||||
"Dockerfile",
|
"Dockerfile",
|
||||||
".dockerignore",
|
".dockerignore",
|
||||||
|
"Library/Sources/Internal/Environment+Properties.swift",
|
||||||
".gitignore",
|
".gitignore",
|
||||||
"LICENSE",
|
"LICENSE",
|
||||||
|
"Library/Sources/Internal/LoggerLevel+Conformances.swift",
|
||||||
"Package.swift",
|
"Package.swift",
|
||||||
"README.md"
|
"README.md",
|
||||||
|
"Test/Sources/Helpers/TestArguments.swift"
|
||||||
]
|
]
|
||||||
|
|
||||||
static let folders: [Folder] = [
|
static let folders: [Folder] = [
|
||||||
|
.app,
|
||||||
|
.libraryPublic,
|
||||||
|
.libraryPublic,
|
||||||
|
.app,
|
||||||
|
.testCasesPublic,
|
||||||
.root,
|
.root,
|
||||||
.root,
|
.root,
|
||||||
|
.libraryInternal,
|
||||||
.root,
|
.root,
|
||||||
.root,
|
.root,
|
||||||
|
.libraryInternal,
|
||||||
.root,
|
.root,
|
||||||
.root
|
.root,
|
||||||
|
.testHelpers
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
static let resourcePaths: [String] = [
|
static let resourcePaths: [String] = [
|
||||||
|
"Resources/Files/Sources/App",
|
||||||
|
"Resources/Files/Sources/Library",
|
||||||
|
"Resources/Files/Sources/Library",
|
||||||
|
"Resources/Files/Sources/App",
|
||||||
|
"Resources/Files/Sources/Test",
|
||||||
"Resources/Files/Sources",
|
"Resources/Files/Sources",
|
||||||
"Resources/Files/Sources",
|
"Resources/Files/Sources",
|
||||||
|
"Resources/Files/Sources/Library",
|
||||||
"Resources/Files/Sources",
|
"Resources/Files/Sources",
|
||||||
"Resources/Files/Sources",
|
"Resources/Files/Sources",
|
||||||
|
"Resources/Files/Sources/Library",
|
||||||
"Resources/Files/Sources",
|
"Resources/Files/Sources",
|
||||||
"Resources/Files/Sources"
|
"Resources/Files/Sources",
|
||||||
|
"Resources/Files/Sources/Test"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user