feat: Moves logging extensions into it's own module, moves configuration merging into config-client, fixes merging bug.

This commit is contained in:
2024-12-25 20:06:52 -05:00
parent fbb4a22e98
commit 56359f3488
11 changed files with 269 additions and 135 deletions

View File

@@ -0,0 +1,76 @@
import Dependencies
import FileClient
import Foundation
import ShellClient
@_spi(Internal)
public extension Configuration {
func merging(_ other: Self?) -> Self {
mergingTarget(other?.target).mergingStrategy(other?.strategy)
}
private func mergingTarget(_ otherTarget: Configuration.Target?) -> Self {
.init(
target: otherTarget ?? target,
strategy: strategy
)
}
private func mergingStrategy(_ otherStrategy: Configuration.VersionStrategy?) -> Self {
.init(
target: target,
strategy: strategy?.merging(otherStrategy)
)
}
}
@_spi(Internal)
public extension Configuration.PreRelease {
func merging(_ other: Self?) -> Self {
return .init(
prefix: other?.prefix ?? prefix,
strategy: other?.strategy ?? strategy
)
}
}
@_spi(Internal)
public extension Configuration.Branch {
func merging(_ other: Self?) -> Self {
return .init(includeCommitSha: other?.includeCommitSha ?? includeCommitSha)
}
}
@_spi(Internal)
public extension Configuration.SemVar {
func merging(_ other: Self?) -> Self {
.init(
allowPreRelease: other?.allowPreRelease ?? allowPreRelease,
preRelease: preRelease == nil ? other?.preRelease : preRelease!.merging(other?.preRelease),
requireExistingFile: other?.requireExistingFile ?? requireExistingFile,
requireExistingSemVar: other?.requireExistingSemVar ?? requireExistingSemVar,
strategy: other?.strategy ?? strategy
)
}
}
@_spi(Internal)
public extension Configuration.VersionStrategy {
func merging(_ other: Self?) -> Self {
if let otherBranch = other?.branch {
guard let branch else {
return .branch(otherBranch)
}
return .branch(branch.merging(otherBranch))
}
guard let branch else {
guard let semvar else {
return other ?? self
}
return .semvar(semvar.merging(other?.semvar))
}
return .branch(branch.merging(other?.branch))
}
}

View File

@@ -16,6 +16,9 @@ public extension DependencyValues {
@DependencyClient
public struct ConfigurationClient: Sendable {
/// The default file name for a configuration file.
public var defaultFileName: @Sendable () -> String = { "test.json" }
/// Find a configuration file in the given directory or in current working directory.
public var find: @Sendable (URL?) async throws -> URL?
@@ -32,6 +35,25 @@ public struct ConfigurationClient: Sendable {
}
return (try? await load(url)) ?? .default
}
/// Loads configuration from the given path, or searches for the default file and loads it.
/// Optionally merges other configuration, then perform an operation with the loaded configuration.
///
/// - Parameters:
/// - path: Optional file path of the configuration to load.
/// - other: Optional configuration to merge with the loaded configuration.
/// - operation: The operation to perform with the loaded configuration.
@discardableResult
public func withConfiguration<T>(
path: String?,
merging other: Configuration? = nil,
operation: (Configuration) async throws -> T
) async throws -> T {
let configuration = try await findAndLoad(
path != nil ? URL(filePath: path!) : nil
)
return try await operation(configuration.merging(other))
}
}
extension ConfigurationClient: DependencyKey {
@@ -39,6 +61,7 @@ extension ConfigurationClient: DependencyKey {
public static var liveValue: ConfigurationClient {
.init(
defaultFileName: { "\(Constants.defaultFileNameWithoutExtension).json" },
find: { try await findConfiguration($0) },
load: { try await loadConfiguration($0) },
write: { try await writeConfiguration($0, to: $1) }