You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
152 lines
4.7 KiB
152 lines
4.7 KiB
#!/usr/bin/env python |
|
# Copyright (c) 2012 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. |
|
|
|
"""Module that sanitizes source files with specified modifiers.""" |
|
|
|
|
|
import commands |
|
import os |
|
import sys |
|
|
|
|
|
_FILE_EXTENSIONS_TO_SANITIZE = ['cpp', 'h', 'c'] |
|
|
|
_SUBDIRS_TO_IGNORE = ['.git', '.svn', 'third_party'] |
|
|
|
|
|
def SanitizeFilesWithModifiers(directory, file_modifiers, line_modifiers): |
|
"""Sanitizes source files with the specified file and line modifiers. |
|
|
|
Args: |
|
directory: string - The directory which will be recursively traversed to |
|
find source files to apply modifiers to. |
|
file_modifiers: list - file-modification methods which should be applied to |
|
the complete file content (Eg: EOFOneAndOnlyOneNewlineAdder). |
|
line_modifiers: list - line-modification methods which should be applied to |
|
lines in a file (Eg: TabReplacer). |
|
""" |
|
for item in os.listdir(directory): |
|
|
|
full_item_path = os.path.join(directory, item) |
|
|
|
if os.path.isfile(full_item_path): # Item is a file. |
|
|
|
# Only sanitize files with extensions we care about. |
|
if (len(full_item_path.split('.')) > 1 and |
|
full_item_path.split('.')[-1] in _FILE_EXTENSIONS_TO_SANITIZE): |
|
f = file(full_item_path) |
|
try: |
|
lines = f.readlines() |
|
finally: |
|
f.close() |
|
|
|
new_lines = [] # Collect changed lines here. |
|
line_number = 0 # Keeps track of line numbers in the source file. |
|
write_to_file = False # File is written to only if this flag is set. |
|
|
|
# Run the line modifiers for each line in this file. |
|
for line in lines: |
|
original_line = line |
|
line_number += 1 |
|
|
|
for modifier in line_modifiers: |
|
line = modifier(line, full_item_path, line_number) |
|
if original_line != line: |
|
write_to_file = True |
|
new_lines.append(line) |
|
|
|
# Run the file modifiers. |
|
old_content = ''.join(lines) |
|
new_content = ''.join(new_lines) |
|
for modifier in file_modifiers: |
|
new_content = modifier(new_content, full_item_path) |
|
if new_content != old_content: |
|
write_to_file = True |
|
|
|
# Write modifications to the file. |
|
if write_to_file: |
|
f = file(full_item_path, 'w') |
|
try: |
|
f.write(new_content) |
|
finally: |
|
f.close() |
|
print 'Made changes to %s' % full_item_path |
|
|
|
elif item not in _SUBDIRS_TO_IGNORE: |
|
# Item is a directory recursively call the method. |
|
SanitizeFilesWithModifiers(full_item_path, file_modifiers, line_modifiers) |
|
|
|
|
|
############## Line Modification methods ############## |
|
|
|
|
|
def TrailingWhitespaceRemover(line, file_path, line_number): |
|
"""Strips out trailing whitespaces from the specified line.""" |
|
stripped_line = line.rstrip() + '\n' |
|
if line != stripped_line: |
|
print 'Removing trailing whitespace in %s:%s' % (file_path, line_number) |
|
return stripped_line |
|
|
|
|
|
def CrlfReplacer(line, file_path, line_number): |
|
"""Replaces CRLF with LF.""" |
|
if '\r\n' in line: |
|
print 'Replacing CRLF with LF in %s:%s' % (file_path, line_number) |
|
return line.replace('\r\n', '\n') |
|
|
|
|
|
def TabReplacer(line, file_path, line_number): |
|
"""Replaces Tabs with 4 whitespaces.""" |
|
if '\t' in line: |
|
print 'Replacing Tab with whitespace in %s:%s' % (file_path, line_number) |
|
return line.replace('\t', ' ') |
|
|
|
|
|
############## File Modification methods ############## |
|
|
|
|
|
def CopywriteChecker(file_content, unused_file_path): |
|
"""Ensures that the copywrite information is correct.""" |
|
# TODO(rmistry): Figure out the legal implications of changing old copyright |
|
# headers. |
|
return file_content |
|
|
|
|
|
def EOFOneAndOnlyOneNewlineAdder(file_content, file_path): |
|
"""Adds one and only one LF at the end of the file.""" |
|
if file_content and (file_content[-1] != '\n' or file_content[-2:-1] == '\n'): |
|
file_content = file_content.rstrip() |
|
file_content += '\n' |
|
print 'Added exactly one newline to %s' % file_path |
|
return file_content |
|
|
|
|
|
def SvnEOLChecker(file_content, file_path): |
|
"""Sets svn:eol-style property to LF.""" |
|
output = commands.getoutput( |
|
'svn propget svn:eol-style %s' % file_path) |
|
if output != 'LF': |
|
print 'Setting svn:eol-style property to LF in %s' % file_path |
|
os.system('svn ps svn:eol-style LF %s' % file_path) |
|
return file_content |
|
|
|
|
|
####################################################### |
|
|
|
|
|
if '__main__' == __name__: |
|
sys.exit(SanitizeFilesWithModifiers( |
|
os.getcwd(), |
|
file_modifiers=[ |
|
CopywriteChecker, |
|
EOFOneAndOnlyOneNewlineAdder, |
|
SvnEOLChecker, |
|
], |
|
line_modifiers=[ |
|
CrlfReplacer, |
|
TabReplacer, |
|
TrailingWhitespaceRemover, |
|
], |
|
))
|
|
|