11package commands
22
33import (
4+ "encoding/json"
45 "fmt"
56 "slices"
67 "sort"
@@ -17,9 +18,27 @@ import (
1718 "github.com/golangci/golangci-lint/pkg/logutils"
1819)
1920
21+ type linterHelp struct {
22+ Name string `json:"name"`
23+ Desc string `json:"description"`
24+ Fast bool `json:"fast"`
25+ AutoFix bool `json:"autoFix"`
26+ Presets []string `json:"presets"`
27+ EnabledByDefault bool `json:"enabledByDefault"`
28+ Deprecated bool `json:"deprecated"`
29+ Since string `json:"since"`
30+ OriginalURL string `json:"originalURL,omitempty"`
31+ }
32+
33+ type helpOptions struct {
34+ JSON bool
35+ }
36+
2037type helpCommand struct {
2138 cmd * cobra.Command
2239
40+ opts helpOptions
41+
2342 dbManager * lintersdb.Manager
2443
2544 log logutils.Log
@@ -37,16 +56,21 @@ func newHelpCommand(logger logutils.Log) *helpCommand {
3756 },
3857 }
3958
40- helpCmd .AddCommand (
41- & cobra.Command {
42- Use : "linters" ,
43- Short : "Help about linters" ,
44- Args : cobra .NoArgs ,
45- ValidArgsFunction : cobra .NoFileCompletions ,
46- Run : c .execute ,
47- PreRunE : c .preRunE ,
48- },
49- )
59+ lintersCmd := & cobra.Command {
60+ Use : "linters" ,
61+ Short : "Help about linters" ,
62+ Args : cobra .NoArgs ,
63+ ValidArgsFunction : cobra .NoFileCompletions ,
64+ RunE : c .execute ,
65+ PreRunE : c .preRunE ,
66+ }
67+
68+ helpCmd .AddCommand (lintersCmd )
69+
70+ fs := lintersCmd .Flags ()
71+ fs .SortFlags = false // sort them as they are defined here
72+
73+ fs .BoolVar (& c .opts .JSON , "json" , false , color .GreenString ("Display as JSON" ))
5074
5175 c .cmd = helpCmd
5276
@@ -66,7 +90,41 @@ func (c *helpCommand) preRunE(_ *cobra.Command, _ []string) error {
6690 return nil
6791}
6892
69- func (c * helpCommand ) execute (_ * cobra.Command , _ []string ) {
93+ func (c * helpCommand ) execute (_ * cobra.Command , _ []string ) error {
94+ if c .opts .JSON {
95+ return c .printJSON ()
96+ }
97+
98+ c .print ()
99+
100+ return nil
101+ }
102+
103+ func (c * helpCommand ) printJSON () error {
104+ var linters []linterHelp
105+
106+ for _ , lc := range c .dbManager .GetAllSupportedLinterConfigs () {
107+ if lc .Internal {
108+ continue
109+ }
110+
111+ linters = append (linters , linterHelp {
112+ Name : lc .Name (),
113+ Desc : formatDescription (lc .Linter .Desc ()),
114+ Fast : ! lc .IsSlowLinter (),
115+ AutoFix : lc .CanAutoFix ,
116+ Presets : lc .InPresets ,
117+ EnabledByDefault : lc .EnabledByDefault ,
118+ Deprecated : lc .IsDeprecated (),
119+ Since : lc .Since ,
120+ OriginalURL : lc .OriginalURL ,
121+ })
122+ }
123+
124+ return json .NewEncoder (c .cmd .OutOrStdout ()).Encode (linters )
125+ }
126+
127+ func (c * helpCommand ) print () {
70128 var enabledLCs , disabledLCs []* linter.Config
71129 for _ , lc := range c .dbManager .GetAllSupportedLinterConfigs () {
72130 if lc .Internal {
@@ -126,22 +184,7 @@ func printLinters(lcs []*linter.Config) {
126184 })
127185
128186 for _ , lc := range lcs {
129- desc := lc .Linter .Desc ()
130-
131- // If the linter description spans multiple lines, truncate everything following the first newline
132- endFirstLine := strings .IndexRune (desc , '\n' )
133- if endFirstLine > 0 {
134- desc = desc [:endFirstLine ]
135- }
136-
137- rawDesc := []rune (desc )
138-
139- r , _ := utf8 .DecodeRuneInString (desc )
140- rawDesc [0 ] = unicode .ToUpper (r )
141-
142- if rawDesc [len (rawDesc )- 1 ] != '.' {
143- rawDesc = append (rawDesc , '.' )
144- }
187+ desc := formatDescription (lc .Linter .Desc ())
145188
146189 deprecatedMark := ""
147190 if lc .IsDeprecated () {
@@ -162,6 +205,25 @@ func printLinters(lcs []*linter.Config) {
162205 }
163206
164207 _ , _ = fmt .Fprintf (logutils .StdOut , "%s%s: %s%s\n " ,
165- color .YellowString (lc .Name ()), deprecatedMark , string (rawDesc ), capability )
208+ color .YellowString (lc .Name ()), deprecatedMark , desc , capability )
209+ }
210+ }
211+
212+ func formatDescription (desc string ) string {
213+ // If the linter description spans multiple lines, truncate everything following the first newline
214+ endFirstLine := strings .IndexRune (desc , '\n' )
215+ if endFirstLine > 0 {
216+ desc = desc [:endFirstLine ]
166217 }
218+
219+ rawDesc := []rune (desc )
220+
221+ r , _ := utf8 .DecodeRuneInString (desc )
222+ rawDesc [0 ] = unicode .ToUpper (r )
223+
224+ if rawDesc [len (rawDesc )- 1 ] != '.' {
225+ rawDesc = append (rawDesc , '.' )
226+ }
227+
228+ return string (rawDesc )
167229}
0 commit comments