github.com/alecthomas/golangci-lint@v1.4.2-0.20180609094924-581a3564ff68/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.md.tmpl" 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 if err = exec.Command("go", "install", "./cmd/...").Run(); err != nil { 52 return nil, fmt.Errorf("can't run go install: %s", err) 53 } 54 55 lintersOut, err := exec.Command("golangci-lint", "linters").Output() 56 if err != nil { 57 return nil, fmt.Errorf("can't run linters cmd: %s", err) 58 } 59 60 lintersOutParts := bytes.Split(lintersOut, []byte("\n\n")) 61 62 helpCmd := exec.Command("golangci-lint", "run", "-h") 63 helpCmd.Env = append(helpCmd.Env, os.Environ()...) 64 helpCmd.Env = append(helpCmd.Env, "HELP_RUN=1") // make default concurrency stable: don't depend on machine CPU number 65 help, err := helpCmd.Output() 66 if err != nil { 67 return nil, fmt.Errorf("can't run help cmd: %s", err) 68 } 69 70 helpLines := bytes.Split(help, []byte("\n")) 71 shortHelp := bytes.Join(helpLines[2:], []byte("\n")) 72 73 return map[string]interface{}{ 74 "GolangciYaml": string(golangciYaml), 75 "LintersCommandOutputEnabledOnly": string(lintersOutParts[0]), 76 "LintersCommandOutputDisabledOnly": string(lintersOutParts[1]), 77 "EnabledByDefaultLinters": getLintersListMarkdown(true), 78 "DisabledByDefaultLinters": getLintersListMarkdown(false), 79 "ThanksList": getThanksList(), 80 "RunHelpText": string(shortHelp), 81 }, nil 82 } 83 84 func getLintersListMarkdown(enabled bool) string { 85 var neededLcs []linter.Config 86 lcs := lintersdb.GetAllSupportedLinterConfigs() 87 for _, lc := range lcs { 88 if lc.EnabledByDefault == enabled { 89 neededLcs = append(neededLcs, lc) 90 } 91 } 92 93 var lines []string 94 for _, lc := range neededLcs { 95 var link string 96 if lc.OriginalURL != "" { 97 link = fmt.Sprintf("[%s](%s)", lc.Linter.Name(), lc.OriginalURL) 98 } else { 99 link = lc.Linter.Name() 100 } 101 line := fmt.Sprintf("- %s - %s", link, lc.Linter.Desc()) 102 lines = append(lines, line) 103 } 104 105 return strings.Join(lines, "\n") 106 } 107 108 func getThanksList() string { 109 var lines []string 110 addedAuthors := map[string]bool{} 111 for _, lc := range lintersdb.GetAllSupportedLinterConfigs() { 112 if lc.OriginalURL == "" { 113 continue 114 } 115 116 const githubPrefix = "https://github.com/" 117 if !strings.HasPrefix(lc.OriginalURL, githubPrefix) { 118 continue 119 } 120 121 githubSuffix := strings.TrimPrefix(lc.OriginalURL, githubPrefix) 122 githubAuthor := strings.Split(githubSuffix, "/")[0] 123 if addedAuthors[githubAuthor] { 124 continue 125 } 126 addedAuthors[githubAuthor] = true 127 128 line := fmt.Sprintf("- [%s](https://github.com/%s)", 129 githubAuthor, githubAuthor) 130 lines = append(lines, line) 131 } 132 133 return strings.Join(lines, "\n") 134 }