| name | gentleman-system |
| description | System detection and command execution patterns for Gentleman.Dots. Trigger: When editing files in installer/internal/system/, adding OS support, or modifying command execution.
|
| license | Apache-2.0 |
| metadata | {"author":"gentleman-programming","version":"1.0"} |
When to Use
Use this skill when:
- Adding support for new operating systems
- Modifying OS detection logic
- Working with command execution (sudo, brew, pkg)
- Adding new system checks
- Implementing backup/restore functionality
Critical Patterns
Pattern 1: OSType Enum
All OS types are defined in detect.go:
type OSType int
const (
OSMac OSType = iota
OSLinux
OSArch
OSDebian
OSTermux
OSUnknown
)
Pattern 2: SystemInfo Structure
Detection results in SystemInfo struct:
type SystemInfo struct {
OS OSType
OSName string
IsWSL bool
IsARM bool
IsTermux bool
HomeDir string
HasBrew bool
HasPkg bool
HasXcode bool
UserShell string
Prefix string
}
Pattern 3: OS Detection Priority
Termux is checked FIRST (runs on Linux but is special):
func Detect() *SystemInfo {
info := &SystemInfo{...}
if isTermux() {
info.OS = OSTermux
info.IsTermux = true
info.HasPkg = checkPkg()
return info
}
switch runtime.GOOS {
case "darwin":
info.OS = OSMac
case "linux":
if isArchLinux() {
info.OS = OSArch
} else if isDebian() {
info.OS = OSDebian
}
}
return info
}
Pattern 4: Command Execution Functions
Use the right function for each context:
system.Run("git clone ...", nil)
system.RunWithLogs("git clone ...", nil, func(line string) {
SendLog(stepID, line)
})
system.RunBrewWithLogs("install fish", nil, logFunc)
system.RunSudo("apt-get install -y git", nil)
system.RunSudoWithLogs("pacman -S git", nil, logFunc)
system.RunPkgInstall("fish git", nil, logFunc)
system.RunPkgWithLogs("update", nil, logFunc)
Decision Tree
Adding new OS support?
โโโ Add OSType constant in detect.go
โโโ Add detection function (isNewOS())
โโโ Update Detect() with priority order
โโโ Update SystemInfo if new fields needed
โโโ Add OS case in installer.go steps
Running a command?
โโโ Needs sudo? โ RunSudo() or RunSudoWithLogs()
โโโ Needs brew? โ RunBrewWithLogs()
โโโ On Termux? โ RunPkgInstall() or RunPkgWithLogs()
โโโ Needs logs? โ RunWithLogs()
โโโ Simple exec? โ Run()
Checking if tool exists?
โโโ Use CommandExists("toolname")
โโโ Returns bool
Code Examples
Example 1: Termux Detection
func isTermux() bool {
if os.Getenv("TERMUX_VERSION") != "" {
return true
}
prefix := os.Getenv("PREFIX")
if strings.Contains(prefix, "com.termux") {
return true
}
if _, err := os.Stat("/data/data/com.termux"); err == nil {
return true
}
return false
}
Example 2: Platform-Specific Execution
func installTool(m *Model) error {
var result *system.ExecResult
switch {
case m.SystemInfo.IsTermux:
result = system.RunPkgInstall("tool", nil, logFunc)
case m.SystemInfo.OS == system.OSArch:
result = system.RunSudoWithLogs("pacman -S --noconfirm tool", nil, logFunc)
case m.SystemInfo.OS == system.OSMac:
result = system.RunBrewWithLogs("install tool", nil, logFunc)
case m.SystemInfo.OS == system.OSDebian:
result = system.RunBrewWithLogs("install tool", nil, logFunc)
default:
return fmt.Errorf("unsupported OS: %v", m.SystemInfo.OS)
}
return result.Error
}
Example 3: Homebrew Prefix Detection
func GetBrewPrefix() string {
if runtime.GOOS == "darwin" {
if runtime.GOARCH == "arm64" {
return "/opt/homebrew"
}
return "/usr/local"
}
return "/home/linuxbrew/.linuxbrew"
}
Example 4: File Operations
if err := system.EnsureDir(filepath.Join(homeDir, ".config/tool")); err != nil {
return err
}
if err := system.CopyFile(src, dst); err != nil {
return err
}
if err := system.CopyDir("Gentleman.Dots/Config/*", destDir+"/"); err != nil {
return err
}
ExecResult Structure
type ExecResult struct {
Output string
Stderr string
ExitCode int
Error error
}
result := system.Run("command", nil)
if result.Error != nil {
}
if result.ExitCode != 0 {
}
Commands
cd installer && go test ./internal/system/...
cd installer && go test -run TestDetect
cd installer && go test -run TestExec
Resources
- Detection: See
installer/internal/system/detect.go for OS detection
- Execution: See
installer/internal/system/exec.go for command running
- Backup: See
installer/internal/system/backup.go for backup/restore
- Tests: See
installer/internal/system/*_test.go for patterns