github.com/nya3jp/tast@v0.0.0-20230601000426-85c8e4d83a9b/src/go.chromium.org/tast/core/cmd/tast-lint/main.go (about)

     1  // Copyright 2018 The ChromiumOS Authors
     2  // Use of this source code is governed by a BSD-style license that can be
     3  // found in the LICENSE file.
     4  
     5  // Package main implements tast-lint executable.
     6  package main
     7  
     8  import (
     9  	"flag"
    10  	"fmt"
    11  	"os"
    12  	"sort"
    13  
    14  	"go.chromium.org/tast/core/cmd/tast-lint/internal/check"
    15  	"go.chromium.org/tast/core/cmd/tast-lint/internal/lint"
    16  	"go.chromium.org/tast/core/shutil"
    17  )
    18  
    19  // categorizeIssues categorize issues into auto-fixable and un-auto-fixable,
    20  // then returns divided two slices.
    21  func categorizeIssues(issues []*check.Issue) (fixable, unfixable, warning []*check.Issue) {
    22  	for _, i := range issues {
    23  		if i.Warning {
    24  			warning = append(warning, i)
    25  		}
    26  		if i.Fixable {
    27  			fixable = append(fixable, i)
    28  		} else {
    29  			unfixable = append(unfixable, i)
    30  		}
    31  	}
    32  	return
    33  }
    34  
    35  // report prints issues to stdout.
    36  func report(issues []*check.Issue) {
    37  	check.SortIssues(issues)
    38  
    39  	for _, i := range issues {
    40  		fmt.Println(" ", i)
    41  	}
    42  
    43  	linkSet := make(map[string]struct{})
    44  	for _, i := range issues {
    45  		if i.Link != "" {
    46  			linkSet[i.Link] = struct{}{}
    47  		}
    48  	}
    49  	if len(linkSet) > 0 {
    50  		var links []string
    51  		for link := range linkSet {
    52  			links = append(links, link)
    53  		}
    54  		sort.Strings(links)
    55  
    56  		fmt.Println()
    57  		fmt.Println(" ", "Refer the following documents for details:")
    58  		for _, link := range links {
    59  			fmt.Println("  ", link)
    60  		}
    61  	}
    62  }
    63  
    64  func main() {
    65  	commit := flag.String("commit", "", "if set, checks files in the specified Git commit")
    66  	debug := flag.Bool("debug", false, "enables debug outputs")
    67  	fix := flag.Bool("fix", false, "modifies auto-fixable errors automatically")
    68  	flag.Parse()
    69  
    70  	issues, err := lint.Run(*commit, *debug, *fix, flag.Args())
    71  	if err == lint.ErrNoTarget {
    72  		flag.Usage()
    73  		return
    74  	}
    75  	if err != nil {
    76  		fmt.Println("Failed to run lint: ", err)
    77  		panic(err)
    78  	}
    79  
    80  	if len(issues) > 0 && !*fix {
    81  		// categorize issues
    82  		fixable, unfixable, warning := categorizeIssues(issues)
    83  		if len(warning) > 0 {
    84  			fmt.Println("Please address the following warnings:")
    85  			report(warning)
    86  			fmt.Println()
    87  		}
    88  		if len(unfixable) > 0 {
    89  			fmt.Println("Following errors should be modified by yourself:")
    90  			report(unfixable)
    91  			fmt.Println()
    92  		}
    93  		if len(fixable) > 0 {
    94  			fmt.Println("Following errors can be automatically modified:")
    95  			report(fixable)
    96  			fmt.Println()
    97  			cmd := append([]string{os.Args[0], "-fix"}, os.Args[1:]...)
    98  			fmt.Printf("  You can run `%s` to fix this\n", shutil.EscapeSlice(cmd))
    99  			fmt.Println()
   100  		}
   101  		os.Exit(1)
   102  	}
   103  }