diff options
| author | AlexanderCurl <alexc@alexc.hu> | 2026-04-18 17:46:06 +0100 |
|---|---|---|
| committer | AlexanderCurl <alexc@alexc.hu> | 2026-04-18 17:46:06 +0100 |
| commit | 70ca3fef77ee8bdc6e3ac28589a6fa08c024cc69 (patch) | |
| tree | ab1123d4067c1b086dd6faa7ee4ea643236b565a /raveos-hyprland-theme/theme-data/DankMaterialShell/core/internal/version/version.go | |
| parent | 5d94c0a7d44a2255b81815a52a7056a94a39842d (diff) | |
| download | RaveOS-PKGBUILD-70ca3fef77ee8bdc6e3ac28589a6fa08c024cc69.tar.gz RaveOS-PKGBUILD-70ca3fef77ee8bdc6e3ac28589a6fa08c024cc69.zip | |
Replaced file structures for themes in the correct format
Diffstat (limited to 'raveos-hyprland-theme/theme-data/DankMaterialShell/core/internal/version/version.go')
| -rw-r--r-- | raveos-hyprland-theme/theme-data/DankMaterialShell/core/internal/version/version.go | 268 |
1 files changed, 268 insertions, 0 deletions
diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/core/internal/version/version.go b/raveos-hyprland-theme/theme-data/DankMaterialShell/core/internal/version/version.go new file mode 100644 index 0000000..db8636e --- /dev/null +++ b/raveos-hyprland-theme/theme-data/DankMaterialShell/core/internal/version/version.go @@ -0,0 +1,268 @@ +package version + +import ( + "encoding/json" + "fmt" + "os" + "os/exec" + "path/filepath" + "strings" + + "github.com/AvengeMedia/DankMaterialShell/core/internal/log" +) + +type VersionInfo struct { + Current string + Latest string + IsGit bool + IsBranch bool + IsTag bool + HasUpdate bool +} + +// VersionFetcher is an interface for fetching version information +type VersionFetcher interface { + GetCurrentVersion(dmsPath string) (string, error) + GetLatestVersion(dmsPath string) (string, error) +} + +// DefaultVersionFetcher is the default implementation that uses git/curl +type DefaultVersionFetcher struct{} + +func (d *DefaultVersionFetcher) GetCurrentVersion(dmsPath string) (string, error) { + if _, err := os.Stat(filepath.Join(dmsPath, ".git")); err == nil { + originalDir, err := os.Getwd() + if err != nil { + return "", err + } + defer func() { + if err := os.Chdir(originalDir); err != nil { + log.Warnf("failed to change back to original directory: %v", err) + } + }() + + if err := os.Chdir(dmsPath); err != nil { + return "", fmt.Errorf("failed to change to DMS directory: %w", err) + } + + 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 (d *DefaultVersionFetcher) GetLatestVersion(dmsPath string) (string, error) { + if _, err := os.Stat(filepath.Join(dmsPath, ".git")); err == nil { + originalDir, err := os.Getwd() + if err != nil { + return "", err + } + defer func() { + if err := os.Chdir(originalDir); err != nil { + log.Warnf("failed to change back to original directory: %v", err) + } + }() + + 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") + if err := fetchCmd.Run(); err != nil { + log.Debugf("git fetch tags failed (continuing with local tags): %v", err) + } + + latestTagCmd := exec.Command("git", "tag", "-l", "v*", "--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 version 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") + if err := fetchCmd.Run(); err != nil { + log.Debugf("git fetch branch failed (continuing with local ref): %v", err) + } + + 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/DankMaterialShell/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 +} + +// defaultFetcher is used by the public functions +var defaultFetcher VersionFetcher = &DefaultVersionFetcher{} + +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") + } + + return defaultFetcher.GetCurrentVersion(dmsPath) +} + +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") + return defaultFetcher.GetLatestVersion(dmsPath) +} + +func GetDMSVersionInfo() (*VersionInfo, error) { + return GetDMSVersionInfoWithFetcher(defaultFetcher) +} + +func GetDMSVersionInfoWithFetcher(fetcher VersionFetcher) (*VersionInfo, error) { + homeDir, err := os.UserHomeDir() + if err != nil { + return nil, 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 nil, fmt.Errorf("DMS not installed") + } + + current, err := fetcher.GetCurrentVersion(dmsPath) + if err != nil { + return nil, err + } + + latest, err := fetcher.GetLatestVersion(dmsPath) + 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) //nolint:errcheck + } + if i < len(parts2) { + fmt.Sscanf(parts2[i], "%d", &p2) //nolint:errcheck + } + + if p1 < p2 { + return -1 + } + if p1 > p2 { + return 1 + } + } + + return 0 +} |