15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)# Copyright 2014 The Chromium Authors. All rights reserved. 25d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)# Use of this source code is governed by a BSD-style license that can be 35d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)# found in the LICENSE file. 45d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 55d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)import collections 65d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)import os 75d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 85d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 95d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class PathSet(collections.MutableSet): 105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) """A set of paths. 115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) All mutation methods can take both directories or individual files, but the 135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) iterator yields the individual files. All paths are automatically normalized. 145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) """ 155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) def __init__(self, iterable=None): 165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self._paths = set() 175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if iterable: 185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self |= iterable 195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) def __contains__(self, path): 215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return os.path.realpath(path) in self._paths 225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) def __iter__(self): 245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return iter(self._paths) 255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) def __len__(self): 275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return len(self._paths) 285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) def add(self, path): 305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) path = os.path.realpath(path) 315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if os.path.isfile(path): 325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self._paths.add(path) 335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for root, _, files in os.walk(path): 345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for basename in files: 355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) file_path = os.path.join(root, basename) 365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if os.path.isfile(file_path): 375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self._paths.add(file_path) 385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) def discard(self, path): 405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) path = os.path.realpath(path) 415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self._paths.discard(path) 425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for root, _, files in os.walk(path): 435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for basename in files: 445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) self._paths.discard(os.path.join(root, basename)) 45