initial commit
This commit is contained in:
211
CONTRIBUTING_DISTRO.md
Normal file
211
CONTRIBUTING_DISTRO.md
Normal file
@@ -0,0 +1,211 @@
|
||||
# Adding New Linux Distributions
|
||||
|
||||
This guide explains how to add support for new Linux distributions to the dankdots installer using the new consolidated architecture.
|
||||
|
||||
## Architecture Overview
|
||||
|
||||
The codebase uses a simple, consolidated approach where each distribution is completely self-contained:
|
||||
|
||||
- **All-in-One** (`internal/distros/{distro}.go`) - Complete distribution implementation
|
||||
- **Auto-Registration** - Distributions register themselves via `init()` functions
|
||||
- **Shared Base** - Common functionality inherited from `BaseDistribution`
|
||||
|
||||
## Adding Support
|
||||
|
||||
### Method 1: Use Existing Implementation (Derivatives)
|
||||
|
||||
For distros that are derivatives (like CachyOS being Arch-based), you can register them to use an existing implementation.
|
||||
|
||||
**Example: Adding CachyOS (Arch-based)**
|
||||
|
||||
```go
|
||||
// internal/distros/arch.go - add to the init function
|
||||
func init() {
|
||||
Register("arch", "#1793D1", func(config DistroConfig, logChan chan<- string) Distribution {
|
||||
return NewArchDistribution(config, logChan)
|
||||
})
|
||||
Register("cachyos", "#318CE7", func(config DistroConfig, logChan chan<- string) Distribution {
|
||||
return NewArchDistribution(config, logChan) // CachyOS uses Arch implementation but different color
|
||||
})
|
||||
}
|
||||
```
|
||||
|
||||
That's it! CachyOS now uses Arch's detection and installation logic.
|
||||
|
||||
**Example: Adding Ubuntu derivatives**
|
||||
|
||||
```go
|
||||
// internal/distros/ubuntu.go (after you create it)
|
||||
func init() {
|
||||
Register("ubuntu", "#E95420", func(config DistroConfig, logChan chan<- string) Distribution {
|
||||
return NewUbuntuDistribution(config, logChan)
|
||||
})
|
||||
Register("kubuntu", "#0079C1", func(config DistroConfig, logChan chan<- string) Distribution {
|
||||
return NewUbuntuDistribution(config, logChan) // Kubuntu uses Ubuntu implementation but different color
|
||||
})
|
||||
Register("xubuntu", "#2F5BEA", func(config DistroConfig, logChan chan<- string) Distribution {
|
||||
return NewUbuntuDistribution(config, logChan) // Xubuntu uses Ubuntu implementation but different color
|
||||
})
|
||||
Register("pop", "#48B9C7", func(config DistroConfig, logChan chan<- string) Distribution {
|
||||
return NewUbuntuDistribution(config, logChan) // Pop!_OS uses Ubuntu implementation but different color
|
||||
})
|
||||
}
|
||||
```
|
||||
|
||||
### Method 2: Create New Implementation
|
||||
|
||||
For entirely new distribution families, create a complete implementation:
|
||||
|
||||
**Example: Adding openSUSE**
|
||||
|
||||
Create `internal/distros/opensuse.go`:
|
||||
|
||||
```go
|
||||
package distros
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os/exec"
|
||||
"strings"
|
||||
|
||||
"github.com/AvengeMedia/danklinux/internal/deps"
|
||||
"github.com/AvengeMedia/danklinux/internal/installer"
|
||||
)
|
||||
|
||||
func init() {
|
||||
Register("opensuse-leap", "#73BA25", func(config DistroConfig, logChan chan<- string) Distribution {
|
||||
return NewOpenSUSEDistribution(config, logChan)
|
||||
})
|
||||
Register("opensuse-tumbleweed", "#73BA25", func(config DistroConfig, logChan chan<- string) Distribution {
|
||||
return NewOpenSUSEDistribution(config, logChan)
|
||||
})
|
||||
}
|
||||
|
||||
type OpenSUSEDistribution struct {
|
||||
*BaseDistribution
|
||||
*ManualPackageInstaller
|
||||
config DistroConfig
|
||||
}
|
||||
|
||||
func NewOpenSUSEDistribution(config DistroConfig, logChan chan<- string) *OpenSUSEDistribution {
|
||||
base := NewBaseDistribution(logChan)
|
||||
return &OpenSUSEDistribution{
|
||||
BaseDistribution: base,
|
||||
ManualPackageInstaller: &ManualPackageInstaller{BaseDistribution: base},
|
||||
config: config,
|
||||
}
|
||||
}
|
||||
|
||||
func (o *OpenSUSEDistribution) GetID() string {
|
||||
return o.config.ID
|
||||
}
|
||||
|
||||
func (o *OpenSUSEDistribution) GetColorHex() string {
|
||||
return o.config.ColorHex
|
||||
}
|
||||
|
||||
func (o *OpenSUSEDistribution) GetPackageManager() PackageManagerType {
|
||||
return PackageManagerZypper
|
||||
}
|
||||
|
||||
func (o *OpenSUSEDistribution) GetPackageMapping(wm deps.WindowManager) map[string]PackageMapping {
|
||||
return map[string]PackageMapping{
|
||||
"git": {Name: "git", Repository: RepoTypeSystem},
|
||||
"ghostty": {Name: "ghostty", Repository: RepoTypeManual}, // Build from source
|
||||
"kitty": {Name: "kitty", Repository: RepoTypeSystem},
|
||||
// ... map all required packages to openSUSE equivalents
|
||||
}
|
||||
}
|
||||
|
||||
func (o *OpenSUSEDistribution) DetectDependencies(ctx context.Context, wm deps.WindowManager) ([]deps.Dependency, error) {
|
||||
return o.DetectDependenciesWithTerminal(ctx, wm, deps.TerminalGhostty)
|
||||
}
|
||||
|
||||
func (o *OpenSUSEDistribution) DetectDependenciesWithTerminal(ctx context.Context, wm deps.WindowManager, terminal deps.Terminal) ([]deps.Dependency, error) {
|
||||
var dependencies []deps.Dependency
|
||||
|
||||
// Use base methods for common functionality
|
||||
dependencies = append(dependencies, o.detectDMS())
|
||||
dependencies = append(dependencies, o.detectSpecificTerminal(terminal))
|
||||
dependencies = append(dependencies, o.detectGit())
|
||||
// ... add openSUSE-specific detection
|
||||
|
||||
return dependencies, nil
|
||||
}
|
||||
|
||||
func (o *OpenSUSEDistribution) InstallPackages(ctx context.Context, dependencies []deps.Dependency, wm deps.WindowManager, sudoPassword string, reinstallFlags map[string]bool, progressChan chan<- installer.InstallProgressMsg) error {
|
||||
// Implement installation logic using zypper
|
||||
// Use o.InstallManualPackages() for source builds
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o *OpenSUSEDistribution) InstallPrerequisites(ctx context.Context, sudoPassword string, progressChan chan<- installer.InstallProgressMsg) error {
|
||||
// Install build tools, enable repositories, etc.
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o *OpenSUSEDistribution) packageInstalled(pkg string) bool {
|
||||
cmd := exec.Command("rpm", "-q", pkg)
|
||||
err := cmd.Run()
|
||||
return err == nil
|
||||
}
|
||||
```
|
||||
|
||||
## Repository Types
|
||||
|
||||
The system supports these repository types:
|
||||
|
||||
- `RepoTypeSystem` - Main system repository (zypper, apt, dnf, pacman)
|
||||
- `RepoTypeAUR` - Arch User Repository
|
||||
- `RepoTypeCOPR` - Fedora COPR
|
||||
- `RepoTypePPA` - Ubuntu PPA
|
||||
- `RepoTypeManual` - Build from source
|
||||
|
||||
## Package Manager Support
|
||||
|
||||
To add a new package manager, add it to `internal/distros/interface.go`:
|
||||
|
||||
```go
|
||||
const (
|
||||
PackageManagerPacman PackageManagerType = "pacman"
|
||||
PackageManagerDNF PackageManagerType = "dnf"
|
||||
PackageManagerAPT PackageManagerType = "apt"
|
||||
PackageManagerZypper PackageManagerType = "zypper"
|
||||
PackageManagerPortage PackageManagerType = "portage" // Add new ones here
|
||||
)
|
||||
```
|
||||
|
||||
## Testing Your Implementation
|
||||
|
||||
1. Build: `go build -o dankdots ./cmd/main.go`
|
||||
2. Test on target distribution
|
||||
3. Verify all packages detect and install correctly
|
||||
4. Test both window managers (Hyprland, Niri)
|
||||
5. Test both terminals (Ghostty, Kitty)
|
||||
|
||||
## Detection Process
|
||||
|
||||
The system automatically detects supported distributions by:
|
||||
|
||||
1. Reading `/etc/os-release` for the `ID` field
|
||||
2. Looking up the ID in the distribution registry
|
||||
3. Creating an instance using the registered constructor function
|
||||
|
||||
No hardcoded lists to maintain - everything is driven by the registry!
|
||||
|
||||
## Benefits of New Architecture
|
||||
|
||||
- ✅ **Single file per distro** - All logic in one place
|
||||
- ✅ **Auto-registration** - No factory methods to update
|
||||
- ✅ **Shared functionality** - Inherit common features
|
||||
- ✅ **No duplication** - Manual builds and fonts are shared
|
||||
- ✅ **Easy derivatives** - One line to support a new derivative
|
||||
|
||||
## Contributing
|
||||
|
||||
1. Fork the repository
|
||||
2. Create your distribution file in `internal/distros/`
|
||||
3. Test thoroughly on your target distribution
|
||||
4. Submit a pull request with example output
|
||||
|
||||
The maintainers will review and provide feedback. Thank you for expanding dankdots support!
|
||||
Reference in New Issue
Block a user