From f1eb883b931877e91ee02c941eba4daee53ee3ac Mon Sep 17 00:00:00 2001 From: Michael Housh Date: Sat, 28 Dec 2024 22:15:24 -0500 Subject: [PATCH] feat: Integrates a precedence configuration setting, needs a command-line option. --- .../CliClient/Internal/CliClient+run.swift | 16 ++++-- ...ns.swift => Configuration+targetUrl.swift} | 0 ...Container.swift => VersionContainer.swift} | 52 +++++++++++++------ .../ConfigurationClient/Configuration.swift | 11 ++++ 4 files changed, 60 insertions(+), 19 deletions(-) rename Sources/CliClient/Internal/{ConfigurationExtensions.swift => Configuration+targetUrl.swift} (100%) rename Sources/CliClient/Internal/{CurrentVersionContainer.swift => VersionContainer.swift} (70%) diff --git a/Sources/CliClient/Internal/CliClient+run.swift b/Sources/CliClient/Internal/CliClient+run.swift index 60b82de..a63e337 100644 --- a/Sources/CliClient/Internal/CliClient+run.swift +++ b/Sources/CliClient/Internal/CliClient+run.swift @@ -147,13 +147,23 @@ extension CliClient.SharedOptions { try await write(container) case let .semvar(semvar): - // FIX: Fix with an option for precedence. - let version = semvar.loadedVersion ?? semvar.nextVersion + + let version: SemVar? + + switch semvar.precedence ?? .default { + case .file: + version = semvar.loadedVersion ?? semvar.strategyVersion + case .strategy: + version = semvar.strategyVersion ?? semvar.loadedVersion + } + + // let version = semvar.loadedVersion ?? semvar.nextVersion guard let version else { throw CliClientError.semVarNotFound(message: "Failed to parse a valid semvar to bump.") } - logger.debug("Semvar prior to bumping: \(version)") + logger.dump(version, level: .debug) { "Version prior to bumping:\n\($0)" } let bumped = version.bump(type) + logger.dump(bumped, level: .trace) { "Bumped version:\n\($0)" } try await write(.semvar(semvar.withUpdateNextVersion(bumped))) } } diff --git a/Sources/CliClient/Internal/ConfigurationExtensions.swift b/Sources/CliClient/Internal/Configuration+targetUrl.swift similarity index 100% rename from Sources/CliClient/Internal/ConfigurationExtensions.swift rename to Sources/CliClient/Internal/Configuration+targetUrl.swift diff --git a/Sources/CliClient/Internal/CurrentVersionContainer.swift b/Sources/CliClient/Internal/VersionContainer.swift similarity index 70% rename from Sources/CliClient/Internal/CurrentVersionContainer.swift rename to Sources/CliClient/Internal/VersionContainer.swift index 3acb70a..c113727 100644 --- a/Sources/CliClient/Internal/CurrentVersionContainer.swift +++ b/Sources/CliClient/Internal/VersionContainer.swift @@ -6,8 +6,8 @@ import Foundation import LoggingExtensions enum VersionContainer: Sendable { - case branch(CurrentVersionContainer2) - case semvar(CurrentVersionContainer2) + case branch(CurrentVersionContainer) + case semvar(CurrentVersionContainer) static func load( projectDirectory: String?, @@ -31,18 +31,20 @@ enum VersionContainer: Sendable { } } -struct CurrentVersionContainer2 { +// TODO: Add a precedence field for which version to prefer, should also be specified in +// configuration. +struct CurrentVersionContainer { let targetUrl: URL let usesOptionalType: Bool let loadedVersion: Version? - // TODO: Rename to strategyVersion - let nextVersion: Version? + let precedence: Configuration.SemVar.Precedence? + let strategyVersion: Version? } -extension CurrentVersionContainer2: Equatable where Version: Equatable { +extension CurrentVersionContainer: Equatable where Version: Equatable { var hasChanges: Bool { - switch (loadedVersion, nextVersion) { + switch (loadedVersion, strategyVersion) { case (.none, .none): return false case (.some, .none), @@ -54,9 +56,9 @@ extension CurrentVersionContainer2: Equatable where Version: Equatable { } } -extension CurrentVersionContainer2: Sendable where Version: Sendable {} +extension CurrentVersionContainer: Sendable where Version: Sendable {} -extension CurrentVersionContainer2 where Version == String { +extension CurrentVersionContainer where Version == String { static func load( branch: Configuration.Branch, @@ -81,17 +83,19 @@ extension CurrentVersionContainer2 where Version == String { targetUrl: url, usesOptionalType: loaded?.1 ?? true, loadedVersion: loaded?.0, - nextVersion: next.description + precedence: nil, + strategyVersion: next.description ) } var versionString: String? { - loadedVersion ?? nextVersion + loadedVersion ?? strategyVersion } } -extension CurrentVersionContainer2 where Version == SemVar { +extension CurrentVersionContainer where Version == SemVar { + // TODO: Update to use precedence and not fetch `nextVersion` if we loaded a file version. static func load(semvar: Configuration.SemVar, gitDirectory: String?, url: URL) async throws -> Self { @Dependency(\.fileClient) var fileClient @Dependency(\.logger) var logger @@ -109,7 +113,8 @@ extension CurrentVersionContainer2 where Version == SemVar { targetUrl: url, usesOptionalType: usesOptionalType, loadedVersion: loaded, - nextVersion: next + precedence: semvar.precedence, + strategyVersion: next ) } @@ -152,11 +157,26 @@ extension CurrentVersionContainer2 where Version == SemVar { } func versionString(withPreRelease: Bool) -> String? { - nextVersion?.versionString(withPreReleaseTag: withPreRelease) - ?? loadedVersion?.versionString(withPreReleaseTag: withPreRelease) + let version: SemVar? + + switch precedence ?? .default { + case .file: + version = loadedVersion ?? strategyVersion + case .strategy: + version = strategyVersion ?? loadedVersion + } + + return version?.versionString(withPreReleaseTag: withPreRelease) } + // TODO: Move to where `bump` is declared and make fileprivate. func withUpdateNextVersion(_ next: SemVar) -> Self { - .init(targetUrl: targetUrl, usesOptionalType: usesOptionalType, loadedVersion: loadedVersion, nextVersion: next) + .init( + targetUrl: targetUrl, + usesOptionalType: usesOptionalType, + loadedVersion: loadedVersion, + precedence: .strategy, // make sure to use the next version, since it was specified, as this is called from `bump`. + strategyVersion: next + ) } } diff --git a/Sources/ConfigurationClient/Configuration.swift b/Sources/ConfigurationClient/Configuration.swift index 02e699e..04a8b8e 100644 --- a/Sources/ConfigurationClient/Configuration.swift +++ b/Sources/ConfigurationClient/Configuration.swift @@ -251,6 +251,8 @@ public extension Configuration { public let allowPreRelease: Bool? + public let precedence: Precedence? + /// Optional pre-releas suffix strategy. public let preRelease: PreRelease? @@ -264,12 +266,14 @@ public extension Configuration { public init( allowPreRelease: Bool? = true, + precedence: Precedence? = .default, preRelease: PreRelease? = nil, requireExistingFile: Bool? = false, requireExistingSemVar: Bool? = false, strategy: Strategy? = nil ) { self.allowPreRelease = allowPreRelease + self.precedence = precedence self.preRelease = preRelease self.requireExistingFile = requireExistingFile self.requireExistingSemVar = requireExistingSemVar @@ -281,6 +285,13 @@ public extension Configuration { case gitTag(exactMatch: Bool? = false) } + public enum Precedence: String, Codable, Equatable, Sendable { + case file + case strategy + + public static var `default`: Self { .file } + } + } }