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  }