1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
|
package distros
import (
"context"
"github.com/AvengeMedia/DankMaterialShell/core/internal/deps"
)
// DistroFamily represents a family of related distributions
type DistroFamily string
const (
FamilyArch DistroFamily = "arch"
FamilyFedora DistroFamily = "fedora"
FamilySUSE DistroFamily = "suse"
FamilyUbuntu DistroFamily = "ubuntu"
FamilyDebian DistroFamily = "debian"
FamilyNix DistroFamily = "nix"
FamilyGentoo DistroFamily = "gentoo"
)
// PackageManagerType defines the package manager a distro uses
type PackageManagerType string
const (
PackageManagerPacman PackageManagerType = "pacman"
PackageManagerDNF PackageManagerType = "dnf"
PackageManagerAPT PackageManagerType = "apt"
PackageManagerZypper PackageManagerType = "zypper"
PackageManagerNix PackageManagerType = "nix"
PackageManagerPortage PackageManagerType = "portage"
)
// RepositoryType defines the type of repository for a package
type RepositoryType string
const (
RepoTypeSystem RepositoryType = "system" // Standard system repo (pacman, dnf, apt)
RepoTypeAUR RepositoryType = "aur" // Arch User Repository
RepoTypeCOPR RepositoryType = "copr" // Fedora COPR
RepoTypePPA RepositoryType = "ppa" // Ubuntu PPA
RepoTypeOBS RepositoryType = "obs" // OpenBuild Service (Debian/OpenSUSE)
RepoTypeFlake RepositoryType = "flake" // Nix flake
RepoTypeGURU RepositoryType = "guru" // Gentoo GURU
RepoTypeManual RepositoryType = "manual" // Manual build from source
)
// InstallPhase represents the current phase of installation
type InstallPhase int
const (
PhasePrerequisites InstallPhase = iota
PhaseAURHelper
PhaseSystemPackages
PhaseAURPackages
PhaseCursorTheme
PhaseConfiguration
PhaseGreeterSetup
PhaseComplete
)
// InstallProgressMsg represents progress during package installation
type InstallProgressMsg struct {
Phase InstallPhase
Progress float64
Step string
IsComplete bool
NeedsSudo bool
CommandInfo string
LogOutput string
Error error
}
// PackageMapping defines how to install a package on a specific distro
type PackageMapping struct {
Name string // Package name to install
Repository RepositoryType // Repository type
RepoURL string // Repository URL if needed (e.g., COPR repo, PPA)
BuildFunc string // Name of manual build function if RepoTypeManual
UseFlags string // USE flags for Gentoo packages
AcceptKeywords string // Accept keywords for Gentoo packages (e.g., "~amd64")
}
// Distribution defines a Linux distribution with all its specific configurations
type Distribution interface {
// Metadata
GetID() string
GetColorHex() string
GetFamily() DistroFamily
GetPackageManager() PackageManagerType
// Dependency Detection
DetectDependencies(ctx context.Context, wm deps.WindowManager) ([]deps.Dependency, error)
DetectDependenciesWithTerminal(ctx context.Context, wm deps.WindowManager, terminal deps.Terminal) ([]deps.Dependency, error)
// Package Installation
InstallPackages(ctx context.Context, dependencies []deps.Dependency, wm deps.WindowManager, sudoPassword string, reinstallFlags map[string]bool, disabledFlags map[string]bool, skipGlobalUseFlags bool, progressChan chan<- InstallProgressMsg) error
// Package Mapping
GetPackageMapping(wm deps.WindowManager) map[string]PackageMapping
// Prerequisites
InstallPrerequisites(ctx context.Context, sudoPassword string, progressChan chan<- InstallProgressMsg) error
}
// DistroConfig holds configuration for a distribution
type DistroConfig struct {
ID string
ColorHex string
Family DistroFamily
Constructor func(config DistroConfig, logChan chan<- string) Distribution
}
// Registry holds all supported distributions
var Registry = make(map[string]DistroConfig)
// Register adds a distribution to the registry
func Register(id, colorHex string, family DistroFamily, constructor func(config DistroConfig, logChan chan<- string) Distribution) {
Registry[id] = DistroConfig{
ID: id,
ColorHex: colorHex,
Family: family,
Constructor: constructor,
}
}
// GetSupportedDistros returns a list of all supported distribution IDs
func GetSupportedDistros() []string {
ids := make([]string, 0, len(Registry))
for id := range Registry {
ids = append(ids, id)
}
return ids
}
// IsDistroSupported checks if a distribution ID is supported
func IsDistroSupported(id string) bool {
_, exists := Registry[id]
return exists
}
// NewDistribution creates a distribution instance by ID
func NewDistribution(id string, logChan chan<- string) (Distribution, error) {
config, exists := Registry[id]
if !exists {
return nil, &UnsupportedDistributionError{ID: id}
}
return config.Constructor(config, logChan), nil
}
// UnsupportedDistributionError is returned when a distribution is not supported
type UnsupportedDistributionError struct {
ID string
}
func (e *UnsupportedDistributionError) Error() string {
return "unsupported distribution: " + e.ID
}
|