github.com/yoheimuta/protolint@v0.49.8-0.20240515023657-4ecaebb7575d/internal/linter/file/protoSet.go (about) 1 package file 2 3 import ( 4 "fmt" 5 "os" 6 "path/filepath" 7 ) 8 9 // ProtoSet represents a set of .proto files. 10 type ProtoSet struct { 11 protoFiles []ProtoFile 12 } 13 14 // NewProtoSet creates a new ProtoSet. 15 func NewProtoSet( 16 targetPaths []string, 17 ) (ProtoSet, error) { 18 fs, err := collectAllProtoFilesFromArgs(targetPaths) 19 if err != nil { 20 return ProtoSet{}, err 21 } 22 if len(fs) == 0 { 23 return ProtoSet{}, fmt.Errorf("not found protocol buffer files in %v", targetPaths) 24 } 25 26 return ProtoSet{ 27 protoFiles: fs, 28 }, nil 29 } 30 31 // ProtoFiles returns proto files. 32 func (s ProtoSet) ProtoFiles() []ProtoFile { 33 return s.protoFiles 34 } 35 36 func collectAllProtoFilesFromArgs( 37 targetPaths []string, 38 ) ([]ProtoFile, error) { 39 cwd, err := os.Getwd() 40 if err != nil { 41 return nil, err 42 } 43 absCwd, err := absClean(cwd) 44 if err != nil { 45 return nil, err 46 } 47 // Eval a possible symlink for the cwd to calculate the correct relative paths in the next step. 48 if newPath, err := filepath.EvalSymlinks(absCwd); err == nil { 49 absCwd = newPath 50 } 51 52 var fs []ProtoFile 53 for _, path := range targetPaths { 54 absTarget, err := absClean(path) 55 if err != nil { 56 return nil, err 57 } 58 59 f, err := collectAllProtoFiles(absCwd, absTarget) 60 if err != nil { 61 return nil, err 62 } 63 fs = append(fs, f...) 64 } 65 return fs, nil 66 } 67 68 func collectAllProtoFiles( 69 absWorkDirPath string, 70 absPath string, 71 ) ([]ProtoFile, error) { 72 var fs []ProtoFile 73 74 err := filepath.Walk( 75 absPath, 76 func(path string, info os.FileInfo, err error) error { 77 if err != nil { 78 return err 79 } 80 if filepath.Ext(path) != ".proto" { 81 return nil 82 } 83 84 displayPath, err := filepath.Rel(absWorkDirPath, path) 85 if err != nil { 86 displayPath = path 87 } 88 displayPath = filepath.Clean(displayPath) 89 fs = append(fs, NewProtoFile(path, displayPath)) 90 return nil 91 }, 92 ) 93 if err != nil { 94 return nil, err 95 } 96 return fs, nil 97 } 98 99 // absClean returns the cleaned absolute path of the given path. 100 func absClean(path string) (string, error) { 101 if path == "" { 102 return path, nil 103 } 104 if !filepath.IsAbs(path) { 105 return filepath.Abs(path) 106 } 107 return filepath.Clean(path), nil 108 }