github.com/serversong/goreporter@v0.0.0-20200325104552-3cfaf44fd178/utils/utils.go (about)

     1  // Copyright 2017 The GoReporter Authors.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //    http://www.apache.org/licenses/LICENSE-2.0
     7  //
     8  // Unless required by applicable law or agreed to in writing, software
     9  // distributed under the License is distributed on an "AS IS" BASIS,
    10  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    11  // See the License for the specific language governing permissions and
    12  // limitations under the License.
    13  
    14  package utils
    15  
    16  import (
    17  	"os"
    18  	"path/filepath"
    19  	"strings"
    20  
    21  	"github.com/golang/glog"
    22  	"go/build"
    23  	"fmt"
    24  )
    25  
    26  var (
    27  	excepts []string
    28  )
    29  
    30  // DirList is a function that traverse the file directory containing the
    31  // specified file format according to the specified rule.
    32  func DirList(projectPath string, suffix, except string) (dirs map[string]string, err error) {
    33  	var relativePath string = ""
    34  	dirs = make(map[string]string, 0)
    35  	_, err = os.Stat(projectPath)
    36  	if err != nil {
    37  		glog.Errorln("dir path is invalid")
    38  	}
    39  	if build.IsLocalImport(projectPath) {
    40  		toPos := strings.LastIndex(projectPath, string(filepath.Separator))
    41  		relativePath = projectPath[0:toPos+1]
    42  	}
    43  	exceptsFilter(except)
    44  	err = filepath.Walk(projectPath, func(subPath string, f os.FileInfo, err error) error {
    45  		if f == nil {
    46  			return err
    47  		}
    48  		if f.IsDir() {
    49  			return nil
    50  		}
    51  		if strings.HasSuffix(subPath, suffix) {
    52  			sepIdx := strings.LastIndex(subPath, string(filepath.Separator))
    53  			var dir string
    54  			if sepIdx == -1 {
    55  				dir = "."
    56  			} else {
    57  				if len(subPath) > sepIdx {
    58  					dir = subPath[0:sepIdx]
    59  					dir = fmt.Sprintf("%s%s", relativePath, dir)
    60  				}
    61  			}
    62  			if ExceptPkg(dir) {
    63  				return nil
    64  			}
    65  			dirs[PackageAbsPath(dir)] = dir
    66  			return nil
    67  		}
    68  		return nil
    69  	})
    70  	if err != nil {
    71  		return nil, err
    72  	}
    73  
    74  	return dirs, nil
    75  }
    76  
    77  // FileList is a function that traverse the file is the specified file format
    78  // according to the specified rule.
    79  func FileList(projectPath string, suffix, except string) (files []string, err error) {
    80  	_, err = os.Stat(projectPath)
    81  	if err != nil {
    82  		glog.Errorln("project path is invalid")
    83  	}
    84  	exceptsFilter(except)
    85  	err = filepath.Walk(projectPath, func(subPath string, f os.FileInfo, err error) error {
    86  		if f == nil {
    87  			return err
    88  		}
    89  		if f.IsDir() {
    90  			return nil
    91  		}
    92  		if strings.HasSuffix(subPath, suffix) {
    93  
    94  			if ExceptPkg(subPath) {
    95  				return nil
    96  			}
    97  			files = append(files, subPath)
    98  			return nil
    99  		}
   100  		return nil
   101  	})
   102  	if err != nil {
   103  		return nil, err
   104  	}
   105  
   106  	return files, nil
   107  }
   108  
   109  // ExceptPkg is a function that will determine whether the package is an exception.
   110  func ExceptPkg(pkg string) bool {
   111  	for _, va := range excepts {
   112  		if strings.Contains(pkg, va) {
   113  			return true
   114  		}
   115  	}
   116  	return false
   117  }
   118  
   119  // PackageAbsPath will gets the absolute path of the specified
   120  // package from GOPATH's [src].
   121  func PackageAbsPath(path string) (packagePath string) {
   122  	_, err := os.Stat(path)
   123  	if err != nil {
   124  		glog.Errorln("package path is invalid")
   125  	}
   126  	absPath, err := filepath.Abs(path)
   127  	if err != nil {
   128  		glog.Fatal(err)
   129  	}
   130  
   131  	packagePathIndex := strings.LastIndex(absPath, string(filepath.Separator)+"src"+string(filepath.Separator))
   132  	if -1 != packagePathIndex {
   133  		packagePath = absPath[(packagePathIndex + 5):]
   134  	}
   135  
   136  	return packagePath
   137  }
   138  
   139  // PackageAbsPath will gets the absolute directory path of
   140  // the specified file from GOPATH's [src].
   141  func PackageAbsPathExceptSuffix(path string) (packagePath string) {
   142  	if strings.LastIndex(path, string(filepath.Separator)) <= 0 {
   143  		path, _ = os.Getwd()
   144  	}
   145  	path = path[0:strings.LastIndex(path, string(filepath.Separator))]
   146  	absPath, err := filepath.Abs(path)
   147  	if err != nil {
   148  		glog.Errorln(err)
   149  	}
   150  	packagePathIndex := strings.Index(absPath, "src")
   151  	if -1 != packagePathIndex && (packagePathIndex+4) < len(absPath) {
   152  		packagePath = absPath[(packagePathIndex + 4):]
   153  	}
   154  
   155  	return packagePath
   156  }
   157  
   158  // ProjectName is a function that gets project's name.
   159  func ProjectName(projectPath string) (project string) {
   160  	absPath, err := filepath.Abs(projectPath)
   161  	if err != nil {
   162  		glog.Errorln(err)
   163  	}
   164  	projectPathIndex := strings.LastIndex(absPath, string(filepath.Separator))
   165  	if -1 != projectPathIndex {
   166  		project = absPath[(projectPathIndex + 1):]
   167  	}
   168  
   169  	return project
   170  }
   171  
   172  // AbsPath is a function that will get absolute path of file.
   173  func AbsPath(path string) string {
   174  	absPath, err := filepath.Abs(path)
   175  	if err != nil {
   176  		glog.Errorln(err)
   177  		return path
   178  	}
   179  	return absPath
   180  }
   181  
   182  // PackageNameFromGoPath is a function that will get package's name from GOPATH.
   183  func PackageNameFromGoPath(path string) string {
   184  	names := strings.Split(path, string(filepath.Separator))
   185  	if len(names) >= 2 {
   186  		return names[len(names)-2]
   187  	}
   188  	return "null"
   189  }
   190  
   191  // exceptsFilter provides function that filte except string check it's
   192  // value is not a null string.
   193  func exceptsFilter(except string) {
   194  	temp := strings.Split(except, ",")
   195  	temp = append(temp, "vendor")
   196  	for i, _ := range temp {
   197  		if temp[i] != "" {
   198  			excepts = append(excepts, temp[i])
   199  		}
   200  	}
   201  }
   202  
   203  // CountPercentage will count all linters' percentage.And rule is
   204  //
   205  //    +--------------------------------------------------+
   206  //    |   issues    |               score                |
   207  //    +==================================================+
   208  //    | 5           | 100-issues*2                       |
   209  //    +--------------------------------------------------+
   210  //    | [5,10)      | 100 - 10 - (issues-5)*4            |
   211  //    +--------------------------------------------------+
   212  //    | [10,20)     | 100 - 10 - 20 - (issues-10)*5      |
   213  //    +--------------------------------------------------+
   214  //    | [20,40)     | 100 - 10 - 20 - 50 - (issues-20)*1 |
   215  //    +--------------------------------------------------+
   216  //    | [40,*)      | 0                                  |
   217  //    +--------------------------------------------------+
   218  //
   219  // It will return a float64 type score.
   220  func CountPercentage(issues int) float64 {
   221  	if issues < 5 {
   222  		return float64(100 - issues*2)
   223  	} else if issues < 10 {
   224  		return float64(100 - 10 - (issues-5)*4)
   225  	} else if issues < 20 {
   226  		return float64(100 - 10 - 20 - (issues-10)*5)
   227  	} else if issues < 40 {
   228  		return float64(100 - 10 - 20 - 50 - (issues-20)*1)
   229  	} else {
   230  		return 0.0
   231  	}
   232  }
   233  
   234  // GetProcessUnit provides function that will get sumProcessNumber of linter's
   235  // weight and the number of current linter's case.It will return 1 if
   236  // sumProcessNumber/int64(number) <= 0 or  sumProcessNumber / int64(number).
   237  // Just for communication.
   238  func GetProcessUnit(sumProcessNumber int64, number int) int64 {
   239  	if number == 0 {
   240  		return sumProcessNumber
   241  	} else if sumProcessNumber/int64(number) <= 0 {
   242  		return int64(1)
   243  	} else {
   244  		return sumProcessNumber / int64(number)
   245  	}
   246  }