added functionality to delete existing partitions before reinstall
Some checks failed
Build / build (push) Failing after 4m53s
Some checks failed
Build / build (push) Failing after 4m53s
This commit is contained in:
@@ -1,221 +0,0 @@
|
||||
package version
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type VersionInfo struct {
|
||||
Current string
|
||||
Latest string
|
||||
IsGit bool
|
||||
IsBranch bool
|
||||
IsTag bool
|
||||
HasUpdate bool
|
||||
}
|
||||
|
||||
func GetCurrentDMSVersion() (string, error) {
|
||||
homeDir, err := os.UserHomeDir()
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to get home directory: %w", err)
|
||||
}
|
||||
|
||||
dmsPath := filepath.Join(homeDir, ".config", "quickshell", "dms")
|
||||
if _, err := os.Stat(dmsPath); os.IsNotExist(err) {
|
||||
return "", fmt.Errorf("DMS not installed")
|
||||
}
|
||||
|
||||
originalDir, err := os.Getwd()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer os.Chdir(originalDir)
|
||||
|
||||
if err := os.Chdir(dmsPath); err != nil {
|
||||
return "", fmt.Errorf("failed to change to DMS directory: %w", err)
|
||||
}
|
||||
|
||||
if _, err := os.Stat(filepath.Join(dmsPath, ".git")); err == nil {
|
||||
tagCmd := exec.Command("git", "describe", "--exact-match", "--tags", "HEAD")
|
||||
if tagOutput, err := tagCmd.Output(); err == nil {
|
||||
return strings.TrimSpace(string(tagOutput)), nil
|
||||
}
|
||||
|
||||
branchCmd := exec.Command("git", "rev-parse", "--abbrev-ref", "HEAD")
|
||||
if branchOutput, err := branchCmd.Output(); err == nil {
|
||||
branch := strings.TrimSpace(string(branchOutput))
|
||||
revCmd := exec.Command("git", "rev-parse", "--short", "HEAD")
|
||||
if revOutput, err := revCmd.Output(); err == nil {
|
||||
rev := strings.TrimSpace(string(revOutput))
|
||||
return fmt.Sprintf("%s@%s", branch, rev), nil
|
||||
}
|
||||
return branch, nil
|
||||
}
|
||||
}
|
||||
|
||||
cmd := exec.Command("dms", "--version")
|
||||
if output, err := cmd.Output(); err == nil {
|
||||
return strings.TrimSpace(string(output)), nil
|
||||
}
|
||||
|
||||
return "unknown", nil
|
||||
}
|
||||
|
||||
func GetLatestDMSVersion() (string, error) {
|
||||
homeDir, err := os.UserHomeDir()
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to get home directory: %w", err)
|
||||
}
|
||||
|
||||
dmsPath := filepath.Join(homeDir, ".config", "quickshell", "dms")
|
||||
|
||||
originalDir, err := os.Getwd()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer os.Chdir(originalDir)
|
||||
|
||||
if _, err := os.Stat(filepath.Join(dmsPath, ".git")); err == nil {
|
||||
if err := os.Chdir(dmsPath); err != nil {
|
||||
return "", fmt.Errorf("failed to change to DMS directory: %w", err)
|
||||
}
|
||||
|
||||
currentRefCmd := exec.Command("git", "symbolic-ref", "-q", "HEAD")
|
||||
currentRefOutput, _ := currentRefCmd.Output()
|
||||
onBranch := len(currentRefOutput) > 0
|
||||
|
||||
if !onBranch {
|
||||
tagCmd := exec.Command("git", "describe", "--exact-match", "--tags", "HEAD")
|
||||
if _, err := tagCmd.Output(); err == nil {
|
||||
// Add timeout to git fetch to prevent hanging
|
||||
fetchCmd := exec.Command("timeout", "5s", "git", "fetch", "origin", "--tags", "--quiet")
|
||||
fetchCmd.Run()
|
||||
|
||||
latestTagCmd := exec.Command("git", "tag", "-l", "v0.1.*", "--sort=-version:refname")
|
||||
latestTagOutput, err := latestTagCmd.Output()
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to get latest tag: %w", err)
|
||||
}
|
||||
|
||||
tags := strings.Split(strings.TrimSpace(string(latestTagOutput)), "\n")
|
||||
if len(tags) == 0 || tags[0] == "" {
|
||||
return "", fmt.Errorf("no v0.1.* tags found")
|
||||
}
|
||||
return tags[0], nil
|
||||
}
|
||||
} else {
|
||||
branchCmd := exec.Command("git", "rev-parse", "--abbrev-ref", "HEAD")
|
||||
branchOutput, err := branchCmd.Output()
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to get current branch: %w", err)
|
||||
}
|
||||
currentBranch := strings.TrimSpace(string(branchOutput))
|
||||
|
||||
// Add timeout to git fetch to prevent hanging
|
||||
fetchCmd := exec.Command("timeout", "5s", "git", "fetch", "origin", currentBranch, "--quiet")
|
||||
fetchCmd.Run()
|
||||
|
||||
remoteRevCmd := exec.Command("git", "rev-parse", "--short", fmt.Sprintf("origin/%s", currentBranch))
|
||||
remoteRevOutput, err := remoteRevCmd.Output()
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to get remote revision: %w", err)
|
||||
}
|
||||
remoteRev := strings.TrimSpace(string(remoteRevOutput))
|
||||
return fmt.Sprintf("%s@%s", currentBranch, remoteRev), nil
|
||||
}
|
||||
}
|
||||
|
||||
// Add timeout to prevent hanging when GitHub is down
|
||||
cmd := exec.Command("curl", "-s", "--max-time", "5", "https://api.github.com/repos/AvengeMedia/danklinux/releases/latest")
|
||||
output, err := cmd.Output()
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to fetch latest release: %w", err)
|
||||
}
|
||||
|
||||
var result struct {
|
||||
TagName string `json:"tag_name"`
|
||||
}
|
||||
if err := json.Unmarshal(output, &result); err != nil {
|
||||
for _, line := range strings.Split(string(output), "\n") {
|
||||
if strings.Contains(line, "\"tag_name\"") {
|
||||
parts := strings.Split(line, "\"")
|
||||
if len(parts) >= 4 {
|
||||
return parts[3], nil
|
||||
}
|
||||
}
|
||||
}
|
||||
return "", fmt.Errorf("failed to parse latest version: %w", err)
|
||||
}
|
||||
|
||||
return result.TagName, nil
|
||||
}
|
||||
|
||||
func GetDMSVersionInfo() (*VersionInfo, error) {
|
||||
current, err := GetCurrentDMSVersion()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
latest, err := GetLatestDMSVersion()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get latest version: %w", err)
|
||||
}
|
||||
|
||||
info := &VersionInfo{
|
||||
Current: current,
|
||||
Latest: latest,
|
||||
IsGit: strings.Contains(current, "@"),
|
||||
IsBranch: strings.Contains(current, "@"),
|
||||
IsTag: !strings.Contains(current, "@") && strings.HasPrefix(current, "v"),
|
||||
}
|
||||
|
||||
if info.IsBranch {
|
||||
parts := strings.Split(current, "@")
|
||||
latestParts := strings.Split(latest, "@")
|
||||
if len(parts) == 2 && len(latestParts) == 2 {
|
||||
info.HasUpdate = parts[1] != latestParts[1]
|
||||
}
|
||||
} else if info.IsTag {
|
||||
info.HasUpdate = current != latest
|
||||
} else {
|
||||
info.HasUpdate = false
|
||||
}
|
||||
|
||||
return info, nil
|
||||
}
|
||||
|
||||
func CompareVersions(v1, v2 string) int {
|
||||
v1 = strings.TrimPrefix(v1, "v")
|
||||
v2 = strings.TrimPrefix(v2, "v")
|
||||
|
||||
parts1 := strings.Split(v1, ".")
|
||||
parts2 := strings.Split(v2, ".")
|
||||
|
||||
maxLen := len(parts1)
|
||||
if len(parts2) > maxLen {
|
||||
maxLen = len(parts2)
|
||||
}
|
||||
|
||||
for i := 0; i < maxLen; i++ {
|
||||
var p1, p2 int
|
||||
if i < len(parts1) {
|
||||
fmt.Sscanf(parts1[i], "%d", &p1)
|
||||
}
|
||||
if i < len(parts2) {
|
||||
fmt.Sscanf(parts2[i], "%d", &p2)
|
||||
}
|
||||
|
||||
if p1 < p2 {
|
||||
return -1
|
||||
}
|
||||
if p1 > p2 {
|
||||
return 1
|
||||
}
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
@@ -1,293 +0,0 @@
|
||||
package version
|
||||
|
||||
import (
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestCompareVersions(t *testing.T) {
|
||||
tests := []struct {
|
||||
v1 string
|
||||
v2 string
|
||||
expected int
|
||||
}{
|
||||
{"v0.1.0", "v0.1.0", 0},
|
||||
{"v0.1.0", "v0.1.1", -1},
|
||||
{"v0.1.1", "v0.1.0", 1},
|
||||
{"v0.1.10", "v0.1.2", 1},
|
||||
{"v0.2.0", "v0.1.9", 1},
|
||||
{"0.1.0", "0.1.0", 0},
|
||||
{"1.0.0", "v1.0.0", 0},
|
||||
{"v1.2.3", "v1.2.4", -1},
|
||||
{"v2.0.0", "v1.9.9", 1},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
result := CompareVersions(tt.v1, tt.v2)
|
||||
if result != tt.expected {
|
||||
t.Errorf("CompareVersions(%q, %q) = %d; want %d", tt.v1, tt.v2, result, tt.expected)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetDMSVersionInfo_Structure(t *testing.T) {
|
||||
homeDir, err := os.UserHomeDir()
|
||||
if err != nil {
|
||||
t.Skip("Cannot get home directory")
|
||||
}
|
||||
|
||||
dmsPath := filepath.Join(homeDir, ".config", "quickshell", "dms")
|
||||
if _, err := os.Stat(dmsPath); os.IsNotExist(err) {
|
||||
t.Skip("DMS not installed, skipping version info test")
|
||||
}
|
||||
|
||||
info, err := GetDMSVersionInfo()
|
||||
if err != nil {
|
||||
t.Fatalf("GetDMSVersionInfo() failed: %v", err)
|
||||
}
|
||||
|
||||
if info == nil {
|
||||
t.Fatal("GetDMSVersionInfo() returned nil")
|
||||
}
|
||||
|
||||
if info.Current == "" {
|
||||
t.Error("Current version is empty")
|
||||
}
|
||||
|
||||
if info.Latest == "" {
|
||||
t.Error("Latest version is empty")
|
||||
}
|
||||
|
||||
t.Logf("Current: %s, Latest: %s, HasUpdate: %v", info.Current, info.Latest, info.HasUpdate)
|
||||
}
|
||||
|
||||
func TestGetCurrentDMSVersion_NotInstalled(t *testing.T) {
|
||||
originalHome := os.Getenv("HOME")
|
||||
defer os.Setenv("HOME", originalHome)
|
||||
|
||||
tempDir := t.TempDir()
|
||||
os.Setenv("HOME", tempDir)
|
||||
|
||||
_, err := GetCurrentDMSVersion()
|
||||
if err == nil {
|
||||
t.Error("Expected error when DMS not installed, got nil")
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetCurrentDMSVersion_GitTag(t *testing.T) {
|
||||
if !commandExists("git") {
|
||||
t.Skip("git not available")
|
||||
}
|
||||
|
||||
tempDir := t.TempDir()
|
||||
dmsPath := filepath.Join(tempDir, ".config", "quickshell", "dms")
|
||||
os.MkdirAll(dmsPath, 0755)
|
||||
|
||||
originalHome := os.Getenv("HOME")
|
||||
defer os.Setenv("HOME", originalHome)
|
||||
os.Setenv("HOME", tempDir)
|
||||
|
||||
exec.Command("git", "init", dmsPath).Run()
|
||||
exec.Command("git", "-C", dmsPath, "config", "user.email", "test@test.com").Run()
|
||||
exec.Command("git", "-C", dmsPath, "config", "user.name", "Test User").Run()
|
||||
|
||||
testFile := filepath.Join(dmsPath, "test.txt")
|
||||
os.WriteFile(testFile, []byte("test"), 0644)
|
||||
exec.Command("git", "-C", dmsPath, "add", ".").Run()
|
||||
exec.Command("git", "-C", dmsPath, "commit", "-m", "initial").Run()
|
||||
exec.Command("git", "-C", dmsPath, "tag", "v0.1.0").Run()
|
||||
|
||||
version, err := GetCurrentDMSVersion()
|
||||
if err != nil {
|
||||
t.Fatalf("GetCurrentDMSVersion() failed: %v", err)
|
||||
}
|
||||
|
||||
if version != "v0.1.0" {
|
||||
t.Errorf("Expected version v0.1.0, got %s", version)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetCurrentDMSVersion_GitBranch(t *testing.T) {
|
||||
if !commandExists("git") {
|
||||
t.Skip("git not available")
|
||||
}
|
||||
|
||||
tempDir := t.TempDir()
|
||||
dmsPath := filepath.Join(tempDir, ".config", "quickshell", "dms")
|
||||
os.MkdirAll(dmsPath, 0755)
|
||||
|
||||
originalHome := os.Getenv("HOME")
|
||||
defer os.Setenv("HOME", originalHome)
|
||||
os.Setenv("HOME", tempDir)
|
||||
|
||||
exec.Command("git", "init", dmsPath).Run()
|
||||
exec.Command("git", "-C", dmsPath, "config", "user.email", "test@test.com").Run()
|
||||
exec.Command("git", "-C", dmsPath, "config", "user.name", "Test User").Run()
|
||||
exec.Command("git", "-C", dmsPath, "checkout", "-b", "master").Run()
|
||||
|
||||
testFile := filepath.Join(dmsPath, "test.txt")
|
||||
os.WriteFile(testFile, []byte("test"), 0644)
|
||||
exec.Command("git", "-C", dmsPath, "add", ".").Run()
|
||||
exec.Command("git", "-C", dmsPath, "commit", "-m", "initial").Run()
|
||||
|
||||
version, err := GetCurrentDMSVersion()
|
||||
if err != nil {
|
||||
t.Fatalf("GetCurrentDMSVersion() failed: %v", err)
|
||||
}
|
||||
|
||||
if version == "" {
|
||||
t.Error("Expected non-empty version")
|
||||
}
|
||||
|
||||
if len(version) < 7 {
|
||||
t.Errorf("Expected version with branch@commit format, got %s", version)
|
||||
}
|
||||
}
|
||||
|
||||
func TestVersionInfo_IsGit(t *testing.T) {
|
||||
tests := []struct {
|
||||
current string
|
||||
isGit bool
|
||||
isBranch bool
|
||||
isTag bool
|
||||
}{
|
||||
{"v0.1.0", false, false, true},
|
||||
{"master@abc1234", true, true, false},
|
||||
{"dev@def5678", true, true, false},
|
||||
{"v0.2.0", false, false, true},
|
||||
{"unknown", false, false, false},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
info := &VersionInfo{
|
||||
IsGit: tt.isGit,
|
||||
IsBranch: tt.isBranch,
|
||||
IsTag: tt.isTag,
|
||||
}
|
||||
|
||||
actualIsGit := len(tt.current) > 0 && tt.current[0] != 'v' && tt.current != "unknown"
|
||||
actualIsBranch := len(tt.current) > 0 && tt.current[0] != 'v'
|
||||
actualIsTag := len(tt.current) > 0 && tt.current[0] == 'v'
|
||||
|
||||
if tt.current == "unknown" {
|
||||
actualIsGit = false
|
||||
actualIsBranch = false
|
||||
actualIsTag = false
|
||||
}
|
||||
|
||||
if info.IsGit != tt.isGit {
|
||||
t.Errorf("For %s: IsGit = %v; want %v", tt.current, info.IsGit, tt.isGit)
|
||||
}
|
||||
if info.IsBranch != tt.isBranch {
|
||||
t.Errorf("For %s: IsBranch = %v; want %v", tt.current, info.IsBranch, tt.isBranch)
|
||||
}
|
||||
if info.IsTag != tt.isTag {
|
||||
t.Errorf("For %s: IsTag = %v; want %v", tt.current, info.IsTag, tt.isTag)
|
||||
}
|
||||
|
||||
_ = actualIsGit
|
||||
_ = actualIsBranch
|
||||
_ = actualIsTag
|
||||
}
|
||||
}
|
||||
|
||||
func TestVersionInfo_HasUpdate_Branch(t *testing.T) {
|
||||
tests := []struct {
|
||||
current string
|
||||
latest string
|
||||
hasUpdate bool
|
||||
}{
|
||||
{"master@abc1234", "master@abc1234", false},
|
||||
{"master@abc1234", "master@def5678", true},
|
||||
{"dev@abc1234", "dev@abc1234", false},
|
||||
{"dev@old1234", "dev@new5678", true},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
info := &VersionInfo{
|
||||
HasUpdate: tt.hasUpdate,
|
||||
}
|
||||
|
||||
if info.HasUpdate != tt.hasUpdate {
|
||||
t.Errorf("For current=%s, latest=%s: HasUpdate = %v; want %v",
|
||||
tt.current, tt.latest, info.HasUpdate, tt.hasUpdate)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestVersionInfo_HasUpdate_Tag(t *testing.T) {
|
||||
tests := []struct {
|
||||
current string
|
||||
latest string
|
||||
hasUpdate bool
|
||||
}{
|
||||
{"v0.1.0", "v0.1.0", false},
|
||||
{"v0.1.0", "v0.1.1", true},
|
||||
{"v0.1.5", "v0.1.5", false},
|
||||
{"v0.1.9", "v0.2.0", true},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
info := &VersionInfo{
|
||||
HasUpdate: tt.hasUpdate,
|
||||
}
|
||||
|
||||
if info.HasUpdate != tt.hasUpdate {
|
||||
t.Errorf("For current=%s, latest=%s: HasUpdate = %v; want %v",
|
||||
tt.current, tt.latest, info.HasUpdate, tt.hasUpdate)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func commandExists(cmd string) bool {
|
||||
_, err := exec.LookPath(cmd)
|
||||
return err == nil
|
||||
}
|
||||
|
||||
func TestGetLatestDMSVersion_FallbackParsing(t *testing.T) {
|
||||
jsonResponse := `{
|
||||
"tag_name": "v0.1.17",
|
||||
"name": "Release v0.1.17"
|
||||
}`
|
||||
|
||||
lines := []string{
|
||||
` "tag_name": "v0.1.17",`,
|
||||
` "name": "Release v0.1.17"`,
|
||||
}
|
||||
|
||||
for _, line := range lines {
|
||||
if len(line) > 0 && line[0:15] == ` "tag_name": "` {
|
||||
parts := []string{"", "", "", "v0.1.17"}
|
||||
version := parts[3]
|
||||
if version != "v0.1.17" {
|
||||
t.Errorf("Failed to parse version from line: %s", line)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_ = jsonResponse
|
||||
}
|
||||
|
||||
func TestCompareVersions_EdgeCases(t *testing.T) {
|
||||
tests := []struct {
|
||||
v1 string
|
||||
v2 string
|
||||
expected int
|
||||
}{
|
||||
{"", "", 0},
|
||||
{"v1", "v1", 0},
|
||||
{"v1.0", "v1", 0},
|
||||
{"v1.0.0", "v1.0", 0},
|
||||
{"v1.0.1", "v1.0", 1},
|
||||
{"v1", "v1.0.1", -1},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
result := CompareVersions(tt.v1, tt.v2)
|
||||
if result != tt.expected {
|
||||
t.Errorf("CompareVersions(%q, %q) = %d; want %d", tt.v1, tt.v2, result, tt.expected)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user