@@ -45,7 +45,9 @@ import (
45
45
"cmd/go/internal/search"
46
46
"cmd/go/internal/work"
47
47
48
+ "golang.org/x/mod/modfile"
48
49
"golang.org/x/mod/module"
50
+ "golang.org/x/mod/semver"
49
51
)
50
52
51
53
var CmdGet = & base.Command {
@@ -462,10 +464,19 @@ func runGet(ctx context.Context, cmd *base.Command, args []string) {
462
464
// what's changing and gives more examples.
463
465
}
464
466
467
+ if ! modload .HasModRoot () {
468
+ return
469
+ }
470
+
465
471
// Everything succeeded. Update go.mod.
472
+ oldReqs := reqsFromGoMod (modload .ModFile ())
473
+
466
474
modload .AllowWriteGoMod ()
467
475
modload .WriteGoMod ()
468
476
modload .DisallowWriteGoMod ()
477
+
478
+ newReqs := reqsFromGoMod (modload .ModFile ())
479
+ r .reportChanges (oldReqs , newReqs )
469
480
}
470
481
471
482
// parseArgs parses command-line arguments and reports errors.
@@ -1563,63 +1574,69 @@ func (r *resolver) checkPackagesAndRetractions(ctx context.Context, pkgPatterns
1563
1574
}
1564
1575
}
1565
1576
1566
- // reportChanges logs resolved version changes to os.Stderr.
1567
- func (r * resolver ) reportChanges (queries []* query ) {
1568
- for _ , q := range queries {
1569
- if q .version == "none" {
1570
- continue
1571
- }
1572
-
1573
- if q .pattern == "all" {
1574
- // To reduce noise for "all", describe module version changes rather than
1575
- // package versions.
1576
- seen := make (map [module.Version ]bool )
1577
- for _ , m := range q .resolved {
1578
- if seen [m ] {
1579
- continue
1580
- }
1581
- seen [m ] = true
1582
-
1583
- before := r .initialSelected (m .Path )
1584
- if before == m .Version {
1585
- continue // m was resolved, but not changed
1586
- }
1577
+ // reportChanges logs version changes to os.Stderr.
1578
+ //
1579
+ // reportChanges only logs changes to modules named on the command line and to
1580
+ // explicitly required modules in go.mod. Most changes to indirect requirements
1581
+ // are not relevant to the user and are not logged.
1582
+ //
1583
+ // reportChanges should be called after WriteGoMod.
1584
+ func (r * resolver ) reportChanges (oldReqs , newReqs []module.Version ) {
1585
+ type change struct {
1586
+ path , old , new string
1587
+ }
1588
+ changes := make (map [string ]change )
1587
1589
1588
- was := ""
1589
- if before != "" {
1590
- was = fmt .Sprintf (" (was %s)" , before )
1591
- }
1592
- fmt .Fprintf (os .Stderr , "go: %v added %s %s%s\n " , q , m .Path , m .Version , was )
1593
- }
1594
- continue
1590
+ // Collect changes in modules matched by command line arguments.
1591
+ for path , reason := range r .resolvedVersion {
1592
+ old := r .initialVersion [path ]
1593
+ new := reason .version
1594
+ if old != new && (old != "" || new != "none" ) {
1595
+ changes [path ] = change {path , old , new }
1595
1596
}
1597
+ }
1596
1598
1597
- for _ , m := range q .resolved {
1598
- before := r .initialSelected (m .Path )
1599
- if before == m .Version {
1600
- continue // m was resolved, but not changed
1601
- }
1599
+ // Collect changes to explicit requirements in go.mod.
1600
+ for _ , req := range oldReqs {
1601
+ path := req .Path
1602
+ old := req .Version
1603
+ new := r .buildListVersion [path ]
1604
+ if old != new {
1605
+ changes [path ] = change {path , old , new }
1606
+ }
1607
+ }
1608
+ for _ , req := range newReqs {
1609
+ path := req .Path
1610
+ old := r .initialVersion [path ]
1611
+ new := req .Version
1612
+ if old != new {
1613
+ changes [path ] = change {path , old , new }
1614
+ }
1615
+ }
1602
1616
1603
- was := ""
1604
- if before != "" {
1605
- was = fmt . Sprintf ( " (was %s)" , before )
1606
- }
1607
- switch {
1608
- case q . isWildcard ():
1609
- if q . matchesPath ( m . Path ) {
1610
- fmt . Fprintf ( os . Stderr , "go: matched %v as %s %s%s \n " , q , m . Path , m . Version , was )
1611
- } else {
1612
- fmt .Fprintf (os .Stderr , "go: matched %v in % s %s%s \n " , q , m . Path , m . Version , was )
1613
- }
1614
- case q . matchesPackages :
1615
- fmt . Fprintf ( os . Stderr , "go: found %v in %s %s%s \n " , q , m . Path , m . Version , was )
1616
- default :
1617
- fmt . Fprintf ( os . Stderr , "go: found %v in %s %s%s \n " , q , m . Path , m . Version , was )
1618
- }
1617
+ sortedChanges := make ([] change , 0 , len ( changes ))
1618
+ for _ , c := range changes {
1619
+ sortedChanges = append ( sortedChanges , c )
1620
+ }
1621
+ sort . Slice ( sortedChanges , func ( i , j int ) bool {
1622
+ return sortedChanges [ i ]. path < sortedChanges [ j ]. path
1623
+ })
1624
+ for _ , c := range sortedChanges {
1625
+ if c . old == "" {
1626
+ fmt .Fprintf (os .Stderr , "go get: added % s %s\n " , c . path , c . new )
1627
+ } else if c . new == "none" || c . new == "" {
1628
+ fmt . Fprintf ( os . Stderr , "go get: removed %s %s \n " , c . path , c . old )
1629
+ } else if semver . Compare ( c . new , c . old ) > 0 {
1630
+ fmt . Fprintf ( os . Stderr , "go get: upgraded %s %s => %s \n " , c . path , c . old , c . new )
1631
+ } else {
1632
+ fmt . Fprintf ( os . Stderr , "go get: downgraded %s %s => %s \n " , c . path , c . old , c . new )
1619
1633
}
1620
1634
}
1621
1635
1622
- // TODO(#33284): Also print relevant upgrades.
1636
+ // TODO(golang.org/issue/33284): attribute changes to command line arguments.
1637
+ // For modules matched by command line arguments, this probably isn't
1638
+ // necessary, but it would be useful for unmatched direct dependencies of
1639
+ // the main module.
1623
1640
}
1624
1641
1625
1642
// resolve records that module m must be at its indicated version (which may be
@@ -1700,6 +1717,14 @@ func (r *resolver) updateBuildList(ctx context.Context, additions []module.Versi
1700
1717
return true
1701
1718
}
1702
1719
1720
+ func reqsFromGoMod (f * modfile.File ) []module.Version {
1721
+ reqs := make ([]module.Version , len (f .Require ))
1722
+ for i , r := range f .Require {
1723
+ reqs [i ] = r .Mod
1724
+ }
1725
+ return reqs
1726
+ }
1727
+
1703
1728
// isNoSuchModuleVersion reports whether err indicates that the requested module
1704
1729
// does not exist at the requested version, either because the module does not
1705
1730
// exist at all or because it does not include that specific version.
0 commit comments