Make some corrections on the check_patch.py script. Also, add an option to check all files on the tree using the -f (or --full-check) option. This is the script I used to create the massive permission and indentation fix.
Signed-off-by: Lucas Meneghel Rodrigues <[email protected]> --- utils/check_patch.py | 94 ++++++++++++++++++++++++++++++++------------------ 1 files changed, 60 insertions(+), 34 deletions(-) diff --git a/utils/check_patch.py b/utils/check_patch.py index 576b97d..f91b54c 100755 --- a/utils/check_patch.py +++ b/utils/check_patch.py @@ -20,7 +20,7 @@ Usage: check_patch.py -p [/path/to/patch] @author: Lucas Meneghel Rodrigues <[email protected]> """ -import os, stat, logging, sys, optparse +import os, stat, logging, sys, optparse, time import common from autotest_lib.client.common_lib import utils, error, logging_config from autotest_lib.client.common_lib import logging_manager @@ -32,6 +32,20 @@ class CheckPatchLoggingConfig(logging_config.LoggingConfig): verbose=verbose) +def ask(question, auto=False): + """ + Raw input with a prompt that emulates logging. + + @param question: Question to be asked + @param auto: Whether to return "y" instead of asking the question + """ + if auto: + logging.info("%s (y/n) y" % question) + return "y" + return raw_input("%s INFO | %s (y/n) " % + (time.strftime("%H:%M:%S", time.localtime()), question)) + + class VCS(object): """ Abstraction layer to the version control system. @@ -104,6 +118,7 @@ class SubVersionBackend(object): """ def __init__(self): logging.debug("Subversion VCS backend initialized.") + self.ignored_extension_list = ['.orig', '.bak'] def get_unknown_files(self): @@ -112,7 +127,9 @@ class SubVersionBackend(object): for line in status.split("\n"): status_flag = line[0] if line and status_flag == "?": - unknown_files.append(line[1:].strip()) + for extension in self.ignored_extension_list: + if not line.endswith(extension): + unknown_files.append(line[1:].strip()) return unknown_files @@ -181,13 +198,16 @@ class FileChecker(object): Picks up a given file and performs various checks, looking after problems and eventually suggesting solutions. """ - def __init__(self, path): + def __init__(self, path, confirm=False): """ Class constructor, sets the path attribute. @param path: Path to the file that will be checked. + @param confirm: Whether to answer yes to all questions asked without + prompting the user. """ self.path = path + self.confirm = confirm self.basename = os.path.basename(self.path) if self.basename.endswith('.py'): self.is_python = True @@ -204,7 +224,7 @@ class FileChecker(object): self.first_line = checked_file.readline() checked_file.close() self.corrective_actions = [] - self.indentation_exceptions = ['cli/job_unittest.py'] + self.indentation_exceptions = ['job_unittest.py'] def _check_indent(self): @@ -226,8 +246,6 @@ class FileChecker(object): reindent_results = reindent_raw.split(" ")[-1].strip(".") if reindent_results == "changed": if self.basename not in self.indentation_exceptions: - logging.error("Possible indentation and spacing issues on " - "file %s" % self.path) self.corrective_actions.append("reindent.py -v %s" % self.path) @@ -242,8 +260,7 @@ class FileChecker(object): c_cmd = 'run_pylint.py %s' % self.path rc = utils.system(c_cmd, ignore_status=True) if rc != 0: - logging.error("Possible syntax problems on file %s", self.path) - logging.error("You might want to rerun '%s'", c_cmd) + logging.error("Syntax issues found during '%s'", c_cmd) def _check_unittest(self): @@ -260,9 +277,8 @@ class FileChecker(object): unittest_cmd = 'python %s' % unittest_path rc = utils.system(unittest_cmd, ignore_status=True) if rc != 0: - logging.error("Problems during unit test execution " - "for file %s", self.path) - logging.error("You might want to rerun '%s'", unittest_cmd) + logging.error("Unittest issues found during '%s'", + unittest_cmd) def _check_permissions(self): @@ -273,14 +289,10 @@ class FileChecker(object): """ if self.first_line.startswith("#!"): if not self.is_executable: - logging.info("File %s seems to require execution " - "permissions. ", self.path) - self.corrective_actions.append("chmod +x %s" % self.path) + self.corrective_actions.append("svn propset svn:executable ON %s" % self.path) else: if self.is_executable: - logging.info("File %s does not seem to require execution " - "permissions. ", self.path) - self.corrective_actions.append("chmod -x %s" % self.path) + self.corrective_actions.append("svn propdel svn:executable %s" % self.path) def report(self): @@ -294,10 +306,9 @@ class FileChecker(object): self._check_code() self._check_unittest() if self.corrective_actions: - logging.info("The following corrective actions are suggested:") for action in self.corrective_actions: - logging.info(action) - answer = raw_input("Would you like to apply it? (y/n) ") + answer = ask("Would you like to execute %s?" % action, + auto=self.confirm) if answer == "y": rc = utils.system(action, ignore_status=True) if rc != 0: @@ -305,7 +316,8 @@ class FileChecker(object): class PatchChecker(object): - def __init__(self, patch=None, patchwork_id=None): + def __init__(self, patch=None, patchwork_id=None, confirm=False): + self.confirm = confirm self.base_dir = os.getcwd() if patch: self.patch = os.path.abspath(patch) @@ -322,7 +334,7 @@ class PatchChecker(object): if changed_files_before: logging.error("Repository has changed files prior to patch " "application. ") - answer = raw_input("Would you like to revert them? (y/n) ") + answer = ask("Would you like to revert them?", auto=self.confirm) if answer == "n": logging.error("Not safe to proceed without reverting files.") sys.exit(1) @@ -370,16 +382,13 @@ class PatchChecker(object): for untracked_file in add_to_vcs: logging.info(untracked_file) logging.info("Might need to be added to VCS") - logging.info("Would you like to add them to VCS ? (y/n/abort) ") - answer = raw_input() + answer = ask("Would you like to add them to VCS ?") if answer == "y": for untracked_file in add_to_vcs: self.vcs.add_untracked_file(untracked_file) modified_files_after.append(untracked_file) elif answer == "n": pass - elif answer == "abort": - sys.exit(1) for modified_file in modified_files_after: file_checker = FileChecker(modified_file) @@ -399,20 +408,37 @@ if __name__ == "__main__": help='id of a given patchwork patch') parser.add_option('--verbose', dest="debug", action='store_true', help='include debug messages in console output') + parser.add_option('-f', '--full-check', dest="full_check", + action='store_true', + help='check the full tree for corrective actions') + parser.add_option('-y', '--yes', dest="confirm", + action='store_true', + help='Answer yes to all questions') options, args = parser.parse_args() local_patch = options.local_patch id = options.id debug = options.debug + full_check = options.full_check + confirm = options.confirm logging_manager.configure_logging(CheckPatchLoggingConfig(), verbose=debug) - if local_patch: - patch_checker = PatchChecker(patch=local_patch) - elif id: - patch_checker = PatchChecker(patchwork_id=id) + ignore_file_list = ['common.py'] + if full_check: + for root, dirs, files in os.walk('.'): + if not '.svn' in root: + for file in files: + if file not in ignore_file_list: + path = os.path.join(root, file) + file_checker = FileChecker(path, confirm=confirm) + file_checker.report() else: - logging.error('No patch or patchwork id specified. Aborting.') - sys.exit(1) - - patch_checker.check() + if local_patch: + patch_checker = PatchChecker(patch=local_patch, confirm=confirm) + elif id: + patch_checker = PatchChecker(patchwork_id=id, confirm=confirm) + else: + logging.error('No patch or patchwork id specified. Aborting.') + sys.exit(1) + patch_checker.check() -- 1.7.2.3 _______________________________________________ Autotest mailing list [email protected] http://test.kernel.org/cgi-bin/mailman/listinfo/autotest
