yay/pkg/srcinfo/service.go
Jo 1bfbd01f94
fix(sync): do not update vcs info of failed packages (#1901)
* extract srcinfo service to pkg

* take into account failed installs for vcs update. Fixes #1892

* fix tests
2023-01-23 21:43:58 +00:00

126 lines
3.2 KiB
Go

package srcinfo
import (
"context"
"errors"
"fmt"
"path/filepath"
gosrc "github.com/Morganamilo/go-srcinfo"
"github.com/leonelquinteros/gotext"
"github.com/Jguer/yay/v11/pkg/db"
"github.com/Jguer/yay/v11/pkg/dep"
"github.com/Jguer/yay/v11/pkg/pgp"
"github.com/Jguer/yay/v11/pkg/settings"
"github.com/Jguer/yay/v11/pkg/settings/exe"
"github.com/Jguer/yay/v11/pkg/text"
"github.com/Jguer/yay/v11/pkg/vcs"
)
// TODO: add tests
type Service struct {
dbExecutor db.Executor
cfg *settings.Configuration
cmdBuilder exe.ICmdBuilder
vcsStore vcs.Store
pkgBuildDirs map[string]string
srcInfos map[string]*gosrc.Srcinfo
}
func NewService(dbExecutor db.Executor, cfg *settings.Configuration,
cmdBuilder exe.ICmdBuilder, vcsStore vcs.Store, pkgBuildDirs map[string]string,
) (*Service, error) {
srcinfos, err := ParseSrcinfoFilesByBase(pkgBuildDirs, true)
if err != nil {
panic(err)
}
return &Service{
dbExecutor: dbExecutor,
cfg: cfg,
cmdBuilder: cmdBuilder,
vcsStore: vcsStore,
pkgBuildDirs: pkgBuildDirs,
srcInfos: srcinfos,
}, nil
}
func (s *Service) IncompatiblePkgs(ctx context.Context) ([]string, error) {
incompatible := []string{}
alpmArch, err := s.dbExecutor.AlpmArchitectures()
if err != nil {
return nil, err
}
nextpkg:
for base, srcinfo := range s.srcInfos {
for _, arch := range srcinfo.Arch {
if db.ArchIsSupported(alpmArch, arch) {
continue nextpkg
}
}
incompatible = append(incompatible, base)
}
return incompatible, nil
}
func (s *Service) CheckPGPKeys(ctx context.Context) error {
_, errCPK := pgp.CheckPgpKeys(ctx, s.pkgBuildDirs, s.srcInfos, s.cmdBuilder, settings.NoConfirm)
return errCPK
}
func (s *Service) UpdateVCSStore(ctx context.Context, targets []map[string]*dep.InstallInfo, ignore map[string]error,
) error {
for _, srcinfo := range s.srcInfos {
if srcinfo.Source == nil {
continue
}
// TODO: high complexity - refactor
for i := range srcinfo.Packages {
for j := range targets {
if _, ok := targets[j][srcinfo.Packages[i].Pkgname]; !ok {
text.Debugln("skipping VCS update for", srcinfo.Packages[i].Pkgname, "not in targets")
continue
}
if _, ok := ignore[srcinfo.Packages[i].Pkgname]; ok {
text.Debugln("skipping VCS update for", srcinfo.Packages[i].Pkgname, "due to install error")
continue
}
text.Debugln("updating VCS entry for", srcinfo.Packages[i].Pkgname, fmt.Sprintf("source: %v", srcinfo.Source))
s.vcsStore.Update(ctx, srcinfo.Packages[i].Pkgname, srcinfo.Source)
}
}
}
return nil
}
func ParseSrcinfoFilesByBase(pkgBuildDirs map[string]string, errIsFatal bool) (map[string]*gosrc.Srcinfo, error) {
srcinfos := make(map[string]*gosrc.Srcinfo)
k := 0
for base, dir := range pkgBuildDirs {
text.OperationInfoln(gotext.Get("(%d/%d) Parsing SRCINFO: %s", k+1, len(pkgBuildDirs), text.Cyan(base)))
pkgbuild, err := gosrc.ParseFile(filepath.Join(dir, ".SRCINFO"))
if err != nil {
if !errIsFatal {
text.Warnln(gotext.Get("failed to parse %s -- skipping: %s", base, err))
continue
}
return nil, errors.New(gotext.Get("failed to parse %s: %s", base, err))
}
srcinfos[base] = pkgbuild
k++
}
return srcinfos, nil
}