github.com/shulhan/golangci-lint@v1.10.1/scripts/gen_readme/main.go (about) 1 package main 2 3 import ( 4 "bytes" 5 "fmt" 6 "io/ioutil" 7 "log" 8 "os" 9 "os/exec" 10 "strings" 11 "text/template" 12 13 "github.com/golangci/golangci-lint/pkg/lint/linter" 14 "github.com/golangci/golangci-lint/pkg/lint/lintersdb" 15 ) 16 17 func main() { 18 const ( 19 tmplPath = "README.tmpl.md" 20 outPath = "README.md" 21 ) 22 23 if err := genReadme(tmplPath, outPath); err != nil { 24 log.Fatalf("failed: %s", err) 25 } 26 log.Printf("Successfully generated %s", outPath) 27 } 28 29 func genReadme(tmplPath, outPath string) error { 30 ctx, err := buildTemplateContext() 31 if err != nil { 32 return err 33 } 34 35 out, err := os.Create(outPath) 36 if err != nil { 37 return err 38 } 39 defer out.Close() 40 41 tmpl := template.Must(template.ParseFiles(tmplPath)) 42 return tmpl.Execute(out, ctx) 43 } 44 45 func buildTemplateContext() (map[string]interface{}, error) { 46 golangciYaml, err := ioutil.ReadFile(".golangci.yml") 47 if err != nil { 48 return nil, fmt.Errorf("can't read .golangci.yml: %s", err) 49 } 50 51 golangciYamlExample, err := ioutil.ReadFile(".golangci.example.yml") 52 if err != nil { 53 return nil, fmt.Errorf("can't read .golangci.example.yml: %s", err) 54 } 55 56 if err = exec.Command("go", "install", "./cmd/...").Run(); err != nil { 57 return nil, fmt.Errorf("can't run go install: %s", err) 58 } 59 60 lintersOut, err := exec.Command("golangci-lint", "help", "linters").Output() 61 if err != nil { 62 return nil, fmt.Errorf("can't run linters cmd: %s", err) 63 } 64 65 lintersOutParts := bytes.Split(lintersOut, []byte("\n\n")) 66 67 helpCmd := exec.Command("golangci-lint", "run", "-h") 68 helpCmd.Env = append(helpCmd.Env, os.Environ()...) 69 helpCmd.Env = append(helpCmd.Env, "HELP_RUN=1") // make default concurrency stable: don't depend on machine CPU number 70 help, err := helpCmd.Output() 71 if err != nil { 72 return nil, fmt.Errorf("can't run help cmd: %s", err) 73 } 74 75 helpLines := bytes.Split(help, []byte("\n")) 76 shortHelp := bytes.Join(helpLines[2:], []byte("\n")) 77 78 return map[string]interface{}{ 79 "GolangciYaml": string(golangciYaml), 80 "GolangciYamlExample": string(golangciYamlExample), 81 "LintersCommandOutputEnabledOnly": string(lintersOutParts[0]), 82 "LintersCommandOutputDisabledOnly": string(lintersOutParts[1]), 83 "EnabledByDefaultLinters": getLintersListMarkdown(true), 84 "DisabledByDefaultLinters": getLintersListMarkdown(false), 85 "ThanksList": getThanksList(), 86 "RunHelpText": string(shortHelp), 87 }, nil 88 } 89 90 func getLintersListMarkdown(enabled bool) string { 91 var neededLcs []linter.Config 92 lcs := lintersdb.GetAllSupportedLinterConfigs() 93 for _, lc := range lcs { 94 if lc.EnabledByDefault == enabled { 95 neededLcs = append(neededLcs, lc) 96 } 97 } 98 99 var lines []string 100 for _, lc := range neededLcs { 101 var link string 102 if lc.OriginalURL != "" { 103 link = fmt.Sprintf("[%s](%s)", lc.Linter.Name(), lc.OriginalURL) 104 } else { 105 link = lc.Linter.Name() 106 } 107 line := fmt.Sprintf("- %s - %s", link, lc.Linter.Desc()) 108 lines = append(lines, line) 109 } 110 111 return strings.Join(lines, "\n") 112 } 113 114 func getThanksList() string { 115 var lines []string 116 addedAuthors := map[string]bool{} 117 for _, lc := range lintersdb.GetAllSupportedLinterConfigs() { 118 if lc.OriginalURL == "" { 119 continue 120 } 121 122 const githubPrefix = "https://github.com/" 123 if !strings.HasPrefix(lc.OriginalURL, githubPrefix) { 124 continue 125 } 126 127 githubSuffix := strings.TrimPrefix(lc.OriginalURL, githubPrefix) 128 githubAuthor := strings.Split(githubSuffix, "/")[0] 129 if addedAuthors[githubAuthor] { 130 continue 131 } 132 addedAuthors[githubAuthor] = true 133 134 line := fmt.Sprintf("- [%s](https://github.com/%s)", 135 githubAuthor, githubAuthor) 136 lines = append(lines, line) 137 } 138 139 return strings.Join(lines, "\n") 140 }