github.com/Rookout/GoSDK@v0.1.48/pkg/utils/path_utils.go (about) 1 package utils 2 3 import ( 4 "os" 5 "path/filepath" 6 "strings" 7 ) 8 9 10 11 12 13 14 15 16 17 18 19 func GetPathMatchingScore(path1, path2 string) int { 20 path1List := splitPath(path1) 21 path2List := splitPath(path2) 22 L1 := len(path1List) 23 L2 := len(path2List) 24 shorterLen := L1 25 if L2 < shorterLen { 26 shorterLen = L2 27 } 28 matchingScore := 0 29 for i := 1; i <= shorterLen; i++ { 30 if path1List[L1-i] == path2List[L2-i] { 31 matchingScore++ 32 } else { 33 break 34 } 35 } 36 return matchingScore 37 } 38 39 func splitPath(p string) []string { 40 sep := string(os.PathSeparator) 41 p = filepath.Clean(p) 42 43 44 splitted := strings.Split(p, sep) 45 46 if len(splitted) > 0 && len(splitted[0]) == 0 { 47 splitted = splitted[1:] 48 } 49 50 if len(splitted) == 1 && len(splitted[0]) == 0 { 51 splitted[0] = "/" 52 } 53 return splitted 54 } 55 56 type FileMatcherUpdateRes int 57 58 const ( 59 NewBestMatch FileMatcherUpdateRes = iota 60 SameBestMatch 61 NotBestMatch 62 ) 63 64 func isInternalModuleFile(filename string) bool { 65 const externalGoModulePathIndicator = "pkg/mod/" 66 return !strings.Contains(filename, externalGoModulePathIndicator) 67 } 68 69 type FileMatcher struct { 70 uniqueFile bool 71 bestFile string 72 bestScore int 73 bestFileInternal bool 74 } 75 76 func NewFileMatcher() *FileMatcher { 77 return &FileMatcher{uniqueFile: false, bestFile: "", bestScore: -1, bestFileInternal: false} 78 } 79 80 func (f *FileMatcher) UpdateMatch(matchScore int, filename string) FileMatcherUpdateRes { 81 if matchScore > f.bestScore { 82 f.resetBest(matchScore, filename) 83 return NewBestMatch 84 } 85 86 if matchScore < f.bestScore { 87 88 return NotBestMatch 89 } 90 91 92 93 if filename == f.GetBestFile() && f.IsUnique() { 94 95 return SameBestMatch 96 } 97 98 if !f.bestFileInternal && isInternalModuleFile(filename) { 99 100 101 f.resetBest(matchScore, filename) 102 return NewBestMatch 103 } 104 105 if f.bestFileInternal && !isInternalModuleFile(filename) { 106 107 return NotBestMatch 108 } 109 110 f.uniqueFile = false 111 return NotBestMatch 112 } 113 114 func (f *FileMatcher) IsUnique() bool { 115 return f.uniqueFile 116 } 117 118 func (f *FileMatcher) GetBestFile() string { 119 return f.bestFile 120 } 121 122 func (f *FileMatcher) AnyMatch() bool { 123 return f.bestScore > 0 124 } 125 126 func (f *FileMatcher) resetBest(score int, filename string) { 127 f.bestScore = score 128 f.bestFile = filename 129 f.uniqueFile = true 130 f.bestFileInternal = isInternalModuleFile(filename) 131 }