Sync a declarative package list with the pacman package manager
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.
 
 

132 lines
2.8 KiB

package fetch
import (
"fmt"
"os"
"time"
"github.com/Riyyi/declpac/pkg/fetch/alpm"
"github.com/Riyyi/declpac/pkg/fetch/aur"
)
type PackageInfo struct {
Name string
InAUR bool
Exists bool
Installed bool
AURInfo *aur.Package
}
type Fetcher struct {
alpmHandle *alpm.Handle
aurClient *aur.Client
}
func New() (*Fetcher, error) {
start := time.Now()
fmt.Fprintf(os.Stderr, "[debug] fetch.Fetcher New: starting...\n")
alpmHandle, err := alpm.New()
if err != nil {
return nil, err
}
aurClient := aur.New()
fmt.Fprintf(os.Stderr, "[debug] fetch.Fetcher New: done (%.2fs)\n", time.Since(start).Seconds())
return &Fetcher{
alpmHandle: alpmHandle,
aurClient: aurClient,
}, nil
}
func (f *Fetcher) Close() error {
return f.alpmHandle.Release()
}
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()
fmt.Fprintf(os.Stderr, "[debug] fetch.Resolve: starting...\n")
result := make(map[string]*PackageInfo)
for _, pkg := range packages {
result[pkg] = &PackageInfo{Name: pkg, Exists: false}
}
syncPkgs, err := f.alpmHandle.SyncPackages(packages)
if err != nil {
return nil, err
}
fmt.Fprintf(os.Stderr, "[debug] fetch.Resolve: sync db check done (%.2fs)\n", time.Since(start).Seconds())
for pkg := range syncPkgs {
result[pkg].Exists = true
result[pkg].InAUR = false
}
localPkgs, err := f.alpmHandle.LocalPackages()
if err != nil {
return nil, err
}
fmt.Fprintf(os.Stderr, "[debug] fetch.Resolve: local pkgs built (%.2fs)\n", time.Since(start).Seconds())
for pkg := range localPkgs {
if info, ok := result[pkg]; ok {
info.Installed = true
}
}
var notInSync []string
for _, pkg := range packages {
if !result[pkg].Exists {
notInSync = append(notInSync, pkg)
}
}
if len(notInSync) > 0 {
if _, err := f.aurClient.Fetch(notInSync); err != nil {
fmt.Fprintf(os.Stderr, "[debug] fetch.Resolve: aur fetch error: %v\n", err)
}
for _, pkg := range packages {
info := result[pkg]
if info.Exists {
continue
}
if aurInfo, ok := f.aurClient.Get(pkg); ok {
info.InAUR = true
info.AURInfo = &aurInfo
continue
}
return nil, fmt.Errorf("package not found: %s", pkg)
}
}
for _, pkg := range packages {
info := result[pkg]
if !info.Exists && !info.InAUR {
return nil, fmt.Errorf("package not validated: %s", pkg)
}
}
fmt.Fprintf(os.Stderr, "[debug] fetch.Resolve: done (%.2fs)\n", time.Since(start).Seconds())
return result, nil
}