feat: Updating command options.

This commit is contained in:
2024-12-24 10:39:56 -05:00
parent f2a2374c4f
commit 8aa4b73cab
12 changed files with 249 additions and 328 deletions

View File

@@ -6,8 +6,6 @@ import Foundation
import GitClient
import ShellClient
// TODO: Integrate ConfigurationClient
public extension DependencyValues {
var cliClient: CliClient {
@@ -35,26 +33,55 @@ public struct CliClient: Sendable {
public struct SharedOptions: Equatable, Sendable {
let allowPreReleaseTag: Bool
let dryRun: Bool
let gitDirectory: String?
let logLevel: Logger.Level
let configuration: Configuration
let target: Configuration.Target?
let branch: Configuration.Branch?
let semvar: Configuration.SemVar?
let configurationFile: String?
public init(
allowPreReleaseTag: Bool = true,
dryRun: Bool = false,
gitDirectory: String? = nil,
logLevel: Logger.Level = .debug,
configuration: Configuration
target: Configuration.Target? = nil,
branch: Configuration.Branch? = nil,
semvar: Configuration.SemVar? = nil,
configurationFile: String? = nil
) {
self.allowPreReleaseTag = allowPreReleaseTag
self.dryRun = dryRun
self.gitDirectory = gitDirectory
self.logLevel = logLevel
self.configuration = configuration
self.target = target
self.branch = branch
self.semvar = semvar
self.configurationFile = configurationFile
}
var allowPreReleaseTag: Bool {
guard let semvar = configuration.strategy?.semvar else { return false }
return semvar.preRelease != nil
public init(
allowPreReleaseTag: Bool = true,
dryRun: Bool = false,
gitDirectory: String? = nil,
verbose: Int,
target: Configuration.Target? = nil,
branch: Configuration.Branch? = nil,
semvar: Configuration.SemVar? = nil,
configurationFile: String? = nil
) {
self.init(
allowPreReleaseTag: allowPreReleaseTag,
dryRun: dryRun,
gitDirectory: gitDirectory,
logLevel: .init(verbose: verbose),
target: target,
branch: branch,
semvar: semvar,
configurationFile: configurationFile
)
}
}

View File

@@ -0,0 +1,70 @@
import ConfigurationClient
import Dependencies
import FileClient
import Foundation
extension Configuration {
func mergingTarget(_ otherTarget: Configuration.Target?) -> Self {
.init(
target: otherTarget ?? target,
strategy: strategy
)
}
func mergingStrategy(_ otherStrategy: Configuration.VersionStrategy?) -> Self {
.init(
target: target,
strategy: strategy?.merging(otherStrategy)
)
}
}
extension Configuration.Branch {
func merging(_ other: Self?) -> Self {
return .init(includeCommitSha: other?.includeCommitSha ?? includeCommitSha)
}
}
extension Configuration.SemVar {
func merging(_ other: Self?) -> Self {
.init(
preRelease: other?.preRelease ?? preRelease,
requireExistingFile: other?.requireExistingFile ?? requireExistingFile,
requireExistingSemVar: other?.requireExistingSemVar ?? requireExistingSemVar
)
}
}
extension Configuration.VersionStrategy {
func merging(_ other: Self?) -> Self {
guard let branch else {
guard let semvar else { return self }
return .semvar(semvar.merging(other?.semvar))
}
return .branch(branch.merging(other?.branch))
}
}
extension Configuration {
func merging(_ other: Self?) -> Self {
var output = self
output = output.mergingTarget(other?.target)
output = output.mergingStrategy(other?.strategy)
return output
}
}
@discardableResult
func withConfiguration<T>(
path: String?,
_ operation: (Configuration) async throws -> T
) async throws -> T {
@Dependency(\.configurationClient) var configurationClient
let configuration = try await configurationClient.findAndLoad(
path != nil ? URL(filePath: path!) : nil
)
return try await operation(configuration)
}

View File

@@ -1,3 +1,4 @@
import ConfigurationClient
import Dependencies
import FileClient
import Foundation
@@ -13,19 +14,37 @@ public extension CliClient.SharedOptions {
try await withDependencies {
$0.logger.logLevel = logLevel
} operation: {
@Dependency(\.logger) var logger
// Load the default configuration, if it exists.
try await withConfiguration(path: configurationFile) { configuration in
@Dependency(\.logger) var logger
let targetUrl = try configuration.targetUrl(gitDirectory: gitDirectory)
logger.debug("Target: \(targetUrl.cleanFilePath)")
// Merge any configuration set from caller into default configuration.
var configuration = configuration
configuration = configuration.mergingTarget(target)
try await operation(
configuration.currentVersion(
targetUrl: targetUrl,
gitDirectory: gitDirectory
if configuration.strategy?.branch != nil, let branch {
configuration = configuration.mergingStrategy(.branch(branch))
} else if let semvar {
configuration = configuration.mergingStrategy(.semvar(semvar))
}
logger.debug("Configuration: \(configuration)")
// This will fail if the target url is not set properly.
let targetUrl = try configuration.targetUrl(gitDirectory: gitDirectory)
logger.debug("Target: \(targetUrl.cleanFilePath)")
// Perform the operation, which generates the new version and writes it.
try await operation(
configuration.currentVersion(
targetUrl: targetUrl,
gitDirectory: gitDirectory
)
)
)
return targetUrl.cleanFilePath
// Return the file path we wrote the version to.
return targetUrl.cleanFilePath
}
}
}

View File

@@ -1,104 +0,0 @@
// import ConfigurationClient
// import Dependencies
// import FileClient
// import struct Foundation.URL
// import GitClient
//
// @_spi(Internal)
// public extension CliClient.PreReleaseStrategy {
//
// func preReleaseString(gitDirectory: String?) async throws -> String {
// @Dependency(\.gitClient) var gitClient
// switch self {
// case let .custom(string, child):
// guard let child else { return string }
// return try await "\(string)-\(child.preReleaseString(gitDirectory: gitDirectory))"
// case .tag:
// return try await gitClient.version(.init(
// gitDirectory: gitDirectory,
// style: .tag(exactMatch: false)
// )).description
// case .branchAndCommit:
// return try await gitClient.version(.init(
// gitDirectory: gitDirectory,
// style: .branch(commitSha: true)
// )).description
// }
// }
// }
//
// @_spi(Internal)
// public extension CliClient.VersionStrategy.SemVarOptions {
//
// private func applyingPreRelease(_ semVar: SemVar, _ gitDirectory: String?) async throws -> SemVar {
// guard let preReleaseStrategy else { return semVar }
// let preRelease = try await preReleaseStrategy.preReleaseString(gitDirectory: gitDirectory)
// return semVar.applyingPreRelease(preRelease)
// }
//
// func currentVersion(file: URL, gitDirectory: String? = nil) async throws -> CurrentVersionContainer.Version {
// @Dependency(\.fileClient) var fileClient
// @Dependency(\.gitClient) var gitClient
//
// let fileOutput = try? await fileClient.semVar(file: file, gitDirectory: gitDirectory)
// var semVar = fileOutput?.semVar
// let usesOptionalType = fileOutput?.usesOptionalType
//
// if requireExistingFile {
// guard let semVar else {
// throw CliClientError.fileDoesNotExist(path: file.cleanFilePath)
// }
// return try await .semVar(
// applyingPreRelease(semVar, gitDirectory),
// usesOptionalType: usesOptionalType ?? false
// )
// }
//
// // Didn't have existing semVar loaded from file, so check for git-tag.
//
// semVar = try await gitClient.version(.init(
// gitDirectory: gitDirectory,
// style: .tag(exactMatch: false)
// )).semVar
// if requireExistingSemVar {
// guard let semVar else {
// fatalError()
// }
// return try await .semVar(
// applyingPreRelease(semVar, gitDirectory),
// usesOptionalType: usesOptionalType ?? false
// )
// }
//
// return try await .semVar(
// applyingPreRelease(.init(), gitDirectory),
// usesOptionalType: usesOptionalType ?? false
// )
// }
// }
//
// @_spi(Internal)
// public extension CliClient.VersionStrategy {
//
// func currentVersion(file: URL, gitDirectory: String?) async throws -> CurrentVersionContainer {
// @Dependency(\.gitClient) var gitClient
//
// switch self {
// case .branchAndCommit:
// return try await .init(
// targetUrl: file,
// version: .string(
// gitClient.version(.init(
// gitDirectory: gitDirectory,
// style: .branch(commitSha: true)
// )).description
// )
// )
// case let .semVar(options):
// return try await .init(
// targetUrl: file,
// version: options.currentVersion(file: file, gitDirectory: gitDirectory)
// )
// }
// }
// }