2012-08-22 18:10:37 +00:00
|
|
|
#!/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', 'gyp', 'gypi']
|
|
|
|
|
|
|
|
_SUBDIRS_TO_IGNORE = ['.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: EOFNewlineAdder).
|
|
|
|
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 EOFNewlineAdder(file_content, file_path):
|
|
|
|
"""Adds a LF at the end of the file if it does not have one."""
|
2012-08-23 14:46:18 +00:00
|
|
|
if file_content and file_content[-1] != '\n':
|
2012-08-22 18:10:37 +00:00
|
|
|
file_content += '\n'
|
|
|
|
print 'Added 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,
|
|
|
|
EOFNewlineAdder,
|
|
|
|
SvnEOLChecker,
|
|
|
|
],
|
|
|
|
line_modifiers=[
|
|
|
|
CrlfReplacer,
|
|
|
|
TabReplacer,
|
|
|
|
TrailingWhitespaceRemover,
|
|
|
|
],
|
|
|
|
))
|
|
|
|
|