| 157 | # Heavily based on |
| 158 | # https://github.com/moby/moby/blob/master/pkg/fileutils/fileutils.go |
| 159 | class PatternMatcher: |
| 160 | def __init__(self, patterns): |
| 161 | self.patterns = list(filter( |
| 162 | lambda p: p.dirs, [Pattern(p) for p in patterns] |
| 163 | )) |
| 164 | self.patterns.append(Pattern('!.dockerignore')) |
| 165 | |
| 166 | def matches(self, filepath): |
| 167 | matched = False |
| 168 | parent_path = os.path.dirname(filepath) |
| 169 | parent_path_dirs = split_path(parent_path) |
| 170 | |
| 171 | for pattern in self.patterns: |
| 172 | negative = pattern.exclusion |
| 173 | match = pattern.match(filepath) |
| 174 | if not match and parent_path != '': |
| 175 | if len(pattern.dirs) <= len(parent_path_dirs): |
| 176 | match = pattern.match( |
| 177 | os.path.sep.join(parent_path_dirs[:len(pattern.dirs)]) |
| 178 | ) |
| 179 | |
| 180 | if match: |
| 181 | matched = not negative |
| 182 | |
| 183 | return matched |
| 184 | |
| 185 | def walk(self, root): |
| 186 | def rec_walk(current_dir): |
| 187 | for f in os.listdir(current_dir): |
| 188 | fpath = os.path.join( |
| 189 | os.path.relpath(current_dir, root), f |
| 190 | ) |
| 191 | if fpath.startswith(f".{os.path.sep}"): |
| 192 | fpath = fpath[2:] |
| 193 | match = self.matches(fpath) |
| 194 | if not match: |
| 195 | yield fpath |
| 196 | |
| 197 | cur = os.path.join(root, fpath) |
| 198 | if not os.path.isdir(cur) or os.path.islink(cur): |
| 199 | continue |
| 200 | |
| 201 | if match: |
| 202 | # If we want to skip this file and it's a directory |
| 203 | # then we should first check to see if there's an |
| 204 | # excludes pattern (e.g. !dir/file) that starts with this |
| 205 | # dir. If so then we can't skip this dir. |
| 206 | skip = True |
| 207 | |
| 208 | for pat in self.patterns: |
| 209 | if not pat.exclusion: |
| 210 | continue |
| 211 | if pat.cleaned_pattern.startswith( |
| 212 | normalize_slashes(fpath)): |
| 213 | skip = False |
| 214 | break |
| 215 | if skip: |
| 216 | continue |
no outgoing calls
no test coverage detected