import Dependencies import DependenciesMacros import Foundation public extension DependencyValues { var cliClient: CliClient { get { self[CliClient.self] } set { self[CliClient.self] = newValue } } } @DependencyClient public struct CliClient: Sendable { public var decoder: @Sendable () -> JSONDecoder = { .init() } public var encoder: @Sendable () -> JSONEncoder = { .init() } public var loadConfiguration: @Sendable () throws -> Configuration } extension CliClient: DependencyKey { public static func live( decoder: JSONDecoder = .init(), encoder: JSONEncoder = .init(), env: [String: String] ) -> Self { .init { decoder } encoder: { encoder } loadConfiguration: { @Dependency(\.logger) var logger @Dependency(\.fileClient) var fileClient let urls = try findConfigurationFiles(env: env) var env = env logger.trace("Loading configuration from: \(urls)") for url in urls { try fileClient.loadFile(url, &env, decoder) } return try .fromEnv(env, encoder: encoder, decoder: decoder) } } public static var liveValue: CliClient { .live(env: ProcessInfo.processInfo.environment) } public static let testValue: CliClient = Self() }