From 64ef819702094e3c49ca2b537b9a513f66de0292 Mon Sep 17 00:00:00 2001 From: naveensrinivasan <172697+naveensrinivasan@users.noreply.github.com> Date: Sun, 29 Mar 2026 22:08:22 -0500 Subject: [PATCH] Enhance ParseSemver function to support two-component versions and update tests - Modified the ParseSemver function to accept "major.minor" format, treating it as "major.minor.0" for compatibility with JetBrains year-based versions. - Updated unit tests to reflect changes, adding cases for two-component versions and ensuring correct parsing of both standard and year-based formats. --- internal/storage/storage.go | 20 +++++++++++--------- internal/storage/storage_test.go | 24 ++++++++++++++++++++---- 2 files changed, 31 insertions(+), 13 deletions(-) diff --git a/internal/storage/storage.go b/internal/storage/storage.go index 327a081..85ebd3e 100644 --- a/internal/storage/storage.go +++ b/internal/storage/storage.go @@ -346,18 +346,20 @@ func (d *DB) GetStats() (map[string]interface{}, error) { return stats, nil } -// ParseSemver parses a semantic version string and returns major, minor, patch components. -// It expects versions in the format "major.minor.patch" (e.g., "1.2.3"). -// Returns an error if the version string doesn't match the expected format. +// ParseSemver parses a version string and returns major, minor, patch components. +// It accepts "major.minor.patch" (e.g., "1.2.3") and "major.minor" (e.g., "2026.1"), +// treating the latter as patch 0. This handles JetBrains year-based versions like "2026.1". func ParseSemver(version string) (major, minor, patch int, err error) { - n, err := fmt.Sscanf(version, "%d.%d.%d", &major, &minor, &patch) - if err != nil { - return 0, 0, 0, fmt.Errorf("failed to parse version %q: %w", version, err) + n, scanErr := fmt.Sscanf(version, "%d.%d.%d", &major, &minor, &patch) + if n == 3 && scanErr == nil { + return major, minor, patch, nil } - if n != 3 { - return 0, 0, 0, fmt.Errorf("%w: %q", ErrInvalidVersionFmt, version) + // Fall back to two-component parse (e.g. "2026.1" → major=2026, minor=1, patch=0). + n2, scanErr2 := fmt.Sscanf(version, "%d.%d", &major, &minor) + if n2 == 2 && scanErr2 == nil { + return major, minor, 0, nil } - return major, minor, patch, nil + return 0, 0, 0, fmt.Errorf("failed to parse version %q: %w", version, scanErr) } // ExtractFilename extracts the filename from a file path using filepath.Base. diff --git a/internal/storage/storage_test.go b/internal/storage/storage_test.go index bd6108e..c20004e 100644 --- a/internal/storage/storage_test.go +++ b/internal/storage/storage_test.go @@ -1054,12 +1054,28 @@ func TestParseSemver(t *testing.T) { wantError: false, }, { - name: "invalid version - missing patch", + name: "two-component version - major.minor treated as patch 0", version: "1.2", - wantMajor: 0, - wantMinor: 0, + wantMajor: 1, + wantMinor: 2, wantPatch: 0, - wantError: true, + wantError: false, + }, + { + name: "intellij year-based version 2026.1", + version: "2026.1", + wantMajor: 2026, + wantMinor: 1, + wantPatch: 0, + wantError: false, + }, + { + name: "intellij year-based version 2025.3", + version: "2025.3", + wantMajor: 2025, + wantMinor: 3, + wantPatch: 0, + wantError: false, }, { name: "invalid version - extra part",