Format: text/x-python
⬇ Download File (1.9 KB)
   1  # Copyright (c) Microsoft Corporation. All rights reserved.
   2  # Licensed under the MIT License. See LICENSE in the project root
   3  # for license information.
   4  
   5  import contextlib
   6  import os
   7  
   8  
   9  @contextlib.contextmanager
  10  def cwd(dirname):
  11      """A context manager for operating in a different directory."""
  12      orig = os.getcwd()
  13      os.chdir(dirname)
  14      try:
  15          yield orig
  16      finally:
  17          os.chdir(orig)
  18  
  19  
  20  def iter_all_files(root, prune_dir=None, exclude_file=None):
  21      """Yield (dirname, basename, filename) for each file in the tree.
  22  
  23      This is an alternative to os.walk() that flattens out the tree and
  24      with filtering.
  25      """
  26      pending = [root]
  27      while pending:
  28          dirname = pending.pop(0)
  29          for result in _iter_files(dirname, pending, prune_dir, exclude_file):
  30              yield result
  31  
  32  
  33  def iter_tree(root, prune_dir=None, exclude_file=None):
  34      """Yield (dirname, files) for each directory in the tree.
  35  
  36      The list of files is actually a list of (basename, filename).
  37  
  38      This is an alternative to os.walk() with filtering."""
  39      pending = [root]
  40      while pending:
  41          dirname = pending.pop(0)
  42          files = []
  43          for _, b, f in _iter_files(dirname, pending, prune_dir, exclude_file):
  44              files.append((b, f))
  45          yield dirname, files
  46  
  47  
  48  def _iter_files(dirname, subdirs, prune_dir, exclude_file):
  49      for basename in os.listdir(dirname):
  50          filename = os.path.join(dirname, basename)
  51          if os.path.isdir(filename):
  52              if prune_dir is not None and prune_dir(dirname, basename):
  53                  continue
  54              subdirs.append(filename)
  55          else:
  56              # TODO: Use os.path.isfile() to narrow it down?
  57              if exclude_file is not None and exclude_file(dirname, basename):
  58                  continue
  59              yield dirname, basename, filename
  60