@@ -504,20 +504,39 @@ type QueryResult struct {
504
504
Packages []string
505
505
}
506
506
507
+ // QueryPackages is like QueryPattern, but requires that the pattern match at
508
+ // least one package and omits the non-package result (if any).
509
+ func QueryPackages (ctx context.Context , pattern , query string , current func (string ) string , allowed AllowedFunc ) ([]QueryResult , error ) {
510
+ pkgMods , modOnly , err := QueryPattern (ctx , pattern , query , current , allowed )
511
+
512
+ if len (pkgMods ) == 0 && err == nil {
513
+ return nil , & PackageNotInModuleError {
514
+ Mod : modOnly .Mod ,
515
+ Replacement : Replacement (modOnly .Mod ),
516
+ Query : query ,
517
+ Pattern : pattern ,
518
+ }
519
+ }
520
+
521
+ return pkgMods , err
522
+ }
523
+
507
524
// QueryPattern looks up the module(s) containing at least one package matching
508
525
// the given pattern at the given version. The results are sorted by module path
509
- // length in descending order.
526
+ // length in descending order. If any proxy provides a non-empty set of candidate
527
+ // modules, no further proxies are tried.
510
528
//
511
- // QueryPattern queries modules with package paths up to the first "..."
512
- // in the pattern. For the pattern "example.com/a/b.../c", QueryPattern would
513
- // consider prefixes of "example.com/a". If multiple modules have versions
514
- // that match the query and packages that match the pattern, QueryPattern
515
- // picks the one with the longest module path.
529
+ // For wildcard patterns, QueryPattern looks in modules with package paths up to
530
+ // the first "..." in the pattern. For the pattern "example.com/a/b.../c",
531
+ // QueryPattern would consider prefixes of "example.com/a".
516
532
//
517
533
// If any matching package is in the main module, QueryPattern considers only
518
534
// the main module and only the version "latest", without checking for other
519
535
// possible modules.
520
- func QueryPattern (ctx context.Context , pattern , query string , current func (string ) string , allowed AllowedFunc ) ([]QueryResult , error ) {
536
+ //
537
+ // QueryPattern always returns at least one QueryResult (which may be only
538
+ // modOnly) or a non-nil error.
539
+ func QueryPattern (ctx context.Context , pattern , query string , current func (string ) string , allowed AllowedFunc ) (pkgMods []QueryResult , modOnly * QueryResult , err error ) {
521
540
ctx , span := trace .StartSpan (ctx , "modload.QueryPattern " + pattern + " " + query )
522
541
defer span .Done ()
523
542
@@ -531,6 +550,7 @@ func QueryPattern(ctx context.Context, pattern, query string, current func(strin
531
550
}
532
551
533
552
var match func (mod module.Version , root string , isLocal bool ) * search.Match
553
+ matchPattern := search .MatchPattern (pattern )
534
554
535
555
if i := strings .Index (pattern , "..." ); i >= 0 {
536
556
base = pathpkg .Dir (pattern [:i + 3 ])
@@ -558,20 +578,29 @@ func QueryPattern(ctx context.Context, pattern, query string, current func(strin
558
578
if HasModRoot () {
559
579
m := match (Target , modRoot , true )
560
580
if len (m .Pkgs ) > 0 {
561
- if query != "latest" {
562
- return nil , fmt .Errorf ("can't query specific version for package %s in the main module (%s)" , pattern , Target .Path )
581
+ if query != "latest" && query != "upgrade" && query != "patch" {
582
+ return nil , nil , fmt .Errorf ("can't query version %q for package %s in the main module (%s)" , query , pattern , Target .Path )
563
583
}
564
584
if err := allowed (ctx , Target ); err != nil {
565
- return nil , fmt .Errorf ("internal error: package %s is in the main module (%s), but version is not allowed: %w" , pattern , Target .Path , err )
585
+ return nil , nil , fmt .Errorf ("internal error: package %s is in the main module (%s), but version is not allowed: %w" , pattern , Target .Path , err )
566
586
}
567
587
return []QueryResult {{
568
588
Mod : Target ,
569
589
Rev : & modfetch.RevInfo {Version : Target .Version },
570
590
Packages : m .Pkgs ,
571
- }}, nil
591
+ }}, nil , nil
572
592
}
573
593
if err := firstError (m ); err != nil {
574
- return nil , err
594
+ return nil , nil , err
595
+ }
596
+
597
+ if query != "latest" && query != "upgrade" && query != "patch" && matchPattern (Target .Path ) {
598
+ if err := allowed (ctx , Target ); err == nil {
599
+ modOnly = & QueryResult {
600
+ Mod : Target ,
601
+ Rev : & modfetch.RevInfo {Version : Target .Version },
602
+ }
603
+ }
575
604
}
576
605
}
577
606
@@ -580,14 +609,17 @@ func QueryPattern(ctx context.Context, pattern, query string, current func(strin
580
609
candidateModules = modulePrefixesExcludingTarget (base )
581
610
)
582
611
if len (candidateModules ) == 0 {
583
- return nil , & PackageNotInModuleError {
584
- Mod : Target ,
585
- Query : query ,
586
- Pattern : pattern ,
612
+ if modOnly == nil {
613
+ return nil , nil , & PackageNotInModuleError {
614
+ Mod : Target ,
615
+ Query : query ,
616
+ Pattern : pattern ,
617
+ }
587
618
}
619
+ return nil , modOnly , nil
588
620
}
589
621
590
- err : = modfetch .TryProxies (func (proxy string ) error {
622
+ err = modfetch .TryProxies (func (proxy string ) error {
591
623
queryModule := func (ctx context.Context , path string ) (r QueryResult , err error ) {
592
624
ctx , span := trace .StartSpan (ctx , "modload.QueryPattern.queryModule [" + proxy + "] " + path )
593
625
defer span .Done ()
@@ -606,7 +638,7 @@ func QueryPattern(ctx context.Context, pattern, query string, current func(strin
606
638
}
607
639
m := match (r .Mod , root , isLocal )
608
640
r .Packages = m .Pkgs
609
- if len (r .Packages ) == 0 {
641
+ if len (r .Packages ) == 0 && ! matchPattern ( path ) {
610
642
if err := firstError (m ); err != nil {
611
643
return r , err
612
644
}
@@ -620,12 +652,19 @@ func QueryPattern(ctx context.Context, pattern, query string, current func(strin
620
652
return r , nil
621
653
}
622
654
623
- var err error
624
- results , err = queryPrefixModules (ctx , candidateModules , queryModule )
655
+ allResults , err := queryPrefixModules (ctx , candidateModules , queryModule )
656
+ results = allResults [:0 ]
657
+ for _ , r := range allResults {
658
+ if len (r .Packages ) == 0 {
659
+ modOnly = & r
660
+ } else {
661
+ results = append (results , r )
662
+ }
663
+ }
625
664
return err
626
665
})
627
666
628
- return results , err
667
+ return results [: len ( results ): len ( results )], modOnly , err
629
668
}
630
669
631
670
// modulePrefixesExcludingTarget returns all prefixes of path that may plausibly
@@ -651,11 +690,6 @@ func modulePrefixesExcludingTarget(path string) []string {
651
690
return prefixes
652
691
}
653
692
654
- type prefixResult struct {
655
- QueryResult
656
- err error
657
- }
658
-
659
693
func queryPrefixModules (ctx context.Context , candidateModules []string , queryModule func (ctx context.Context , path string ) (QueryResult , error )) (found []QueryResult , err error ) {
660
694
ctx , span := trace .StartSpan (ctx , "modload.queryPrefixModules" )
661
695
defer span .Done ()
0 commit comments