| Index: post_process/mangle.py
 | 
| diff --git a/post_process/mangle.py b/post_process/mangle.py
 | 
| new file mode 100644
 | 
| index 0000000000000000000000000000000000000000..1ba7bcb76707bda6e110b135742ef17b583c2c61
 | 
| --- /dev/null
 | 
| +++ b/post_process/mangle.py
 | 
| @@ -0,0 +1,55 @@
 | 
| +# Copyright (c) 2011 The Chromium Authors. All rights reserved.
 | 
| +# Use of this source code is governed by a BSD-style license that can be
 | 
| +# found in the LICENSE file.
 | 
| +
 | 
| +from __future__ import with_statement
 | 
| +import os
 | 
| +import re
 | 
| +
 | 
| +
 | 
| +class MangleBase(object):
 | 
| +  """For each of the modified file, process the file."""
 | 
| +  def __init__(self, max_lines_search=None, once=False):
 | 
| +    self.max_lines_search = max_lines_search
 | 
| +    self.once = once
 | 
| +
 | 
| +  def process(self, checkout, patches):
 | 
| +    for patch in patches.patches:
 | 
| +      if patch.is_delete or patch.is_binary:
 | 
| +        pass
 | 
| +      filepath = os.path.join(checkout.project_path, patch.filename)
 | 
| +      with open(filepath, 'rb') as f:
 | 
| +        content = f.read().splitlines(True)
 | 
| +      if not content:
 | 
| +        continue
 | 
| +      if self.process_lines(content):
 | 
| +        with open(filepath, 'wb') as f:
 | 
| +          f.write(''.join(content))
 | 
| +
 | 
| +  def process_lines(self, lines):
 | 
| +    """Modifies lines in-place."""
 | 
| +    modified = False
 | 
| +    for i in xrange(min(self.max_lines_search, len(lines))):
 | 
| +      old_line = lines[i]
 | 
| +      lines[i] = self.process_line(lines[i])
 | 
| +      modified |= (old_line != lines[i])
 | 
| +      if self.once and modified:
 | 
| +        break
 | 
| +    return modified
 | 
| +
 | 
| +  def process_line(self, line):
 | 
| +    raise NotImplementedError('Modifies a single line')
 | 
| +
 | 
| +
 | 
| +class CopyrightMangle(MangleBase):
 | 
| +  """Process the copyright in the first 5 lines."""
 | 
| +  def __init__(self, pattern, replacement, max_lines_search=5):
 | 
| +    """Replaces |pattern| with |replacement| once if found within first
 | 
| +    |max_lines_search| lines of the file.
 | 
| +    """
 | 
| +    super(CopyrightMangle, self).__init__(max_lines_search, True)
 | 
| +    self.pattern = pattern
 | 
| +    self.replacement = replacement
 | 
| +
 | 
| +  def process_line(self, line):
 | 
| +    return re.sub(self.pattern, self.replacement, line)
 | 
| 
 |