feat: Integrates a precedence configuration setting, needs a command-line option.
All checks were successful
CI / Ubuntu (push) Successful in 2m47s

This commit is contained in:
2024-12-28 22:15:24 -05:00
parent 9631c62ee3
commit f1eb883b93
4 changed files with 60 additions and 19 deletions

View File

@@ -147,13 +147,23 @@ extension CliClient.SharedOptions {
try await write(container) try await write(container)
case let .semvar(semvar): 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 { guard let version else {
throw CliClientError.semVarNotFound(message: "Failed to parse a valid semvar to bump.") 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) let bumped = version.bump(type)
logger.dump(bumped, level: .trace) { "Bumped version:\n\($0)" }
try await write(.semvar(semvar.withUpdateNextVersion(bumped))) try await write(.semvar(semvar.withUpdateNextVersion(bumped)))
} }
} }

View File

@@ -6,8 +6,8 @@ import Foundation
import LoggingExtensions import LoggingExtensions
enum VersionContainer: Sendable { enum VersionContainer: Sendable {
case branch(CurrentVersionContainer2<String>) case branch(CurrentVersionContainer<String>)
case semvar(CurrentVersionContainer2<SemVar>) case semvar(CurrentVersionContainer<SemVar>)
static func load( static func load(
projectDirectory: String?, projectDirectory: String?,
@@ -31,18 +31,20 @@ enum VersionContainer: Sendable {
} }
} }
struct CurrentVersionContainer2<Version> { // TODO: Add a precedence field for which version to prefer, should also be specified in
// configuration.
struct CurrentVersionContainer<Version> {
let targetUrl: URL let targetUrl: URL
let usesOptionalType: Bool let usesOptionalType: Bool
let loadedVersion: Version? let loadedVersion: Version?
// TODO: Rename to strategyVersion let precedence: Configuration.SemVar.Precedence?
let nextVersion: Version? let strategyVersion: Version?
} }
extension CurrentVersionContainer2: Equatable where Version: Equatable { extension CurrentVersionContainer: Equatable where Version: Equatable {
var hasChanges: Bool { var hasChanges: Bool {
switch (loadedVersion, nextVersion) { switch (loadedVersion, strategyVersion) {
case (.none, .none): case (.none, .none):
return false return false
case (.some, .none), 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( static func load(
branch: Configuration.Branch, branch: Configuration.Branch,
@@ -81,17 +83,19 @@ extension CurrentVersionContainer2 where Version == String {
targetUrl: url, targetUrl: url,
usesOptionalType: loaded?.1 ?? true, usesOptionalType: loaded?.1 ?? true,
loadedVersion: loaded?.0, loadedVersion: loaded?.0,
nextVersion: next.description precedence: nil,
strategyVersion: next.description
) )
} }
var versionString: String? { 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 { static func load(semvar: Configuration.SemVar, gitDirectory: String?, url: URL) async throws -> Self {
@Dependency(\.fileClient) var fileClient @Dependency(\.fileClient) var fileClient
@Dependency(\.logger) var logger @Dependency(\.logger) var logger
@@ -109,7 +113,8 @@ extension CurrentVersionContainer2 where Version == SemVar {
targetUrl: url, targetUrl: url,
usesOptionalType: usesOptionalType, usesOptionalType: usesOptionalType,
loadedVersion: loaded, loadedVersion: loaded,
nextVersion: next precedence: semvar.precedence,
strategyVersion: next
) )
} }
@@ -152,11 +157,26 @@ extension CurrentVersionContainer2 where Version == SemVar {
} }
func versionString(withPreRelease: Bool) -> String? { func versionString(withPreRelease: Bool) -> String? {
nextVersion?.versionString(withPreReleaseTag: withPreRelease) let version: SemVar?
?? loadedVersion?.versionString(withPreReleaseTag: withPreRelease)
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 { 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
)
} }
} }

View File

@@ -251,6 +251,8 @@ public extension Configuration {
public let allowPreRelease: Bool? public let allowPreRelease: Bool?
public let precedence: Precedence?
/// Optional pre-releas suffix strategy. /// Optional pre-releas suffix strategy.
public let preRelease: PreRelease? public let preRelease: PreRelease?
@@ -264,12 +266,14 @@ public extension Configuration {
public init( public init(
allowPreRelease: Bool? = true, allowPreRelease: Bool? = true,
precedence: Precedence? = .default,
preRelease: PreRelease? = nil, preRelease: PreRelease? = nil,
requireExistingFile: Bool? = false, requireExistingFile: Bool? = false,
requireExistingSemVar: Bool? = false, requireExistingSemVar: Bool? = false,
strategy: Strategy? = nil strategy: Strategy? = nil
) { ) {
self.allowPreRelease = allowPreRelease self.allowPreRelease = allowPreRelease
self.precedence = precedence
self.preRelease = preRelease self.preRelease = preRelease
self.requireExistingFile = requireExistingFile self.requireExistingFile = requireExistingFile
self.requireExistingSemVar = requireExistingSemVar self.requireExistingSemVar = requireExistingSemVar
@@ -281,6 +285,13 @@ public extension Configuration {
case gitTag(exactMatch: Bool? = false) case gitTag(exactMatch: Bool? = false)
} }
public enum Precedence: String, Codable, Equatable, Sendable {
case file
case strategy
public static var `default`: Self { .file }
}
} }
} }