Refactor fetch and pacman packages into subpackages
Split fetch into alpm and aur subpackages for better organization. Rename state to log. Split pacman into read and sync subpackages. Remove validation in favor of read.DBFreshness.
This commit is contained in:
@@ -0,0 +1,180 @@
|
||||
package sync
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"os/exec"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Result struct {
|
||||
Installed int
|
||||
Removed int
|
||||
}
|
||||
|
||||
func SyncPackages(packages []string, logWriter io.Writer) error {
|
||||
start := time.Now()
|
||||
fmt.Fprintf(os.Stderr, "[debug] SyncPackages: starting...\n")
|
||||
|
||||
if logWriter == nil {
|
||||
logWriter = os.Stderr
|
||||
}
|
||||
|
||||
args := append([]string{"-S", "--needed"}, packages...)
|
||||
cmd := exec.Command("pacman", args...)
|
||||
cmd.Stdout = logWriter
|
||||
cmd.Stderr = logWriter
|
||||
err := cmd.Run()
|
||||
if err != nil {
|
||||
return fmt.Errorf("pacman sync failed: %w", err)
|
||||
}
|
||||
|
||||
fmt.Fprintf(os.Stderr, "[debug] SyncPackages: done (%.2fs)\n", time.Since(start).Seconds())
|
||||
return nil
|
||||
}
|
||||
|
||||
func RefreshDB(logWriter io.Writer) error {
|
||||
start := time.Now()
|
||||
fmt.Fprintf(os.Stderr, "[debug] RefreshDB: starting...\n")
|
||||
|
||||
if logWriter == nil {
|
||||
logWriter = os.Stderr
|
||||
}
|
||||
|
||||
cmd := exec.Command("pacman", "-Syy")
|
||||
cmd.Stdout = logWriter
|
||||
cmd.Stderr = logWriter
|
||||
if err := cmd.Run(); err != nil {
|
||||
return fmt.Errorf("failed to refresh pacman database: %w", err)
|
||||
}
|
||||
|
||||
fmt.Fprintf(os.Stderr, "[debug] RefreshDB: done (%.2fs)\n", time.Since(start).Seconds())
|
||||
return nil
|
||||
}
|
||||
|
||||
func MarkAs(packages []string, flag string, logWriter io.Writer) error {
|
||||
if len(packages) == 0 {
|
||||
return nil
|
||||
}
|
||||
start := time.Now()
|
||||
flagName := map[string]string{"deps": "asdeps", "explicit": "asexplicit"}[flag]
|
||||
fmt.Fprintf(os.Stderr, "[debug] MarkAs(%s): starting...\n", flag)
|
||||
|
||||
if logWriter == nil {
|
||||
logWriter = os.Stderr
|
||||
}
|
||||
|
||||
args := append([]string{"-D", "--" + flagName}, packages...)
|
||||
cmd := exec.Command("pacman", args...)
|
||||
cmd.Stdout = logWriter
|
||||
cmd.Stderr = logWriter
|
||||
err := cmd.Run()
|
||||
if err != nil {
|
||||
return fmt.Errorf("mark as %s failed: %w", flag, err)
|
||||
}
|
||||
|
||||
fmt.Fprintf(os.Stderr, "[debug] MarkAs(%s): done (%.2fs)\n", flag, time.Since(start).Seconds())
|
||||
return nil
|
||||
}
|
||||
|
||||
func RemoveOrphans(orphans []string, logWriter io.Writer) (int, error) {
|
||||
start := time.Now()
|
||||
fmt.Fprintf(os.Stderr, "[debug] RemoveOrphans: starting...\n")
|
||||
|
||||
if logWriter == nil {
|
||||
logWriter = os.Stderr
|
||||
}
|
||||
|
||||
if len(orphans) == 0 {
|
||||
fmt.Fprintf(os.Stderr, "[debug] RemoveOrphans: done (no orphans) (%.2fs)\n", time.Since(start).Seconds())
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
args := make([]string, 0, 2+len(orphans))
|
||||
args = append(args, "pacman", "-Rns")
|
||||
args = append(args, orphans...)
|
||||
removeCmd := exec.Command(args[0], args[1:]...)
|
||||
removeCmd.Stdout = logWriter
|
||||
removeCmd.Stderr = logWriter
|
||||
err := removeCmd.Run()
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("remove orphans failed: %w", err)
|
||||
}
|
||||
|
||||
count := len(orphans)
|
||||
|
||||
fmt.Fprintf(os.Stderr, "[debug] RemoveOrphans: done (%d) (%.2fs)\n", count, time.Since(start).Seconds())
|
||||
return count, nil
|
||||
}
|
||||
|
||||
func InstallAUR(pkgName string, packageBase string, logWriter io.Writer) error {
|
||||
start := time.Now()
|
||||
fmt.Fprintf(os.Stderr, "[debug] InstallAUR: starting...\n")
|
||||
|
||||
if logWriter == nil {
|
||||
logWriter = os.Stderr
|
||||
}
|
||||
|
||||
sudoUser := os.Getenv("SUDO_USER")
|
||||
if sudoUser == "" {
|
||||
sudoUser = os.Getenv("USER")
|
||||
if sudoUser == "" {
|
||||
sudoUser = "root"
|
||||
}
|
||||
}
|
||||
|
||||
tmpDir := "/tmp/declpac-aur-" + pkgName
|
||||
mkdirCmd := exec.Command("su", "-", sudoUser, "-c", "rm -rf "+tmpDir+" && mkdir -p "+tmpDir)
|
||||
if err := mkdirCmd.Run(); err != nil {
|
||||
return fmt.Errorf("failed to create temp directory: %w", err)
|
||||
}
|
||||
defer os.RemoveAll(tmpDir)
|
||||
|
||||
cloneURL := "https://aur.archlinux.org/" + packageBase + ".git"
|
||||
cloneCmd := exec.Command("su", "-", sudoUser, "-c", "git clone "+cloneURL+" "+tmpDir)
|
||||
cloneCmd.Stdout = logWriter
|
||||
cloneCmd.Stderr = logWriter
|
||||
if err := cloneCmd.Run(); err != nil {
|
||||
return fmt.Errorf("failed to clone AUR repo: %w", err)
|
||||
}
|
||||
fmt.Fprintf(os.Stderr, "[debug] InstallAUR: cloned (%.2fs)\n", time.Since(start).Seconds())
|
||||
|
||||
makepkgCmd := exec.Command("su", "-", sudoUser, "-c", "cd "+tmpDir+" && makepkg -s --noconfirm")
|
||||
makepkgCmd.Stdout = logWriter
|
||||
makepkgCmd.Stderr = logWriter
|
||||
if err := makepkgCmd.Run(); err != nil {
|
||||
return fmt.Errorf("makepkg failed to build AUR package: %w", err)
|
||||
}
|
||||
fmt.Fprintf(os.Stderr, "[debug] InstallAUR: built (%.2fs)\n", time.Since(start).Seconds())
|
||||
|
||||
pkgFile, err := findPKGFile(tmpDir)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to find built package: %w", err)
|
||||
}
|
||||
|
||||
installCmd := exec.Command("pacman", "-U", "--noconfirm", pkgFile)
|
||||
installCmd.Stdout = logWriter
|
||||
installCmd.Stderr = logWriter
|
||||
if err := installCmd.Run(); err != nil {
|
||||
return fmt.Errorf("failed to install package: %w", err)
|
||||
}
|
||||
fmt.Fprintf(os.Stderr, "[debug] InstallAUR: done (%.2fs)\n", time.Since(start).Seconds())
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func findPKGFile(dir string) (string, error) {
|
||||
entries, err := os.ReadDir(dir)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
for _, entry := range entries {
|
||||
name := entry.Name()
|
||||
if strings.HasSuffix(name, ".pkg.tar.zst") || strings.HasSuffix(name, ".pkg.tar.gz") {
|
||||
return strings.Join([]string{dir, name}, "/"), nil
|
||||
}
|
||||
}
|
||||
return "", fmt.Errorf("no package file found in %s", dir)
|
||||
}
|
||||
Reference in New Issue
Block a user