github.com/jgarto/itcv@v0.0.0-20180826224514-4eea09c1aa0d/cmd/reactVet/reactVet.go (about)

     1  // reactVet is a vet program used to check the correctness of myitcv.io/react based packages.
     2  //
     3  //For more information see https://github.com/myitcv/react/wiki/reactVet
     4  //
     5  package main
     6  
     7  import (
     8  	"flag"
     9  	"fmt"
    10  	"go/build"
    11  	"go/token"
    12  	"os"
    13  	"path/filepath"
    14  	"sort"
    15  	"strings"
    16  
    17  	"github.com/kisielk/gotool"
    18  )
    19  
    20  func main() {
    21  	flag.Parse()
    22  
    23  	wd, err := os.Getwd()
    24  	if err != nil {
    25  		fatalf("could not get the working directory")
    26  	}
    27  
    28  	specs := gotool.ImportPaths(flag.Args())
    29  
    30  	emsgs := vet(wd, specs)
    31  
    32  	for _, msg := range emsgs {
    33  		fmt.Fprintf(os.Stderr, "%v\n", msg)
    34  	}
    35  
    36  	if len(emsgs) > 0 {
    37  		os.Exit(1)
    38  	}
    39  }
    40  
    41  func vet(wd string, specs []string) []vetErr {
    42  
    43  	var vetErrs []vetErr
    44  
    45  	for _, spec := range specs {
    46  
    47  		bpkg, err := build.Import(spec, wd, 0)
    48  		if err != nil {
    49  			fatalf("unable to import %v relative to %v: %v", spec, wd, err)
    50  		}
    51  
    52  		rv := newReactVetter(bpkg, wd)
    53  		rv.vetPackages()
    54  
    55  		vetErrs = append(vetErrs, rv.errlist...)
    56  	}
    57  
    58  	for i := range vetErrs {
    59  		rel, err := filepath.Rel(wd, vetErrs[i].pos.Filename)
    60  		if err != nil {
    61  			fatalf("relative path error, %v", err)
    62  		}
    63  
    64  		vetErrs[i].pos.Filename = rel
    65  	}
    66  
    67  	sort.Slice(vetErrs, func(i, j int) bool {
    68  
    69  		l, r := vetErrs[i].pos, vetErrs[j].pos
    70  
    71  		if v := strings.Compare(l.Filename, r.Filename); v != 0 {
    72  			return v < 0
    73  		}
    74  
    75  		if l.Line != r.Line {
    76  			return l.Line < r.Line
    77  		}
    78  
    79  		if l.Column != r.Column {
    80  			return l.Column < r.Column
    81  		}
    82  
    83  		return vetErrs[i].msg < vetErrs[j].msg
    84  	})
    85  
    86  	return vetErrs
    87  }
    88  
    89  type vetErr struct {
    90  	pos token.Position
    91  	msg string
    92  }
    93  
    94  func (r vetErr) String() string {
    95  	return fmt.Sprintf("%v:%v:%v: %v", r.pos.Filename, r.pos.Line, r.pos.Column, r.msg)
    96  }
    97  
    98  func fatalf(format string, args ...interface{}) {
    99  	panic(fmt.Errorf(format, args...))
   100  }