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
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 |
|
}
|
|
|