feat: Pre-release prefix now works with git-tag straegy. Working on todo items.
All checks were successful
CI / Ubuntu (push) Successful in 2m12s
All checks were successful
CI / Ubuntu (push) Successful in 2m12s
This commit is contained in:
27
.bump-version.pre.json
Normal file
27
.bump-version.pre.json
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
{
|
||||||
|
"strategy" : {
|
||||||
|
"semvar" : {
|
||||||
|
"allowPreRelease" : true,
|
||||||
|
"preRelease" : {
|
||||||
|
"prefix" : "rc",
|
||||||
|
"strategy" : {
|
||||||
|
"gitTag" : {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"requireExistingFile" : false,
|
||||||
|
"requireExistingSemVar" : false,
|
||||||
|
"strategy" : {
|
||||||
|
"gitTag" : {
|
||||||
|
"exactMatch" : false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"target" : {
|
||||||
|
"module" : {
|
||||||
|
"name" : "BumpVersion"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -189,7 +189,8 @@ the output is as the suffix.
|
|||||||
"preRelease": {
|
"preRelease": {
|
||||||
"strategy": {
|
"strategy": {
|
||||||
"command": {
|
"command": {
|
||||||
"arguments": ["my-command", "--some-option", "foo"]
|
"arguments": ["my-command", "--some-option", "foo"],
|
||||||
|
"allowPrefix": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,2 +1,2 @@
|
|||||||
// Do not set this variable, it is set during the build process.
|
// Do not set this variable, it is set during the build process.
|
||||||
let VERSION: String? = "0.2.1"
|
let VERSION: String? = "0.2.0-rc-5-ga26d869"
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ extension Configuration {
|
|||||||
|
|
||||||
func currentVersion(targetUrl: URL, gitDirectory: String?) async throws -> CurrentVersionContainer {
|
func currentVersion(targetUrl: URL, gitDirectory: String?) async throws -> CurrentVersionContainer {
|
||||||
guard let strategy else {
|
guard let strategy else {
|
||||||
throw ConfigurationParsingError.versionNotFound
|
throw ConfigurationParsingError.versionStrategyNotFound
|
||||||
}
|
}
|
||||||
return try await strategy.currentVersion(
|
return try await strategy.currentVersion(
|
||||||
targetUrl: targetUrl,
|
targetUrl: targetUrl,
|
||||||
@@ -23,7 +23,99 @@ extension Configuration {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extension Configuration.Target {
|
@_spi(Internal)
|
||||||
|
public extension Configuration.SemVar {
|
||||||
|
|
||||||
|
// TODO: Need to handle custom command semvar strategy.
|
||||||
|
|
||||||
|
func currentVersion(file: URL, gitDirectory: String? = nil) async throws -> CurrentVersionContainer.Version {
|
||||||
|
@Dependency(\.fileClient) var fileClient
|
||||||
|
@Dependency(\.gitClient) var gitClient
|
||||||
|
@Dependency(\.logger) var logger
|
||||||
|
|
||||||
|
let fileOutput = try? await fileClient.semvar(file: file, gitDirectory: gitDirectory)
|
||||||
|
var semVar = fileOutput?.semVar
|
||||||
|
|
||||||
|
logger.trace("file output semvar: \(String(describing: semVar))")
|
||||||
|
|
||||||
|
let usesOptionalType = fileOutput?.usesOptionalType
|
||||||
|
|
||||||
|
// We parsed a semvar from the existing file, use it.
|
||||||
|
if semVar != nil {
|
||||||
|
let semvarWithPreRelease = try await applyingPreRelease(semVar!, gitDirectory)
|
||||||
|
|
||||||
|
return .semvar(
|
||||||
|
semvarWithPreRelease,
|
||||||
|
usesOptionalType: usesOptionalType ?? false,
|
||||||
|
hasChanges: semvarWithPreRelease != semVar
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
if requireExistingFile == true {
|
||||||
|
logger.debug("Failed to parse existing file, and caller requires it.")
|
||||||
|
throw CliClientError.fileDoesNotExist(path: file.cleanFilePath)
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.trace("Does not require existing file, checking git-tag.")
|
||||||
|
|
||||||
|
// TODO: Is this what we want to do here? Seems that the strategy should be set by the client / configuration.
|
||||||
|
|
||||||
|
// 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 semVar != nil {
|
||||||
|
let semvarWithPreRelease = try await applyingPreRelease(semVar!, gitDirectory)
|
||||||
|
return .semvar(
|
||||||
|
semvarWithPreRelease,
|
||||||
|
usesOptionalType: usesOptionalType ?? false,
|
||||||
|
hasChanges: semvarWithPreRelease != semVar
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
if requireExistingSemVar == true {
|
||||||
|
logger.trace("Caller requires existing semvar and it was not found in file or git-tag.")
|
||||||
|
throw CliClientError.semVarNotFound
|
||||||
|
}
|
||||||
|
|
||||||
|
// Semvar doesn't exist, so create a new one.
|
||||||
|
logger.trace("Generating new semvar.")
|
||||||
|
return try await .semvar(
|
||||||
|
applyingPreRelease(.init(), gitDirectory),
|
||||||
|
usesOptionalType: usesOptionalType ?? false,
|
||||||
|
hasChanges: true
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private extension Configuration.VersionStrategy {
|
||||||
|
|
||||||
|
func currentVersion(targetUrl: URL, gitDirectory: String?) async throws -> CurrentVersionContainer {
|
||||||
|
@Dependency(\.gitClient) var gitClient
|
||||||
|
|
||||||
|
guard let branch else {
|
||||||
|
guard let semvar else {
|
||||||
|
throw ConfigurationParsingError.versionStrategyError(
|
||||||
|
message: "Neither branch nor semvar set on configuration."
|
||||||
|
)
|
||||||
|
}
|
||||||
|
return try await .init(
|
||||||
|
targetUrl: targetUrl,
|
||||||
|
version: semvar.currentVersion(file: targetUrl, gitDirectory: gitDirectory)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
return try await .init(
|
||||||
|
targetUrl: targetUrl,
|
||||||
|
version: .string(
|
||||||
|
gitClient.version(includeCommitSha: branch.includeCommitSha, gitDirectory: gitDirectory)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private extension Configuration.Target {
|
||||||
func url(gitDirectory: String?) throws -> URL {
|
func url(gitDirectory: String?) throws -> URL {
|
||||||
@Dependency(\.logger) var logger
|
@Dependency(\.logger) var logger
|
||||||
|
|
||||||
@@ -58,7 +150,7 @@ extension Configuration.Target {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extension GitClient {
|
private extension GitClient {
|
||||||
func version(includeCommitSha: Bool, gitDirectory: String?) async throws -> String {
|
func version(includeCommitSha: Bool, gitDirectory: String?) async throws -> String {
|
||||||
@Dependency(\.gitClient) var gitClient
|
@Dependency(\.gitClient) var gitClient
|
||||||
|
|
||||||
@@ -69,9 +161,8 @@ extension GitClient {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extension Configuration.PreRelease {
|
private extension Configuration.PreRelease {
|
||||||
|
|
||||||
// FIX: This needs to handle the pre-release type appropriatly.
|
|
||||||
func preReleaseString(gitDirectory: String?) async throws -> PreReleaseString? {
|
func preReleaseString(gitDirectory: String?) async throws -> PreReleaseString? {
|
||||||
guard let strategy else { return nil }
|
guard let strategy else { return nil }
|
||||||
|
|
||||||
@@ -90,10 +181,10 @@ extension Configuration.PreRelease {
|
|||||||
includeCommitSha: includeCommitSha,
|
includeCommitSha: includeCommitSha,
|
||||||
gitDirectory: gitDirectory
|
gitDirectory: gitDirectory
|
||||||
)
|
)
|
||||||
case let .command(arguments: arguments):
|
case let .command(arguments: arguments, allowPrefix: allowPrefix):
|
||||||
logger.trace("Command pre-release strategy, arguments: \(arguments).")
|
logger.trace("Command pre-release strategy, arguments: \(arguments).")
|
||||||
// TODO: What to do with allows prefix? Need a configuration setting for commands.
|
|
||||||
preReleaseString = try await asyncShellClient.background(.init(arguments))
|
preReleaseString = try await asyncShellClient.background(.init(arguments))
|
||||||
|
allowsPrefix = allowPrefix ?? false
|
||||||
case .gitTag:
|
case .gitTag:
|
||||||
logger.trace("Git tag pre-release strategy.")
|
logger.trace("Git tag pre-release strategy.")
|
||||||
logger.trace("This will ignore any set prefix.")
|
logger.trace("This will ignore any set prefix.")
|
||||||
@@ -105,18 +196,12 @@ extension Configuration.PreRelease {
|
|||||||
)).description
|
)).description
|
||||||
}
|
}
|
||||||
|
|
||||||
if let prefix {
|
if let prefix, allowsPrefix {
|
||||||
if allowsPrefix {
|
|
||||||
preReleaseString = "\(prefix)-\(preReleaseString)"
|
preReleaseString = "\(prefix)-\(preReleaseString)"
|
||||||
} else {
|
|
||||||
logger.warning("Found prefix, but pre-release strategy may not work properly, ignoring prefix.")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
guard suffix else { return .semvar(preReleaseString) }
|
guard suffix else { return .semvar(preReleaseString) }
|
||||||
return .suffix(preReleaseString)
|
return .suffix(preReleaseString)
|
||||||
|
|
||||||
// return preReleaseString
|
|
||||||
}
|
}
|
||||||
|
|
||||||
enum PreReleaseString: Sendable {
|
enum PreReleaseString: Sendable {
|
||||||
@@ -125,10 +210,9 @@ extension Configuration.PreRelease {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@_spi(Internal)
|
private extension Configuration.SemVar {
|
||||||
public extension Configuration.SemVar {
|
|
||||||
|
|
||||||
private 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)")
|
||||||
|
|
||||||
@@ -139,7 +223,6 @@ public extension Configuration.SemVar {
|
|||||||
return semvar
|
return semvar
|
||||||
}
|
}
|
||||||
|
|
||||||
// let preRelease = try await preReleaseStrategy.preReleaseString(gitDirectory: gitDirectory)
|
|
||||||
logger.trace("Pre-release string: \(preRelease)")
|
logger.trace("Pre-release string: \(preRelease)")
|
||||||
|
|
||||||
switch preRelease {
|
switch preRelease {
|
||||||
@@ -149,94 +232,15 @@ public extension Configuration.SemVar {
|
|||||||
guard let semvar = SemVar(string: string) else {
|
guard let semvar = SemVar(string: string) else {
|
||||||
throw CliClientError.preReleaseParsingError(string)
|
throw CliClientError.preReleaseParsingError(string)
|
||||||
}
|
}
|
||||||
|
if let prefix = self.preRelease?.prefix {
|
||||||
|
var prefixString = prefix
|
||||||
|
if let preReleaseString = semvar.preRelease {
|
||||||
|
prefixString = "\(prefix)-\(preReleaseString)"
|
||||||
|
}
|
||||||
|
return semvar.applyingPreRelease(prefixString)
|
||||||
|
}
|
||||||
return semvar
|
return semvar
|
||||||
}
|
}
|
||||||
|
|
||||||
// return semVar.applyingPreRelease(preRelease)
|
|
||||||
}
|
|
||||||
|
|
||||||
func currentVersion(file: URL, gitDirectory: String? = nil) async throws -> CurrentVersionContainer.Version {
|
|
||||||
@Dependency(\.fileClient) var fileClient
|
|
||||||
@Dependency(\.gitClient) var gitClient
|
|
||||||
@Dependency(\.logger) var logger
|
|
||||||
|
|
||||||
let fileOutput = try? await fileClient.semvar(file: file, gitDirectory: gitDirectory)
|
|
||||||
var semVar = fileOutput?.semVar
|
|
||||||
|
|
||||||
logger.trace("file output semvar: \(String(describing: semVar))")
|
|
||||||
|
|
||||||
let usesOptionalType = fileOutput?.usesOptionalType
|
|
||||||
|
|
||||||
// We parsed a semvar from the existing file, use it.
|
|
||||||
if semVar != nil {
|
|
||||||
let semvarWithPreRelease = try await applyingPreRelease(semVar!, gitDirectory)
|
|
||||||
|
|
||||||
return .semvar(
|
|
||||||
semvarWithPreRelease,
|
|
||||||
usesOptionalType: usesOptionalType ?? false,
|
|
||||||
hasChanges: semvarWithPreRelease != semVar
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
if requireExistingFile == true {
|
|
||||||
logger.debug("Failed to parse existing file, and caller requires it.")
|
|
||||||
throw CliClientError.fileDoesNotExist(path: file.cleanFilePath)
|
|
||||||
}
|
|
||||||
|
|
||||||
logger.trace("Does not require existing file, checking git-tag.")
|
|
||||||
|
|
||||||
// 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 semVar != nil {
|
|
||||||
let semvarWithPreRelease = try await applyingPreRelease(semVar!, gitDirectory)
|
|
||||||
return .semvar(
|
|
||||||
semvarWithPreRelease,
|
|
||||||
usesOptionalType: usesOptionalType ?? false,
|
|
||||||
hasChanges: semvarWithPreRelease != semVar
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
if requireExistingSemVar == true {
|
|
||||||
logger.trace("Caller requires existing semvar and it was not found in file or git-tag.")
|
|
||||||
throw CliClientError.semVarNotFound
|
|
||||||
}
|
|
||||||
|
|
||||||
// Semvar doesn't exist, so create a new one.
|
|
||||||
logger.trace("Generating new semvar.")
|
|
||||||
return try await .semvar(
|
|
||||||
applyingPreRelease(.init(), gitDirectory),
|
|
||||||
usesOptionalType: usesOptionalType ?? false,
|
|
||||||
hasChanges: true
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extension Configuration.VersionStrategy {
|
|
||||||
|
|
||||||
func currentVersion(targetUrl: URL, gitDirectory: String?) async throws -> CurrentVersionContainer {
|
|
||||||
@Dependency(\.gitClient) var gitClient
|
|
||||||
|
|
||||||
guard let branch else {
|
|
||||||
guard let semvar else {
|
|
||||||
throw ConfigurationParsingError.versionStrategyError(
|
|
||||||
message: "Neither branch nor semvar set on configuration."
|
|
||||||
)
|
|
||||||
}
|
|
||||||
return try await .init(
|
|
||||||
targetUrl: targetUrl,
|
|
||||||
version: semvar.currentVersion(file: targetUrl, gitDirectory: gitDirectory)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
return try await .init(
|
|
||||||
targetUrl: targetUrl,
|
|
||||||
version: .string(
|
|
||||||
gitClient.version(includeCommitSha: branch.includeCommitSha, gitDirectory: gitDirectory)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -244,5 +248,5 @@ enum ConfigurationParsingError: Error {
|
|||||||
case targetNotFound
|
case targetNotFound
|
||||||
case pathOrModuleNotSet
|
case pathOrModuleNotSet
|
||||||
case versionStrategyError(message: String)
|
case versionStrategyError(message: String)
|
||||||
case versionNotFound
|
case versionStrategyNotFound
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ public extension Configuration {
|
|||||||
|
|
||||||
public enum Strategy: Codable, Equatable, Sendable {
|
public enum Strategy: Codable, Equatable, Sendable {
|
||||||
case branch(includeCommitSha: Bool = true)
|
case branch(includeCommitSha: Bool = true)
|
||||||
case command(arguments: [String])
|
case command(arguments: [String], allowPrefix: Bool? = nil)
|
||||||
case gitTag
|
case gitTag
|
||||||
|
|
||||||
public var branch: Branch? {
|
public var branch: Branch? {
|
||||||
|
|||||||
Reference in New Issue
Block a user