feat: Prep to update current version container in cli-client.
This commit is contained in:
@@ -96,45 +96,6 @@ public extension CliClient.SharedOptions {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Add optional property for currentVersion (loaded version from file)
|
|
||||||
// and rename version to nextVersion.
|
|
||||||
|
|
||||||
@_spi(Internal)
|
|
||||||
public struct CurrentVersionContainer: Sendable {
|
|
||||||
|
|
||||||
let targetUrl: URL
|
|
||||||
let currentVersion: CurrentVersion?
|
|
||||||
let version: Version
|
|
||||||
|
|
||||||
var usesOptionalType: Bool {
|
|
||||||
switch version {
|
|
||||||
case .string: return false
|
|
||||||
case let .semvar(_, usesOptionalType, _): return usesOptionalType
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public enum CurrentVersion: Sendable {
|
|
||||||
case branch(String, usesOptionalType: Bool)
|
|
||||||
case semvar(SemVar, usesOptionalType: Bool)
|
|
||||||
}
|
|
||||||
|
|
||||||
public enum Version: Sendable {
|
|
||||||
// TODO: Call this branch for consistency.
|
|
||||||
case string(String)
|
|
||||||
// TODO: Remove has changes when currentVersion/nextVersion is implemented.
|
|
||||||
case semvar(SemVar, usesOptionalType: Bool = true, hasChanges: Bool)
|
|
||||||
|
|
||||||
func string(allowPreReleaseTag: Bool) throws -> String {
|
|
||||||
switch self {
|
|
||||||
case let .string(string):
|
|
||||||
return string
|
|
||||||
case let .semvar(semvar, usesOptionalType: _, hasChanges: _):
|
|
||||||
return semvar.versionString(withPreReleaseTag: allowPreReleaseTag)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extension CliClient.SharedOptions {
|
extension CliClient.SharedOptions {
|
||||||
|
|
||||||
func build(_ environment: [String: String]) async throws -> String {
|
func build(_ environment: [String: String]) async throws -> String {
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import ConfigurationClient
|
import ConfigurationClient
|
||||||
|
import CustomDump
|
||||||
import Dependencies
|
import Dependencies
|
||||||
import Foundation
|
import Foundation
|
||||||
import GitClient
|
import GitClient
|
||||||
@@ -119,6 +120,38 @@ public extension Configuration.SemVar {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extension Configuration.VersionStrategy {
|
||||||
|
|
||||||
|
func loadNextVersion(gitDirectory: String?) async throws -> CurrentVersionContainer.Version {
|
||||||
|
@Dependency(\.gitClient) var gitClient
|
||||||
|
@Dependency(\.logger) var logger
|
||||||
|
|
||||||
|
switch self {
|
||||||
|
case let .branch(includeCommitSha: includeCommitSha):
|
||||||
|
logger.trace("Loading next version for branch strategy...")
|
||||||
|
let next = try await gitClient.version(includeCommitSha: includeCommitSha, gitDirectory: gitDirectory)
|
||||||
|
logger.trace("Next version: \(next)")
|
||||||
|
return .string(next)
|
||||||
|
case .semvar:
|
||||||
|
logger.trace("Loading next version for semvar strategy...")
|
||||||
|
let semvar = semvar!
|
||||||
|
guard let strategy = semvar.strategy else {
|
||||||
|
// TODO: Error here.
|
||||||
|
fatalError()
|
||||||
|
}
|
||||||
|
let next = try await strategy.getSemvar(gitDirectory: gitDirectory)
|
||||||
|
var nextString = ""
|
||||||
|
customDump(next, to: &nextString)
|
||||||
|
logger.trace("Next version:\n\(nextString)")
|
||||||
|
|
||||||
|
// TODO: Need to check for pre-release and load it here.
|
||||||
|
|
||||||
|
// TODO: Fix optional type / has changes.
|
||||||
|
return .semvar(next, usesOptionalType: true, hasChanges: true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private extension Configuration.VersionStrategy {
|
private extension Configuration.VersionStrategy {
|
||||||
|
|
||||||
// TODO: This should just load the `nextVersion`, and should probably live on CurrentVersionContainer.
|
// TODO: This should just load the `nextVersion`, and should probably live on CurrentVersionContainer.
|
||||||
@@ -246,6 +279,7 @@ private extension Configuration.PreRelease {
|
|||||||
|
|
||||||
private extension Configuration.SemVar {
|
private extension Configuration.SemVar {
|
||||||
|
|
||||||
|
// TODO: Move this to SemVar, not Configuration.SemVar
|
||||||
func applyingPreRelease(_ semvar: SemVar, _ gitDirectory: String?) async throws -> SemVar {
|
func applyingPreRelease(_ semvar: SemVar, _ gitDirectory: String?) async throws -> SemVar {
|
||||||
@Dependency(\.logger) var logger
|
@Dependency(\.logger) var logger
|
||||||
logger.trace("Start apply pre-release to: \(semvar)")
|
logger.trace("Start apply pre-release to: \(semvar)")
|
||||||
|
|||||||
103
Sources/CliClient/Internal/CurrentVersionContainer.swift
Normal file
103
Sources/CliClient/Internal/CurrentVersionContainer.swift
Normal file
@@ -0,0 +1,103 @@
|
|||||||
|
import ConfigurationClient
|
||||||
|
import CustomDump
|
||||||
|
import Dependencies
|
||||||
|
import FileClient
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
// TODO: Add optional property for currentVersion (loaded version from file)
|
||||||
|
// and rename version to nextVersion.
|
||||||
|
|
||||||
|
/// An internal type that holds onto the loaded version from a file (if found),
|
||||||
|
/// the computed next version, and the target file url.
|
||||||
|
///
|
||||||
|
@_spi(Internal)
|
||||||
|
public struct CurrentVersionContainer: Sendable {
|
||||||
|
|
||||||
|
let targetUrl: URL
|
||||||
|
let currentVersion: CurrentVersion?
|
||||||
|
let version: Version
|
||||||
|
|
||||||
|
// TODO: Derive from current version.
|
||||||
|
var usesOptionalType: Bool {
|
||||||
|
switch version {
|
||||||
|
case .string: return false
|
||||||
|
case let .semvar(_, usesOptionalType, _): return usesOptionalType
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var hasChanges: Bool {
|
||||||
|
guard let currentVersion else { return false }
|
||||||
|
switch (currentVersion, version) {
|
||||||
|
case let (.branch(currentString, _), .string(nextString)):
|
||||||
|
return currentString == nextString
|
||||||
|
case let (.semvar(currentSemvar, _), .semvar(nextSemvar, _, _)):
|
||||||
|
return currentSemvar == nextSemvar
|
||||||
|
// TODO: What to do with mis-matched values.
|
||||||
|
case (.branch, .semvar),
|
||||||
|
(.semvar, .string):
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum CurrentVersion: Sendable {
|
||||||
|
case branch(String, usesOptionalType: Bool)
|
||||||
|
case semvar(SemVar, usesOptionalType: Bool)
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum Version: Sendable {
|
||||||
|
// TODO: Call this branch for consistency.
|
||||||
|
case string(String)
|
||||||
|
// TODO: Remove has changes when currentVersion/nextVersion is implemented.
|
||||||
|
case semvar(SemVar, usesOptionalType: Bool = true, hasChanges: Bool)
|
||||||
|
|
||||||
|
func string(allowPreReleaseTag: Bool) throws -> String {
|
||||||
|
switch self {
|
||||||
|
case let .string(string):
|
||||||
|
return string
|
||||||
|
case let .semvar(semvar, usesOptionalType: _, hasChanges: _):
|
||||||
|
return semvar.versionString(withPreReleaseTag: allowPreReleaseTag)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension CurrentVersionContainer {
|
||||||
|
|
||||||
|
static func load(
|
||||||
|
configuration: Configuration,
|
||||||
|
sharedOptions: CliClient.SharedOptions
|
||||||
|
) async throws -> Self {
|
||||||
|
@Dependency(\.fileClient) var fileClient
|
||||||
|
@Dependency(\.logger) var logger
|
||||||
|
|
||||||
|
let targetUrl = try configuration.targetUrl(gitDirectory: sharedOptions.projectDirectory)
|
||||||
|
logger.trace("Begin loading current version from: \(targetUrl.cleanFilePath)")
|
||||||
|
|
||||||
|
let currentVersion = try await fileClient.loadCurrentVersion(
|
||||||
|
url: targetUrl,
|
||||||
|
gitDirectory: sharedOptions.projectDirectory,
|
||||||
|
expectsBranch: configuration.strategy?.branch != nil
|
||||||
|
)
|
||||||
|
var currentVersionString = ""
|
||||||
|
customDump(currentVersion, to: ¤tVersionString)
|
||||||
|
logger.trace("Loaded current version:\n\(currentVersionString)")
|
||||||
|
|
||||||
|
if configuration.strategy?.semvar?.requireExistingFile == true {
|
||||||
|
guard currentVersion != nil else {
|
||||||
|
// TODO: Better error.
|
||||||
|
throw CliClientError.semVarNotFound
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check that there's a valid strategy to get the next version.
|
||||||
|
guard let strategy = configuration.strategy else {
|
||||||
|
// TODO: Return without a next version here when nextVersion is optional.
|
||||||
|
fatalError()
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: make optional?
|
||||||
|
let next = try await strategy.loadNextVersion(gitDirectory: sharedOptions.projectDirectory)
|
||||||
|
|
||||||
|
fatalError()
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user