@@ -569,11 +569,11 @@ func (p *PkgResolver) GetPackagesWithDependencies(ctx context.Context, packages
569569func (p * PkgResolver ) GetPackageWithDependencies (ctx context.Context , pkgName string , existing map [string ]* RepositoryPackage , dq map [* RepositoryPackage ]string ) (* RepositoryPackage , []* RepositoryPackage , []string , error ) {
570570 parents := make (map [string ]bool )
571571 localExisting := make (map [string ]* RepositoryPackage , len (existing ))
572- existingOrigins := map [string ]bool {}
572+ existingOrigins := map [string ]string {}
573573 for k , v := range existing {
574574 localExisting [k ] = v
575575 if v != nil && v .Origin != "" {
576- existingOrigins [v .Origin ] = true
576+ existingOrigins [v .Origin ] = v . Version
577577 }
578578 }
579579
@@ -712,7 +712,7 @@ func (p *PkgResolver) resolvePackage(pkgName string, dq map[*RepositoryPackage]s
712712// It might change the order of install.
713713// In other words, this _should_ be a DAG (acyclical), but because the packages
714714// are just listing dependencies in text, it might be cyclical. We need to be careful of that.
715- func (p * PkgResolver ) getPackageDependencies (ctx context.Context , pkg * RepositoryPackage , allowPin string , parents map [string ]bool , existing map [string ]* RepositoryPackage , existingOrigins map [string ]bool , dq map [* RepositoryPackage ]string ) (dependencies []* RepositoryPackage , conflicts []string , err error ) {
715+ func (p * PkgResolver ) getPackageDependencies (ctx context.Context , pkg * RepositoryPackage , allowPin string , parents map [string ]bool , existing map [string ]* RepositoryPackage , existingOrigins map [string ]string , dq map [* RepositoryPackage ]string ) (dependencies []* RepositoryPackage , conflicts []string , err error ) {
716716 if err := ctx .Err (); err != nil {
717717 return nil , nil , context .Cause (ctx )
718718 }
@@ -902,7 +902,9 @@ func (p *PkgResolver) getPackageDependencies(ctx context.Context, pkg *Repositor
902902 conflicts = append (conflicts , confs ... )
903903 for _ , dep := range subDeps {
904904 existing [dep .Name ] = dep
905- existingOrigins [dep .Origin ] = true
905+ if dep .Origin != "" {
906+ existingOrigins [dep .Origin ] = dep .Version
907+ }
906908 }
907909 }
908910 return dependencies , conflicts , nil
@@ -944,11 +946,11 @@ func cachedResolvePackageNameVersionPin(pkgName string) ParsedConstraint {
944946// For example, if the original search was for package "a", then pkgs may contain some that
945947// are named "a", but others that provided "a". In that case, we should look not at the
946948// version of the package, but the version of "a" that the package provides.
947- func (p * PkgResolver ) sortPackages (pkgs []* repositoryPackage , compare * RepositoryPackage , name string , existing map [string ]* RepositoryPackage , existingOrigins map [string ]bool , pin string ) {
949+ func (p * PkgResolver ) sortPackages (pkgs []* repositoryPackage , compare * RepositoryPackage , name string , existing map [string ]* RepositoryPackage , existingOrigins map [string ]string , pin string ) {
948950 slices .SortFunc (pkgs , p .comparePackages (compare , name , existing , existingOrigins , pin ))
949951}
950952
951- func (p * PkgResolver ) comparePackages (compare * RepositoryPackage , name string , existing map [string ]* RepositoryPackage , existingOrigins map [string ]bool , pin string ) func (a , b * repositoryPackage ) int { //nolint:gocyclo
953+ func (p * PkgResolver ) comparePackages (compare * RepositoryPackage , name string , existing map [string ]* RepositoryPackage , existingOrigins map [string ]string , pin string ) func (a , b * repositoryPackage ) int { //nolint:gocyclo
952954 return func (a , b * repositoryPackage ) int {
953955 // determine versions
954956 iVersionStr := p .getDepVersionForName (a , name )
@@ -990,9 +992,12 @@ func (p *PkgResolver) comparePackages(compare *RepositoryPackage, name string, e
990992 }
991993 // both matched, so keep looking
992994
993- // see if an origin already is installed
994- iOriginMatched := existingOrigins [a .Origin ]
995- jOriginMatched := existingOrigins [b .Origin ]
995+ // Prefer a candidate whose origin we've already pulled in, but only at
996+ // the version we pulled in. Otherwise this heuristic would keep us on
997+ // an older version of an origin (e.g. when a package moves origins at
998+ // a newer version, or an old binary lingers in the index after rebuild).
999+ iOriginMatched := a .Origin != "" && existingOrigins [a .Origin ] == a .Version
1000+ jOriginMatched := b .Origin != "" && existingOrigins [b .Origin ] == b .Version
9961001 if iOriginMatched && ! jOriginMatched {
9971002 return - 1
9981003 }
@@ -1052,7 +1057,7 @@ func (p *PkgResolver) comparePackages(compare *RepositoryPackage, name string, e
10521057 }
10531058}
10541059
1055- func (p * PkgResolver ) bestPackage (pkgs []* repositoryPackage , compare * RepositoryPackage , name string , existing map [string ]* RepositoryPackage , existingOrigins map [string ]bool , pin string ) * repositoryPackage {
1060+ func (p * PkgResolver ) bestPackage (pkgs []* repositoryPackage , compare * RepositoryPackage , name string , existing map [string ]* RepositoryPackage , existingOrigins map [string ]string , pin string ) * repositoryPackage {
10561061 if len (pkgs ) == 0 {
10571062 return nil
10581063 }
0 commit comments