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  }