Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 19 additions & 8 deletions Sources/NnexKit/Version/AutoVersionHandler.swift
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,10 @@ public extension AutoVersionHandler {
return false
}

guard let updatedContent = updateVersionInContent(fileContent, newVersion: newVersion) else {
// Force normalized "1.2.3" format (no "v" prefix)
let forced = normalizeVersion(newVersion)

guard let updatedContent = updateVersionInContent(fileContent, newVersion: forced) else {
return false
}

Expand Down Expand Up @@ -101,8 +104,8 @@ private extension AutoVersionHandler {
/// - Parameter content: The file content to search.
/// - Returns: The version string if found.
func extractVersionFromContent(_ content: String) -> String? {
// Look for version: "v0.8.6" pattern in CommandConfiguration
let pattern = #"version:\s*"([^"]+)""#
// Look for version: "0.8.6" or version: "v0.8.6"
let pattern = #"version\s*:\s*"([^"]+)""#

guard let regex = try? NSRegularExpression(pattern: pattern, options: []) else {
return nil
Expand All @@ -117,7 +120,8 @@ private extension AutoVersionHandler {
return nil
}

return String(content[versionRange])
let raw = String(content[versionRange])
return normalizeVersion(raw)
}

/// Updates version in file content.
Expand All @@ -126,28 +130,35 @@ private extension AutoVersionHandler {
/// - newVersion: The new version to set.
/// - Returns: Updated content if successful, nil otherwise.
func updateVersionInContent(_ content: String, newVersion: String) -> String? {
let pattern = #"(version:\s*)"([^"]+)""#
let pattern = #"version\s*:\s*"([^"]+)""#

guard let regex = try? NSRegularExpression(pattern: pattern, options: []) else {
return nil
}

// Force always-writing the strict format:
// version: "1.2.3"
let forcedLine = #"version: "\#(newVersion)""#

let range = NSRange(location: 0, length: content.utf16.count)
let replacement = "$1\"\(newVersion)\""

return regex.stringByReplacingMatches(
in: content,
options: [],
range: range,
withTemplate: replacement
withTemplate: forcedLine
)
}

/// Normalizes version strings for comparison (removes 'v' prefix if present).
/// - Parameter version: The version string to normalize.
/// - Returns: Normalized version string.
func normalizeVersion(_ version: String) -> String {
return version.hasPrefix("v") ? String(version.dropFirst()) : version
let trimmed = version.trimmingCharacters(in: .whitespaces)
if trimmed.lowercased().hasPrefix("v") {
return String(trimmed.dropFirst()).trimmingCharacters(in: .whitespaces)
}
return trimmed
}

func strippedCode(_ s: String) -> String {
Expand Down
2 changes: 1 addition & 1 deletion Tests/NnexKitTests/AutoVersionHandlerTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ extension AutoVersionHandlerTests {
let sut = makeSUT()
let detectedVersion = try sut.detectArgumentParserVersion(projectPath: projectFolder.path)

#expect(detectedVersion == "v2.1.0")
#expect(detectedVersion == "2.1.0")
}

@Test("Ignores non-main ParsableCommand files")
Expand Down