You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
162 lines
4.5 KiB
162 lines
4.5 KiB
package pacman |
|
|
|
import ( |
|
"fmt" |
|
"os" |
|
"time" |
|
|
|
"github.com/Riyyi/declpac/pkg/fetch" |
|
"github.com/Riyyi/declpac/pkg/log" |
|
"github.com/Riyyi/declpac/pkg/output" |
|
"github.com/Riyyi/declpac/pkg/pacman/read" |
|
"github.com/Riyyi/declpac/pkg/pacman/sync" |
|
) |
|
|
|
func Sync(packages []string) (*output.Result, error) { |
|
start := time.Now() |
|
fmt.Fprintf(os.Stderr, "[debug] Sync: starting...\n") |
|
|
|
list, err := read.List() |
|
if err != nil { |
|
return nil, err |
|
} |
|
before := len(list) |
|
|
|
fresh, err := read.DBFreshness() |
|
if err != nil { |
|
return nil, err |
|
} |
|
if !fresh { |
|
if err := sync.RefreshDB(log.GetLogWriter()); err != nil { |
|
return nil, err |
|
} |
|
} |
|
fmt.Fprintf(os.Stderr, "[debug] Sync: database fresh (%.2fs)\n", time.Since(start).Seconds()) |
|
|
|
f, err := fetch.New() |
|
if err != nil { |
|
return nil, err |
|
} |
|
defer f.Close() |
|
fmt.Fprintf(os.Stderr, "[debug] Sync: initialized fetcher (%.2fs)\n", time.Since(start).Seconds()) |
|
|
|
fmt.Fprintf(os.Stderr, "[debug] Sync: categorizing packages...\n") |
|
pacmanPkgs, aurPkgs, err := categorizePackages(f, packages) |
|
if err != nil { |
|
return nil, err |
|
} |
|
fmt.Fprintf(os.Stderr, "[debug] Sync: packages categorized (%.2fs)\n", time.Since(start).Seconds()) |
|
|
|
if len(pacmanPkgs) > 0 { |
|
fmt.Fprintf(os.Stderr, "[debug] Sync: syncing %d pacman packages...\n", len(pacmanPkgs)) |
|
if err := sync.SyncPackages(pacmanPkgs, log.GetLogWriter()); err != nil { |
|
return nil, err |
|
} |
|
fmt.Fprintf(os.Stderr, "[debug] Sync: pacman packages synced (%.2fs)\n", time.Since(start).Seconds()) |
|
} |
|
|
|
for _, pkg := range aurPkgs { |
|
fmt.Fprintf(os.Stderr, "[debug] Sync: installing AUR package %s...\n", pkg) |
|
aurInfo, ok := f.GetAURPackage(pkg) |
|
if !ok { |
|
return nil, fmt.Errorf("AUR package not found in cache: %s", pkg) |
|
} |
|
if err := sync.InstallAUR(pkg, aurInfo.PackageBase, log.GetLogWriter()); err != nil { |
|
return nil, err |
|
} |
|
fmt.Fprintf(os.Stderr, "[debug] Sync: AUR package %s installed (%.2fs)\n", pkg, time.Since(start).Seconds()) |
|
} |
|
|
|
fmt.Fprintf(os.Stderr, "[debug] Sync: marking all as deps...\n") |
|
markAllAsDeps() |
|
fmt.Fprintf(os.Stderr, "[debug] Sync: all marked as deps (%.2fs)\n", time.Since(start).Seconds()) |
|
|
|
fmt.Fprintf(os.Stderr, "[debug] Sync: marking state packages as explicit...\n") |
|
if err := sync.MarkAs(packages, "explicit", log.GetLogWriter()); err != nil { |
|
fmt.Fprintf(os.Stderr, "warning: could not mark state packages as explicit: %v\n", err) |
|
} |
|
fmt.Fprintf(os.Stderr, "[debug] Sync: state packages marked as explicit (%.2fs)\n", time.Since(start).Seconds()) |
|
|
|
removed, err := cleanupOrphans() |
|
if err != nil { |
|
return nil, err |
|
} |
|
|
|
list, _ = read.List() |
|
if err != nil { |
|
return nil, err |
|
} |
|
after := len(list) |
|
|
|
installedCount := max(after-before, 0) |
|
|
|
fmt.Fprintf(os.Stderr, "[debug] Sync: done (%.2fs)\n", time.Since(start).Seconds()) |
|
return &output.Result{ |
|
Installed: installedCount, |
|
Removed: removed, |
|
}, nil |
|
} |
|
|
|
func categorizePackages(f *fetch.Fetcher, packages []string) (pacmanPkgs, aurPkgs []string, err error) { |
|
start := time.Now() |
|
fmt.Fprintf(os.Stderr, "[debug] categorizePackages: starting...\n") |
|
|
|
resolved, err := f.Resolve(packages) |
|
if err != nil { |
|
return nil, nil, err |
|
} |
|
|
|
for _, pkg := range packages { |
|
info := resolved[pkg] |
|
if info == nil || (!info.Exists && !info.InAUR) { |
|
fmt.Fprintf(os.Stderr, "error: package not found: %s\n", pkg) |
|
continue |
|
} |
|
if info.InAUR { |
|
aurPkgs = append(aurPkgs, pkg) |
|
} else { |
|
pacmanPkgs = append(pacmanPkgs, pkg) |
|
} |
|
} |
|
|
|
fmt.Fprintf(os.Stderr, "[debug] categorizePackages: done (%.2fs)\n", time.Since(start).Seconds()) |
|
return pacmanPkgs, aurPkgs, nil |
|
} |
|
|
|
func markAllAsDeps() error { |
|
start := time.Now() |
|
fmt.Fprintf(os.Stderr, "[debug] markAllAsDeps: starting...\n") |
|
|
|
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 |
|
} |
|
|
|
fmt.Fprintf(os.Stderr, "[debug] markAllAsDeps: done (%.2fs)\n", time.Since(start).Seconds()) |
|
return nil |
|
} |
|
|
|
func cleanupOrphans() (int, error) { |
|
start := time.Now() |
|
fmt.Fprintf(os.Stderr, "[debug] cleanupOrphans: starting...\n") |
|
|
|
orphans, err := read.ListOrphans() |
|
if err != nil { |
|
log.Write([]byte(fmt.Sprintf("error: %v\n", err))) |
|
return 0, err |
|
} |
|
|
|
removed, err := sync.RemoveOrphans(orphans, log.GetLogWriter()) |
|
if err != nil { |
|
log.Write([]byte(fmt.Sprintf("error: %v\n", err))) |
|
return 0, err |
|
} |
|
|
|
fmt.Fprintf(os.Stderr, "[debug] cleanupOrphans: done (%.2fs)\n", time.Since(start).Seconds()) |
|
return removed, nil |
|
}
|
|
|