@@ -43,6 +43,7 @@ type File struct {
43
43
Exclude []* Exclude
44
44
Replace []* Replace
45
45
Retract []* Retract
46
+ Tool []* Tool
46
47
47
48
Syntax * FileSyntax
48
49
}
@@ -93,6 +94,12 @@ type Retract struct {
93
94
Syntax * Line
94
95
}
95
96
97
+ // A Tool is a single tool statement.
98
+ type Tool struct {
99
+ Path string
100
+ Syntax * Line
101
+ }
102
+
96
103
// A VersionInterval represents a range of versions with upper and lower bounds.
97
104
// Intervals are closed: both bounds are included. When Low is equal to High,
98
105
// the interval may refer to a single version ('v1.2.3') or an interval
@@ -297,7 +304,7 @@ func parseToFile(file string, data []byte, fix VersionFixer, strict bool) (parse
297
304
})
298
305
}
299
306
continue
300
- case "module" , "godebug" , "require" , "exclude" , "replace" , "retract" :
307
+ case "module" , "godebug" , "require" , "exclude" , "replace" , "retract" , "tool" :
301
308
for _ , l := range x .Line {
302
309
f .add (& errs , x , l , x .Token [0 ], l .Token , fix , strict )
303
310
}
@@ -509,6 +516,21 @@ func (f *File) add(errs *ErrorList, block *LineBlock, line *Line, verb string, a
509
516
Syntax : line ,
510
517
}
511
518
f .Retract = append (f .Retract , retract )
519
+
520
+ case "tool" :
521
+ if len (args ) != 1 {
522
+ errorf ("tool directive expects exactly one argument" )
523
+ return
524
+ }
525
+ s , err := parseString (& args [0 ])
526
+ if err != nil {
527
+ errorf ("invalid quoted string: %v" , err )
528
+ return
529
+ }
530
+ f .Tool = append (f .Tool , & Tool {
531
+ Path : s ,
532
+ Syntax : line ,
533
+ })
512
534
}
513
535
}
514
536
@@ -1567,6 +1589,36 @@ func (f *File) DropRetract(vi VersionInterval) error {
1567
1589
return nil
1568
1590
}
1569
1591
1592
+ // AddTool adds a new tool directive with the given path.
1593
+ // It does nothing if the tool line already exists.
1594
+ func (f * File ) AddTool (path string ) error {
1595
+ for _ , t := range f .Tool {
1596
+ if t .Path == path {
1597
+ return nil
1598
+ }
1599
+ }
1600
+
1601
+ f .Tool = append (f .Tool , & Tool {
1602
+ Path : path ,
1603
+ Syntax : f .Syntax .addLine (nil , "tool" , path ),
1604
+ })
1605
+
1606
+ f .SortBlocks ()
1607
+ return nil
1608
+ }
1609
+
1610
+ // RemoveTool removes a tool directive with the given path.
1611
+ // It does nothing if no such tool directive exists.
1612
+ func (f * File ) DropTool (path string ) error {
1613
+ for _ , t := range f .Tool {
1614
+ if t .Path == path {
1615
+ t .Syntax .markRemoved ()
1616
+ * t = Tool {}
1617
+ }
1618
+ }
1619
+ return nil
1620
+ }
1621
+
1570
1622
func (f * File ) SortBlocks () {
1571
1623
f .removeDups () // otherwise sorting is unsafe
1572
1624
@@ -1593,9 +1645,9 @@ func (f *File) SortBlocks() {
1593
1645
}
1594
1646
}
1595
1647
1596
- // removeDups removes duplicate exclude and replace directives.
1648
+ // removeDups removes duplicate exclude, replace and tool directives.
1597
1649
//
1598
- // Earlier exclude directives take priority.
1650
+ // Earlier exclude and tool directives take priority.
1599
1651
//
1600
1652
// Later replace directives take priority.
1601
1653
//
@@ -1605,10 +1657,10 @@ func (f *File) SortBlocks() {
1605
1657
// retract directives are not de-duplicated since comments are
1606
1658
// meaningful, and versions may be retracted multiple times.
1607
1659
func (f * File ) removeDups () {
1608
- removeDups (f .Syntax , & f .Exclude , & f .Replace )
1660
+ removeDups (f .Syntax , & f .Exclude , & f .Replace , & f . Tool )
1609
1661
}
1610
1662
1611
- func removeDups (syntax * FileSyntax , exclude * []* Exclude , replace * []* Replace ) {
1663
+ func removeDups (syntax * FileSyntax , exclude * []* Exclude , replace * []* Replace , tool * [] * Tool ) {
1612
1664
kill := make (map [* Line ]bool )
1613
1665
1614
1666
// Remove duplicate excludes.
@@ -1649,6 +1701,24 @@ func removeDups(syntax *FileSyntax, exclude *[]*Exclude, replace *[]*Replace) {
1649
1701
}
1650
1702
* replace = repl
1651
1703
1704
+ if tool != nil {
1705
+ haveTool := make (map [string ]bool )
1706
+ for _ , t := range * tool {
1707
+ if haveTool [t .Path ] {
1708
+ kill [t .Syntax ] = true
1709
+ continue
1710
+ }
1711
+ haveTool [t .Path ] = true
1712
+ }
1713
+ var newTool []* Tool
1714
+ for _ , t := range * tool {
1715
+ if ! kill [t .Syntax ] {
1716
+ newTool = append (newTool , t )
1717
+ }
1718
+ }
1719
+ * tool = newTool
1720
+ }
1721
+
1652
1722
// Duplicate require and retract directives are not removed.
1653
1723
1654
1724
// Drop killed statements from the syntax tree.
0 commit comments