(dir string, file string)
| 23 | ) |
| 24 | |
| 25 | func IsChild(dir string, file string) bool { |
| 26 | if dir == "" { |
| 27 | return false |
| 28 | } |
| 29 | |
| 30 | dir = filepath.Clean(dir) |
| 31 | current := filepath.Clean(file) |
| 32 | child := "." |
| 33 | for { |
| 34 | if strings.EqualFold(dir, current) { |
| 35 | // If the two paths are exactly equal, then they must be the same. |
| 36 | if dir == current { |
| 37 | return true |
| 38 | } |
| 39 | |
| 40 | // If the two paths are equal under case-folding, but not exactly equal, |
| 41 | // then the only way to check if they're truly "equal" is to check |
| 42 | // to see if we're on a case-insensitive file system. |
| 43 | // |
| 44 | // This is a notoriously tricky problem. See how dep solves it here: |
| 45 | // https://github.com/golang/dep/blob/v0.5.4/internal/fs/fs.go#L33 |
| 46 | // |
| 47 | // because you can mount case-sensitive filesystems onto case-insensitive |
| 48 | // file-systems, and vice versa :scream: |
| 49 | // |
| 50 | // We want to do as much of this check as possible with strings-only |
| 51 | // (to avoid a file system read and error handling), so we only |
| 52 | // do this check if we have no other choice. |
| 53 | dirInfo, err := os.Stat(dir) |
| 54 | if err != nil { |
| 55 | return false |
| 56 | } |
| 57 | |
| 58 | currentInfo, err := os.Stat(current) |
| 59 | if err != nil { |
| 60 | return false |
| 61 | } |
| 62 | |
| 63 | if !os.SameFile(dirInfo, currentInfo) { |
| 64 | return false |
| 65 | } |
| 66 | return true |
| 67 | } |
| 68 | |
| 69 | if len(current) <= len(dir) || current == "." { |
| 70 | return false |
| 71 | } |
| 72 | |
| 73 | cDir := filepath.Dir(current) |
| 74 | cBase := filepath.Base(current) |
| 75 | child = filepath.Join(cBase, child) |
| 76 | current = cDir |
| 77 | } |
| 78 | } |
| 79 | |
| 80 | // EncompassingPaths returns the minimal set of paths that root all paths |
| 81 | // from the original collection. |
no test coverage detected