mirror of
https://github.com/lukaszraczylo/semver-generator.git
synced 2026-06-05 22:49:25 +00:00
Fix ignoring strict.force and strict.commit.
This commit is contained in:
@@ -1,16 +0,0 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"github.com/lukaszraczylo/semver-generator/cmd/utils"
|
||||
)
|
||||
|
||||
// These functions are now in the utils package
|
||||
// They are kept here as stubs for backward compatibility
|
||||
|
||||
func updatePackage() bool {
|
||||
return utils.UpdatePackage()
|
||||
}
|
||||
|
||||
func checkLatestRelease() (string, bool) {
|
||||
return utils.CheckLatestRelease()
|
||||
}
|
||||
@@ -1,52 +0,0 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/lukaszraczylo/semver-generator/cmd/utils"
|
||||
)
|
||||
|
||||
func Test_checkLatestRelease(t *testing.T) {
|
||||
utils.InitLogger(true)
|
||||
tests := []struct {
|
||||
name string
|
||||
want string
|
||||
want1 bool
|
||||
}{
|
||||
{
|
||||
name: "Check latest release",
|
||||
want1: true,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
_, got1 := checkLatestRelease()
|
||||
if got1 != tt.want1 {
|
||||
t.Errorf("checkLatestRelease() got1 = %v, want %v", got1, tt.want1)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_updatePackage(t *testing.T) {
|
||||
utils.InitLogger(true)
|
||||
if testing.Short() {
|
||||
t.Skip("Skipping test in short / CI mode")
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
want bool
|
||||
}{
|
||||
{
|
||||
name: "Run autoupdater",
|
||||
want: true,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if got := updatePackage(); got != tt.want {
|
||||
t.Errorf("updatePackage() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
+9
-2
@@ -135,18 +135,25 @@ func ListCommits(repo *GitRepository) ([]CommitDetails, error) {
|
||||
|
||||
Debug("Listing commits", map[string]interface{}{"commits": tmpResults})
|
||||
|
||||
// Filter commits starting from the specified commit if provided
|
||||
// Filter commits starting after the specified commit if provided
|
||||
if repo.StartCommit != "" {
|
||||
found := false
|
||||
for commitId, cmt := range tmpResults {
|
||||
if cmt.Hash == repo.StartCommit {
|
||||
Debug("Found commit match", map[string]interface{}{
|
||||
"commit": cmt.Hash,
|
||||
"index": commitId,
|
||||
})
|
||||
repo.Commits = tmpResults[commitId:]
|
||||
// Start from the commit AFTER the specified one
|
||||
repo.Commits = tmpResults[commitId+1:]
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
// If specified commit not found, use all commits
|
||||
repo.Commits = tmpResults
|
||||
}
|
||||
} else {
|
||||
repo.Commits = tmpResults
|
||||
}
|
||||
|
||||
@@ -34,14 +34,6 @@ type ReleaseAsset struct {
|
||||
BrowserDownloadURL string `json:"browser_download_url"`
|
||||
}
|
||||
|
||||
// UpdateInfo contains information about an available update
|
||||
type UpdateInfo struct {
|
||||
CurrentVersion string
|
||||
LatestVersion string
|
||||
ReleaseURL string
|
||||
DownloadURL string
|
||||
}
|
||||
|
||||
// httpClient is the HTTP client used for requests (allows mocking in tests)
|
||||
var httpClient = &http.Client{
|
||||
Timeout: requestTimeout,
|
||||
@@ -60,30 +52,6 @@ func CheckLatestRelease() (string, bool) {
|
||||
return version, true
|
||||
}
|
||||
|
||||
// CheckForUpdate checks if a newer version is available
|
||||
// Returns UpdateInfo if an update is available, nil otherwise
|
||||
func CheckForUpdate(currentVersion string) *UpdateInfo {
|
||||
release, err := fetchLatestRelease(context.Background())
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
latestVersion := normalizeVersion(release.TagName)
|
||||
current := normalizeVersion(currentVersion)
|
||||
|
||||
if isNewerVersion(latestVersion, current) {
|
||||
downloadURL := findBinaryAsset(release.Assets)
|
||||
return &UpdateInfo{
|
||||
CurrentVersion: current,
|
||||
LatestVersion: latestVersion,
|
||||
ReleaseURL: release.HTMLURL,
|
||||
DownloadURL: downloadURL,
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// UpdatePackage downloads and installs the latest version
|
||||
func UpdatePackage() bool {
|
||||
Info("Checking for updates", nil)
|
||||
@@ -389,49 +357,3 @@ func normalizeVersion(v string) string {
|
||||
v = strings.TrimPrefix(v, "V")
|
||||
return v
|
||||
}
|
||||
|
||||
// isNewerVersion compares two semver-like versions
|
||||
// Returns true if latest is newer than current
|
||||
func isNewerVersion(latest, current string) bool {
|
||||
latestParts := parseVersionParts(latest)
|
||||
currentParts := parseVersionParts(current)
|
||||
|
||||
for i := 0; i < len(latestParts) && i < len(currentParts); i++ {
|
||||
if latestParts[i] > currentParts[i] {
|
||||
return true
|
||||
}
|
||||
if latestParts[i] < currentParts[i] {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return len(latestParts) > len(currentParts)
|
||||
}
|
||||
|
||||
// parseVersionParts splits a version string into numeric parts
|
||||
func parseVersionParts(v string) []int {
|
||||
// Remove any suffix like -beta, -rc1, etc.
|
||||
if idx := strings.IndexAny(v, "-+"); idx != -1 {
|
||||
v = v[:idx]
|
||||
}
|
||||
|
||||
parts := strings.Split(v, ".")
|
||||
result := make([]int, 0, len(parts))
|
||||
|
||||
for _, p := range parts {
|
||||
var num int
|
||||
if _, err := fmt.Sscanf(p, "%d", &num); err != nil {
|
||||
// If parsing fails, use 0 for this part
|
||||
num = 0
|
||||
}
|
||||
result = append(result, num)
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
// FormatUpdateMessage formats a user-friendly update notification
|
||||
func (u *UpdateInfo) FormatUpdateMessage() string {
|
||||
return fmt.Sprintf("New version available: %s (current: %s) - %s",
|
||||
u.LatestVersion, u.CurrentVersion, u.ReleaseURL)
|
||||
}
|
||||
|
||||
@@ -30,57 +30,6 @@ func TestNormalizeVersion(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseVersionParts(t *testing.T) {
|
||||
tests := []struct {
|
||||
input string
|
||||
expected []int
|
||||
}{
|
||||
{"1.0.0", []int{1, 0, 0}},
|
||||
{"2.1.3", []int{2, 1, 3}},
|
||||
{"1.0", []int{1, 0}},
|
||||
{"10.20.30", []int{10, 20, 30}},
|
||||
{"1.0.0-beta", []int{1, 0, 0}},
|
||||
{"1.0.0-rc1", []int{1, 0, 0}},
|
||||
{"1.0.0+build123", []int{1, 0, 0}},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.input, func(t *testing.T) {
|
||||
result := parseVersionParts(tt.input)
|
||||
assert.Equal(t, tt.expected, result)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsNewerVersion(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
latest string
|
||||
current string
|
||||
expected bool
|
||||
}{
|
||||
{"major version bump", "2.0.0", "1.0.0", true},
|
||||
{"minor version bump", "1.1.0", "1.0.0", true},
|
||||
{"patch version bump", "1.0.1", "1.0.0", true},
|
||||
{"same version", "1.0.0", "1.0.0", false},
|
||||
{"current is newer major", "1.0.0", "2.0.0", false},
|
||||
{"current is newer minor", "1.0.0", "1.1.0", false},
|
||||
{"current is newer patch", "1.0.0", "1.0.1", false},
|
||||
{"multi-digit versions", "1.10.0", "1.9.0", true},
|
||||
{"longer version is newer", "1.0.1", "1.0", true},
|
||||
{"shorter version is older", "1.0", "1.0.1", false},
|
||||
{"complex comparison", "2.1.3", "2.1.2", true},
|
||||
{"real world example", "0.2.0", "0.1.0", true},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
result := isNewerVersion(tt.latest, tt.current)
|
||||
assert.Equal(t, tt.expected, result)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestFindBinaryAsset(t *testing.T) {
|
||||
assets := []ReleaseAsset{
|
||||
{Name: "semver-gen-1.0.0-linux-amd64.tar.gz", BrowserDownloadURL: "https://example.com/linux-amd64.tar.gz"},
|
||||
@@ -102,19 +51,6 @@ func TestFindBinaryAssetEmpty(t *testing.T) {
|
||||
assert.Empty(t, url, "Should return empty string when no assets")
|
||||
}
|
||||
|
||||
func TestUpdateInfo_FormatUpdateMessage(t *testing.T) {
|
||||
info := &UpdateInfo{
|
||||
CurrentVersion: "1.0.0",
|
||||
LatestVersion: "2.0.0",
|
||||
ReleaseURL: "https://github.com/lukaszraczylo/semver-generator/releases/tag/v2.0.0",
|
||||
}
|
||||
|
||||
msg := info.FormatUpdateMessage()
|
||||
assert.Contains(t, msg, "2.0.0")
|
||||
assert.Contains(t, msg, "1.0.0")
|
||||
assert.Contains(t, msg, "https://github.com/lukaszraczylo/semver-generator/releases/tag/v2.0.0")
|
||||
}
|
||||
|
||||
func TestCheckLatestRelease(t *testing.T) {
|
||||
// Initialize logger
|
||||
InitLogger(false)
|
||||
@@ -141,22 +77,6 @@ func TestCheckLatestRelease(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestCheckForUpdate(t *testing.T) {
|
||||
InitLogger(false)
|
||||
|
||||
// Test with a very old version - should show update available if network works
|
||||
info := CheckForUpdate("0.0.1")
|
||||
// This will either return update info or nil depending on network
|
||||
if info != nil {
|
||||
assert.NotEmpty(t, info.LatestVersion)
|
||||
assert.Equal(t, "0.0.1", info.CurrentVersion)
|
||||
}
|
||||
|
||||
// Test with a very new version - should not show update
|
||||
info = CheckForUpdate("999.999.999")
|
||||
assert.Nil(t, info, "Should not show update for future version")
|
||||
}
|
||||
|
||||
func TestFetchLatestReleaseError(t *testing.T) {
|
||||
InitLogger(false)
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestInitLogger(t *testing.T) {
|
||||
// Test with debug mode enabled
|
||||
logger := InitLogger(true)
|
||||
|
||||
+26
-11
@@ -16,22 +16,37 @@ func CalculateSemver(
|
||||
tagPrefixes []string,
|
||||
) SemVer {
|
||||
semver := initialSemver
|
||||
startIndex := 0
|
||||
|
||||
for _, commit := range commits {
|
||||
// Check for existing tags if enabled
|
||||
if respectExisting {
|
||||
for _, tagHash := range tags {
|
||||
if commit.Hash == tagHash.Hash {
|
||||
Debug("Found existing tag", map[string]interface{}{
|
||||
"tag": tagHash.Name,
|
||||
"commit": strings.TrimSuffix(commit.Message, "\n"),
|
||||
// If respecting existing tags, find the latest tagged commit and start from there
|
||||
if respectExisting && len(tags) > 0 {
|
||||
latestTagIndex := -1
|
||||
var latestTagName string
|
||||
|
||||
// Find the latest tagged commit (highest index since commits are oldest-first)
|
||||
for i, commit := range commits {
|
||||
for _, tag := range tags {
|
||||
if commit.Hash == tag.Hash {
|
||||
if i > latestTagIndex {
|
||||
latestTagIndex = i
|
||||
latestTagName = tag.Name
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If we found a tagged commit, use its version and start processing after it
|
||||
if latestTagIndex >= 0 {
|
||||
Debug("Found latest existing tag", map[string]interface{}{
|
||||
"tag": latestTagName,
|
||||
"commit": strings.TrimSuffix(commits[latestTagIndex].Message, "\n"),
|
||||
})
|
||||
semver = ParseExistingSemver(tagHash.Name, semver, tagPrefixes)
|
||||
continue
|
||||
}
|
||||
semver = ParseExistingSemver(latestTagName, semver, tagPrefixes)
|
||||
startIndex = latestTagIndex + 1
|
||||
}
|
||||
}
|
||||
|
||||
for _, commit := range commits[startIndex:] {
|
||||
// In non-strict mode, increment patch by default
|
||||
if !strictMode {
|
||||
semver.Patch++
|
||||
|
||||
Reference in New Issue
Block a user