github.com/hikaru7719/go@v0.0.0-20181025140707-c8b2ac68906a/src/cmd/go/internal/imports/scan.go (about) 1 // Copyright 2018 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package imports 6 7 import ( 8 "fmt" 9 "io/ioutil" 10 "os" 11 "path/filepath" 12 "sort" 13 "strconv" 14 "strings" 15 ) 16 17 func ScanDir(dir string, tags map[string]bool) ([]string, []string, error) { 18 infos, err := ioutil.ReadDir(dir) 19 if err != nil { 20 return nil, nil, err 21 } 22 var files []string 23 for _, info := range infos { 24 name := info.Name() 25 if info.Mode().IsRegular() && !strings.HasPrefix(name, "_") && strings.HasSuffix(name, ".go") && MatchFile(name, tags) { 26 files = append(files, filepath.Join(dir, name)) 27 } 28 } 29 return scanFiles(files, tags, false) 30 } 31 32 func ScanFiles(files []string, tags map[string]bool) ([]string, []string, error) { 33 return scanFiles(files, tags, true) 34 } 35 36 func scanFiles(files []string, tags map[string]bool, explicitFiles bool) ([]string, []string, error) { 37 imports := make(map[string]bool) 38 testImports := make(map[string]bool) 39 numFiles := 0 40 Files: 41 for _, name := range files { 42 r, err := os.Open(name) 43 if err != nil { 44 return nil, nil, err 45 } 46 var list []string 47 data, err := ReadImports(r, false, &list) 48 r.Close() 49 if err != nil { 50 return nil, nil, fmt.Errorf("reading %s: %v", name, err) 51 } 52 53 // import "C" is implicit requirement of cgo tag. 54 // When listing files on the command line (explicitFiles=true) 55 // we do not apply build tag filtering but we still do apply 56 // cgo filtering, so no explicitFiles check here. 57 // Why? Because we always have, and it's not worth breaking 58 // that behavior now. 59 for _, path := range list { 60 if path == `"C"` && !tags["cgo"] && !tags["*"] { 61 continue Files 62 } 63 } 64 65 if !explicitFiles && !ShouldBuild(data, tags) { 66 continue 67 } 68 numFiles++ 69 m := imports 70 if strings.HasSuffix(name, "_test.go") { 71 m = testImports 72 } 73 for _, p := range list { 74 q, err := strconv.Unquote(p) 75 if err != nil { 76 continue 77 } 78 m[q] = true 79 } 80 } 81 if numFiles == 0 { 82 return nil, nil, ErrNoGo 83 } 84 return keys(imports), keys(testImports), nil 85 } 86 87 var ErrNoGo = fmt.Errorf("no Go source files") 88 89 func keys(m map[string]bool) []string { 90 var list []string 91 for k := range m { 92 list = append(list, k) 93 } 94 sort.Strings(list) 95 return list 96 }