Browse Source

Reorder functions to follow public-first convention

master
AI Bot 1 week ago committed by Riyyi
parent
commit
31fad42ab3
  1. 107
      pkg/fetch/alpm/alpm.go
  2. 50
      pkg/fetch/fetch.go
  3. 37
      pkg/log/log.go
  4. 39
      pkg/pacman/pacman.go
  5. 129
      pkg/pacman/read/read.go
  6. 135
      pkg/pacman/sync/sync.go

107
pkg/fetch/alpm/alpm.go

@ -19,6 +19,59 @@ type Handle struct {
syncDBs []dyalpm.Database
}
func (h *Handle) LocalPackages() (map[string]dyalpm.Package, error) {
start := time.Now()
log.Debug("LocalPackages: starting...")
localPkgs := make(map[string]dyalpm.Package)
err := h.localDB.PkgCache().ForEach(func(pkg dyalpm.Package) error {
localPkgs[pkg.Name()] = pkg
return nil
})
if err != nil {
return nil, fmt.Errorf("failed to iterate local package cache: %w", err)
}
log.Debug("LocalPackages: done (%.2fs)", time.Since(start).Seconds())
return localPkgs, nil
}
func (h *Handle) Release() error {
if h.handle != nil {
h.handle.Release()
}
return nil
}
func (h *Handle) SyncPackages(pkgNames []string) (map[string]dyalpm.Package, error) {
start := time.Now()
log.Debug("SyncPackages: starting...")
syncPkgs := make(map[string]dyalpm.Package)
pkgSet := make(map[string]bool)
for _, name := range pkgNames {
pkgSet[name] = true
}
for _, db := range h.syncDBs {
err := db.PkgCache().ForEach(func(pkg dyalpm.Package) error {
if pkgSet[pkg.Name()] {
if _, exists := syncPkgs[pkg.Name()]; !exists {
syncPkgs[pkg.Name()] = pkg
}
}
return nil
})
if err != nil {
return nil, fmt.Errorf("failed to iterate sync database %s: %w", db.Name(), err)
}
}
log.Debug("SyncPackages: done (%.2fs)", time.Since(start).Seconds())
return syncPkgs, nil
}
func New() (*Handle, error) {
start := time.Now()
log.Debug("alpm.New: starting...")
@ -56,12 +109,8 @@ func New() (*Handle, error) {
}, nil
}
func (h *Handle) Release() error {
if h.handle != nil {
h.handle.Release()
}
return nil
}
// -----------------------------------------
// private
func registerSyncDBs(handle dyalpm.Handle) ([]dyalpm.Database, error) {
log.Debug("registerSyncDBs: starting...")
@ -89,49 +138,3 @@ func registerSyncDBs(handle dyalpm.Handle) ([]dyalpm.Database, error) {
log.Debug("registerSyncDBs: done (%d dbs)", len(dbs))
return dbs, nil
}
func (h *Handle) LocalPackages() (map[string]dyalpm.Package, error) {
start := time.Now()
log.Debug("LocalPackages: starting...")
localPkgs := make(map[string]dyalpm.Package)
err := h.localDB.PkgCache().ForEach(func(pkg dyalpm.Package) error {
localPkgs[pkg.Name()] = pkg
return nil
})
if err != nil {
return nil, fmt.Errorf("failed to iterate local package cache: %w", err)
}
log.Debug("LocalPackages: done (%.2fs)", time.Since(start).Seconds())
return localPkgs, nil
}
func (h *Handle) SyncPackages(pkgNames []string) (map[string]dyalpm.Package, error) {
start := time.Now()
log.Debug("SyncPackages: starting...")
syncPkgs := make(map[string]dyalpm.Package)
pkgSet := make(map[string]bool)
for _, name := range pkgNames {
pkgSet[name] = true
}
for _, db := range h.syncDBs {
err := db.PkgCache().ForEach(func(pkg dyalpm.Package) error {
if pkgSet[pkg.Name()] {
if _, exists := syncPkgs[pkg.Name()]; !exists {
syncPkgs[pkg.Name()] = pkg
}
}
return nil
})
if err != nil {
return nil, fmt.Errorf("failed to iterate sync database %s: %w", db.Name(), err)
}
}
log.Debug("SyncPackages: done (%.2fs)", time.Since(start).Seconds())
return syncPkgs, nil
}

50
pkg/fetch/fetch.go

@ -22,22 +22,16 @@ type Fetcher struct {
aurClient *aur.Client
}
func New() (*Fetcher, error) {
start := time.Now()
log.Debug("fetch.Fetcher New: starting...")
alpmHandle, err := alpm.New()
func (f *Fetcher) BuildLocalPkgMap() (map[string]interface{}, error) {
localPkgs, err := f.alpmHandle.LocalPackages()
if err != nil {
return nil, err
}
aurClient := aur.New()
log.Debug("fetch.Fetcher New: done (%.2fs)", time.Since(start).Seconds())
return &Fetcher{
alpmHandle: alpmHandle,
aurClient: aurClient,
}, nil
result := make(map[string]interface{})
for k, v := range localPkgs {
result[k] = v
}
return result, nil
}
func (f *Fetcher) Close() error {
@ -48,18 +42,6 @@ func (f *Fetcher) GetAURPackage(name string) (aur.Package, bool) {
return f.aurClient.Get(name)
}
func (f *Fetcher) BuildLocalPkgMap() (map[string]interface{}, error) {
localPkgs, err := f.alpmHandle.LocalPackages()
if err != nil {
return nil, err
}
result := make(map[string]interface{})
for k, v := range localPkgs {
result[k] = v
}
return result, nil
}
func (f *Fetcher) Resolve(packages []string) (map[string]*PackageInfo, error) {
start := time.Now()
log.Debug("fetch.Resolve: starting...")
@ -130,3 +112,21 @@ func (f *Fetcher) Resolve(packages []string) (map[string]*PackageInfo, error) {
log.Debug("fetch.Resolve: done (%.2fs)", time.Since(start).Seconds())
return result, nil
}
func New() (*Fetcher, error) {
start := time.Now()
log.Debug("fetch.Fetcher New: starting...")
alpmHandle, err := alpm.New()
if err != nil {
return nil, err
}
aurClient := aur.New()
log.Debug("fetch.Fetcher New: done (%.2fs)", time.Since(start).Seconds())
return &Fetcher{
alpmHandle: alpmHandle,
aurClient: aurClient,
}, nil
}

37
pkg/log/log.go

@ -10,12 +10,21 @@ import (
"time"
)
// -----------------------------------------
var logFile *os.File
var Verbose bool
// -----------------------------------------
func Close() error {
if logFile == nil {
return nil
}
return logFile.Close()
}
func Command(name string, args ...string) *exec.Cmd {
cmdStr := name + " " + strings.Join(args, " ")
fmt.Fprintf(logFile, "[cmd] %s\n", cmdStr)
return exec.Command(name, args...)
}
func Debug(format string, args ...interface{}) {
if !Verbose {
@ -24,7 +33,9 @@ func Debug(format string, args ...interface{}) {
fmt.Fprintf(os.Stderr, "[debug] "+format+"\n", args...)
}
// -----------------------------------------
func GetLogWriter() io.Writer {
return logFile
}
func OpenLog() error {
logPath := filepath.Join("/var/log", "declpac.log")
@ -37,28 +48,12 @@ func OpenLog() error {
return nil
}
func GetLogWriter() io.Writer {
return logFile
}
func Write(msg []byte) {
logFile.Write(msg)
}
func Command(name string, args ...string) *exec.Cmd {
cmdStr := name + " " + strings.Join(args, " ")
fmt.Fprintf(logFile, "[cmd] %s\n", cmdStr)
return exec.Command(name, args...)
}
func Close() error {
if logFile == nil {
return nil
}
return logFile.Close()
}
// -----------------------------------------
// private
func writeTimestamp() {
ts := time.Now().Format("2006-01-02 15:04:05")

39
pkg/pacman/pacman.go

@ -117,6 +117,9 @@ func Sync(packages []string, noCheck bool, prune bool) (*output.Result, error) {
}, nil
}
// -----------------------------------------
// private
func categorizePackages(f *fetch.Fetcher, packages []string) (pacmanPkgs, aurPkgs []string, err error) {
start := time.Now()
log.Debug("categorizePackages: starting...")
@ -143,24 +146,6 @@ func categorizePackages(f *fetch.Fetcher, packages []string) (pacmanPkgs, aurPkg
return pacmanPkgs, aurPkgs, nil
}
func markAllAsDeps() error {
start := time.Now()
log.Debug("markAllAsDeps: starting...")
packages, err := read.List()
if err != nil || len(packages) == 0 {
return fmt.Errorf("failed to list packages: %w", err)
}
if err := sync.MarkAs(packages, "deps", log.GetLogWriter()); err != nil {
log.Write([]byte(fmt.Sprintf("error: %v\n", err)))
return err
}
log.Debug("markAllAsDeps: done (%.2fs)", time.Since(start).Seconds())
return nil
}
func cleanupOrphans() (int, error) {
start := time.Now()
log.Debug("cleanupOrphans: starting...")
@ -180,3 +165,21 @@ func cleanupOrphans() (int, error) {
log.Debug("cleanupOrphans: done (%.2fs)", time.Since(start).Seconds())
return removed, nil
}
func markAllAsDeps() error {
start := time.Now()
log.Debug("markAllAsDeps: starting...")
packages, err := read.List()
if err != nil || len(packages) == 0 {
return fmt.Errorf("failed to list packages: %w", err)
}
if err := sync.MarkAs(packages, "deps", log.GetLogWriter()); err != nil {
log.Write([]byte(fmt.Sprintf("error: %v\n", err)))
return err
}
log.Debug("markAllAsDeps: done (%.2fs)", time.Since(start).Seconds())
return nil
}

129
pkg/pacman/read/read.go

@ -16,71 +16,6 @@ import (
var LockFile = "/var/lib/pacman/db.lock"
func List() ([]string, error) {
start := time.Now()
log.Debug("List: starting...")
cmd := exec.Command("pacman", "-Qq")
output, err := cmd.Output()
if err != nil {
return nil, err
}
list := strings.Split(strings.TrimSpace(string(output)), "\n")
if list[0] == "" {
list = nil
}
log.Debug("List: done (%.2fs)", time.Since(start).Seconds())
return list, nil
}
func ExplicitList() ([]string, error) {
start := time.Now()
log.Debug("ExplicitList: starting...")
cmd := exec.Command("pacman", "-Qqe")
output, err := cmd.Output()
if err != nil {
return nil, err
}
list := strings.Split(strings.TrimSpace(string(output)), "\n")
if len(list) > 0 && list[0] == "" {
list = nil
}
log.Debug("ExplicitList: done (%.2fs)", time.Since(start).Seconds())
return list, nil
}
func ListOrphans() ([]string, error) {
start := time.Now()
log.Debug("ListOrphans: starting...")
cmd := exec.Command("pacman", "-Qdtq")
var stderr bytes.Buffer
cmd.Stderr = &stderr
output, err := cmd.Output()
if err != nil {
// pacman -Qdtq exits 1 when there are no orphans, this isnt an error
var exitErr *exec.ExitError
if errors.As(err, &exitErr) && exitErr.ExitCode() == 1 && stderr.Len() == 0 {
return nil, nil
}
return nil, err
}
orphans := strings.Split(strings.TrimSpace(string(output)), "\n")
if len(orphans) > 0 && orphans[0] == "" {
orphans = orphans[1:]
}
log.Debug("ListOrphans: done (%.2fs)", time.Since(start).Seconds())
return orphans, nil
}
func DBFreshness() (bool, error) {
info, err := os.Stat(LockFile)
if err != nil {
@ -148,3 +83,67 @@ func DryRun(packages []string) (*output.Result, error) {
ToRemove: toRemove,
}, nil
}
func ExplicitList() ([]string, error) {
start := time.Now()
log.Debug("ExplicitList: starting...")
cmd := exec.Command("pacman", "-Qqe")
output, err := cmd.Output()
if err != nil {
return nil, err
}
list := strings.Split(strings.TrimSpace(string(output)), "\n")
if len(list) > 0 && list[0] == "" {
list = nil
}
log.Debug("ExplicitList: done (%.2fs)", time.Since(start).Seconds())
return list, nil
}
func List() ([]string, error) {
start := time.Now()
log.Debug("List: starting...")
cmd := exec.Command("pacman", "-Qq")
output, err := cmd.Output()
if err != nil {
return nil, err
}
list := strings.Split(strings.TrimSpace(string(output)), "\n")
if list[0] == "" {
list = nil
}
log.Debug("List: done (%.2fs)", time.Since(start).Seconds())
return list, nil
}
func ListOrphans() ([]string, error) {
start := time.Now()
log.Debug("ListOrphans: starting...")
cmd := exec.Command("pacman", "-Qdtq")
var stderr bytes.Buffer
cmd.Stderr = &stderr
output, err := cmd.Output()
if err != nil {
var exitErr *exec.ExitError
if errors.As(err, &exitErr) && exitErr.ExitCode() == 1 && stderr.Len() == 0 {
return nil, nil
}
return nil, err
}
orphans := strings.Split(strings.TrimSpace(string(output)), "\n")
if len(orphans) > 0 && orphans[0] == "" {
orphans = orphans[1:]
}
log.Debug("ListOrphans: done (%.2fs)", time.Since(start).Seconds())
return orphans, nil
}

135
pkg/pacman/sync/sync.go

@ -15,43 +15,59 @@ type Result struct {
Removed int
}
func SyncPackages(packages []string, logWriter io.Writer) error {
func InstallAUR(pkgName string, packageBase string, logWriter io.Writer) error {
start := time.Now()
log.Debug("SyncPackages: starting...")
log.Debug("InstallAUR: starting...")
if logWriter == nil {
logWriter = os.Stderr
}
args := append([]string{"-S", "--needed", "--noconfirm"}, packages...)
cmd := log.Command("pacman", args...)
cmd.Stdout = logWriter
cmd.Stderr = logWriter
err := cmd.Run()
if err != nil {
return fmt.Errorf("pacman sync failed: %w", err)
sudoUser := os.Getenv("SUDO_USER")
if sudoUser == "" {
sudoUser = os.Getenv("USER")
if sudoUser == "" {
sudoUser = "root"
}
}
log.Debug("SyncPackages: done (%.2fs)", time.Since(start).Seconds())
return nil
tmpDir := "/tmp/declpac/" + pkgName
mkdirCmd := log.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)
func RefreshDB(logWriter io.Writer) error {
start := time.Now()
log.Debug("RefreshDB: starting...")
cloneURL := "https://aur.archlinux.org/" + packageBase + ".git"
cloneCmd := log.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)
}
log.Debug("InstallAUR: cloned (%.2fs)", time.Since(start).Seconds())
if logWriter == nil {
logWriter = os.Stderr
makepkgCmd := log.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)
}
log.Debug("InstallAUR: built (%.2fs)", time.Since(start).Seconds())
cmd := log.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)
pkgFile, err := findPKGFile(pkgName, tmpDir)
if err != nil {
return fmt.Errorf("failed to find built package: %w", err)
}
log.Debug("RefreshDB: done (%.2fs)", time.Since(start).Seconds())
installCmd := log.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)
}
log.Debug("InstallAUR: done (%.2fs)", time.Since(start).Seconds())
return nil
}
@ -80,6 +96,25 @@ func MarkAs(packages []string, flag string, logWriter io.Writer) error {
return nil
}
func RefreshDB(logWriter io.Writer) error {
start := time.Now()
log.Debug("RefreshDB: starting...")
if logWriter == nil {
logWriter = os.Stderr
}
cmd := log.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)
}
log.Debug("RefreshDB: done (%.2fs)", time.Since(start).Seconds())
return nil
}
func RemoveOrphans(orphans []string, logWriter io.Writer) (int, error) {
start := time.Now()
log.Debug("RemoveOrphans: starting...")
@ -110,62 +145,30 @@ func RemoveOrphans(orphans []string, logWriter io.Writer) (int, error) {
return count, nil
}
func InstallAUR(pkgName string, packageBase string, logWriter io.Writer) error {
func SyncPackages(packages []string, logWriter io.Writer) error {
start := time.Now()
log.Debug("InstallAUR: starting...")
log.Debug("SyncPackages: starting...")
if logWriter == nil {
logWriter = os.Stderr
}
sudoUser := os.Getenv("SUDO_USER")
if sudoUser == "" {
sudoUser = os.Getenv("USER")
if sudoUser == "" {
sudoUser = "root"
}
}
tmpDir := "/tmp/declpac/" + pkgName
mkdirCmd := log.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 := log.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)
}
log.Debug("InstallAUR: cloned (%.2fs)", time.Since(start).Seconds())
makepkgCmd := log.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)
}
log.Debug("InstallAUR: built (%.2fs)", time.Since(start).Seconds())
pkgFile, err := findPKGFile(pkgName, tmpDir)
args := append([]string{"-S", "--needed", "--noconfirm"}, packages...)
cmd := log.Command("pacman", args...)
cmd.Stdout = logWriter
cmd.Stderr = logWriter
err := cmd.Run()
if err != nil {
return fmt.Errorf("failed to find built package: %w", err)
}
installCmd := log.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)
return fmt.Errorf("pacman sync failed: %w", err)
}
log.Debug("InstallAUR: done (%.2fs)", time.Since(start).Seconds())
log.Debug("SyncPackages: done (%.2fs)", time.Since(start).Seconds())
return nil
}
// -----------------------------------------
// private
func findPKGFile(pkgName string, dir string) (string, error) {
entries, err := os.ReadDir(dir)
if err != nil {

Loading…
Cancel
Save