| Index: presubmit_support.py
 | 
| ===================================================================
 | 
| --- presubmit_support.py	(revision 17575)
 | 
| +++ presubmit_support.py	(working copy)
 | 
| @@ -230,8 +230,9 @@
 | 
|      dir_with_slash = normpath("%s/" % self.PresubmitLocalPath())
 | 
|      if len(dir_with_slash) == 1:
 | 
|        dir_with_slash = ''
 | 
| -    return filter(lambda x: normpath(x.LocalPath()).startswith(dir_with_slash),
 | 
| -                  self.change.AffectedFiles(include_dirs, include_deletes))
 | 
| +    return filter(
 | 
| +        lambda x: normpath(x.AbsoluteLocalPath()).startswith(dir_with_slash),
 | 
| +        self.change.AffectedFiles(include_dirs, include_deletes))
 | 
|  
 | 
|    def LocalPaths(self, include_dirs=False):
 | 
|      """Returns local paths of input_api.AffectedFiles()."""
 | 
| @@ -548,33 +549,29 @@
 | 
|                 self.AffectedFiles(include_deletes=False)))
 | 
|  
 | 
|  
 | 
| -def ListRelevantPresubmitFiles(files):
 | 
| +def ListRelevantPresubmitFiles(files, root):
 | 
|    """Finds all presubmit files that apply to a given set of source files.
 | 
|  
 | 
|    Args:
 | 
|      files: An iterable container containing file paths.
 | 
| +    root: Path where to stop searching.
 | 
|  
 | 
|    Return:
 | 
| -    ['foo/blat/PRESUBMIT.py', 'mat/gat/PRESUBMIT.py']
 | 
| +    List of absolute paths of the existing PRESUBMIT.py scripts.
 | 
|    """
 | 
| -  checked_dirs = {}  # Keys are directory paths, values are ignored.
 | 
| -  source_dirs = [os.path.dirname(f) for f in files]
 | 
| -  presubmit_files = []
 | 
| -  for dir in source_dirs:
 | 
| -    while (True):
 | 
| -      if dir in checked_dirs:
 | 
| -        break  # We've already walked up from this directory.
 | 
| -
 | 
| -      test_path = os.path.join(dir, 'PRESUBMIT.py')
 | 
| -      if os.path.isfile(test_path):
 | 
| -        presubmit_files.append(normpath(test_path))
 | 
| -
 | 
| -      checked_dirs[dir] = ''
 | 
| -      if dir in ['', '.']:
 | 
| +  entries = []
 | 
| +  for f in files:
 | 
| +    f = normpath(os.path.join(root, f))
 | 
| +    while f:
 | 
| +      f = os.path.dirname(f)
 | 
| +      if f in entries:
 | 
|          break
 | 
| -      else:
 | 
| -        dir = os.path.dirname(dir)
 | 
| -  return presubmit_files
 | 
| +      entries.append(f)
 | 
| +      if f == root:
 | 
| +        break
 | 
| +  entries.sort()
 | 
| +  entries = map(lambda x: os.path.join(x, 'PRESUBMIT.py'), entries)
 | 
| +  return filter(lambda x: os.path.isfile(x), entries)
 | 
|  
 | 
|  
 | 
|  class PresubmitExecuter(object):
 | 
| @@ -653,7 +650,9 @@
 | 
|    Return:
 | 
|      True if execution can continue, False if not.
 | 
|    """
 | 
| -  presubmit_files = ListRelevantPresubmitFiles(change_info.FileList())
 | 
| +  checkout_root = gcl.GetRepositoryRoot()
 | 
| +  presubmit_files = ListRelevantPresubmitFiles(change_info.FileList(),
 | 
| +                                               checkout_root)
 | 
|    if not presubmit_files and verbose:
 | 
|      output_stream.write("Warning, no presubmit.py found.\n")
 | 
|    results = []
 | 
| @@ -661,7 +660,8 @@
 | 
|    if default_presubmit:
 | 
|      if verbose:
 | 
|        output_stream.write("Running default presubmit script.\n")
 | 
| -    results += executer.ExecPresubmitScript(default_presubmit, 'PRESUBMIT.py')
 | 
| +    fake_path = os.path.join(checkout_root, 'PRESUBMIT.py')
 | 
| +    results += executer.ExecPresubmitScript(default_presubmit, fake_path)
 | 
|    for filename in presubmit_files:
 | 
|      filename = os.path.abspath(filename)
 | 
|      if verbose:
 | 
| 
 |