diff options
Diffstat (limited to 'WebKitTools/Scripts/webkitpy/style/optparser.py')
-rw-r--r-- | WebKitTools/Scripts/webkitpy/style/optparser.py | 457 |
1 files changed, 0 insertions, 457 deletions
diff --git a/WebKitTools/Scripts/webkitpy/style/optparser.py b/WebKitTools/Scripts/webkitpy/style/optparser.py deleted file mode 100644 index f4e9923..0000000 --- a/WebKitTools/Scripts/webkitpy/style/optparser.py +++ /dev/null @@ -1,457 +0,0 @@ -# Copyright (C) 2010 Chris Jerdonek (cjerdonek@webkit.org) -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# 1. Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# -# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY -# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -# DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY -# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -"""Supports the parsing of command-line options for check-webkit-style.""" - -import logging -from optparse import OptionParser -import os.path -import sys - -from filter import validate_filter_rules -# This module should not import anything from checker.py. - -_log = logging.getLogger(__name__) - -_USAGE = """usage: %prog [--help] [options] [path1] [path2] ... - -Overview: - Check coding style according to WebKit style guidelines: - - http://webkit.org/coding/coding-style.html - - Path arguments can be files and directories. If neither a git commit nor - paths are passed, then all changes in your source control working directory - are checked. - -Style errors: - This script assigns to every style error a confidence score from 1-5 and - a category name. A confidence score of 5 means the error is certainly - a problem, and 1 means it could be fine. - - Category names appear in error messages in brackets, for example - [whitespace/indent]. See the options section below for an option that - displays all available categories and which are reported by default. - -Filters: - Use filters to configure what errors to report. Filters are specified using - a comma-separated list of boolean filter rules. The script reports errors - in a category if the category passes the filter, as described below. - - All categories start out passing. Boolean filter rules are then evaluated - from left to right, with later rules taking precedence. For example, the - rule "+foo" passes any category that starts with "foo", and "-foo" fails - any such category. The filter input "-whitespace,+whitespace/braces" fails - the category "whitespace/tab" and passes "whitespace/braces". - - Examples: --filter=-whitespace,+whitespace/braces - --filter=-whitespace,-runtime/printf,+runtime/printf_format - --filter=-,+build/include_what_you_use - -Paths: - Certain style-checking behavior depends on the paths relative to - the WebKit source root of the files being checked. For example, - certain types of errors may be handled differently for files in - WebKit/gtk/webkit/ (e.g. by suppressing "readability/naming" errors - for files in this directory). - - Consequently, if the path relative to the source root cannot be - determined for a file being checked, then style checking may not - work correctly for that file. This can occur, for example, if no - WebKit checkout can be found, or if the source root can be detected, - but one of the files being checked lies outside the source tree. - - If a WebKit checkout can be detected and all files being checked - are in the source tree, then all paths will automatically be - converted to paths relative to the source root prior to checking. - This is also useful for display purposes. - - Currently, this command can detect the source root only if the - command is run from within a WebKit checkout (i.e. if the current - working directory is below the root of a checkout). In particular, - it is not recommended to run this script from a directory outside - a checkout. - - Running this script from a top-level WebKit source directory and - checking only files in the source tree will ensure that all style - checking behaves correctly -- whether or not a checkout can be - detected. This is because all file paths will already be relative - to the source root and so will not need to be converted.""" - -_EPILOG = ("This script can miss errors and does not substitute for " - "code review.") - - -# This class should not have knowledge of the flag key names. -class DefaultCommandOptionValues(object): - - """Stores the default check-webkit-style command-line options. - - Attributes: - output_format: A string that is the default output format. - min_confidence: An integer that is the default minimum confidence level. - - """ - - def __init__(self, min_confidence, output_format): - self.min_confidence = min_confidence - self.output_format = output_format - - -# This class should not have knowledge of the flag key names. -class CommandOptionValues(object): - - """Stores the option values passed by the user via the command line. - - Attributes: - is_verbose: A boolean value of whether verbose logging is enabled. - - filter_rules: The list of filter rules provided by the user. - These rules are appended to the base rules and - path-specific rules and so take precedence over - the base filter rules, etc. - - git_commit: A string representing the git commit to check. - The default is None. - - min_confidence: An integer between 1 and 5 inclusive that is the - minimum confidence level of style errors to report. - The default is 1, which reports all errors. - - output_format: A string that is the output format. The supported - output formats are "emacs" which emacs can parse - and "vs7" which Microsoft Visual Studio 7 can parse. - - """ - def __init__(self, - filter_rules=None, - git_commit=None, - diff_files=None, - is_verbose=False, - min_confidence=1, - output_format="emacs"): - if filter_rules is None: - filter_rules = [] - - if (min_confidence < 1) or (min_confidence > 5): - raise ValueError('Invalid "min_confidence" parameter: value ' - "must be an integer between 1 and 5 inclusive. " - 'Value given: "%s".' % min_confidence) - - if output_format not in ("emacs", "vs7"): - raise ValueError('Invalid "output_format" parameter: ' - 'value must be "emacs" or "vs7". ' - 'Value given: "%s".' % output_format) - - self.filter_rules = filter_rules - self.git_commit = git_commit - self.diff_files = diff_files - self.is_verbose = is_verbose - self.min_confidence = min_confidence - self.output_format = output_format - - # Useful for unit testing. - def __eq__(self, other): - """Return whether this instance is equal to another.""" - if self.filter_rules != other.filter_rules: - return False - if self.git_commit != other.git_commit: - return False - if self.diff_files != other.diff_files: - return False - if self.is_verbose != other.is_verbose: - return False - if self.min_confidence != other.min_confidence: - return False - if self.output_format != other.output_format: - return False - - return True - - # Useful for unit testing. - def __ne__(self, other): - # Python does not automatically deduce this from __eq__(). - return not self.__eq__(other) - - -class ArgumentPrinter(object): - - """Supports the printing of check-webkit-style command arguments.""" - - def _flag_pair_to_string(self, flag_key, flag_value): - return '--%(key)s=%(val)s' % {'key': flag_key, 'val': flag_value } - - def to_flag_string(self, options): - """Return a flag string of the given CommandOptionValues instance. - - This method orders the flag values alphabetically by the flag key. - - Args: - options: A CommandOptionValues instance. - - """ - flags = {} - flags['min-confidence'] = options.min_confidence - flags['output'] = options.output_format - # Only include the filter flag if user-provided rules are present. - filter_rules = options.filter_rules - if filter_rules: - flags['filter'] = ",".join(filter_rules) - if options.git_commit: - flags['git-commit'] = options.git_commit - if options.diff_files: - flags['diff_files'] = options.diff_files - - flag_string = '' - # Alphabetizing lets us unit test this method. - for key in sorted(flags.keys()): - flag_string += self._flag_pair_to_string(key, flags[key]) + ' ' - - return flag_string.strip() - - -class ArgumentParser(object): - - # FIXME: Move the documentation of the attributes to the __init__ - # docstring after making the attributes internal. - """Supports the parsing of check-webkit-style command arguments. - - Attributes: - create_usage: A function that accepts a DefaultCommandOptionValues - instance and returns a string of usage instructions. - Defaults to the function that generates the usage - string for check-webkit-style. - default_options: A DefaultCommandOptionValues instance that provides - the default values for options not explicitly - provided by the user. - stderr_write: A function that takes a string as a parameter and - serves as stderr.write. Defaults to sys.stderr.write. - This parameter should be specified only for unit tests. - - """ - - def __init__(self, - all_categories, - default_options, - base_filter_rules=None, - mock_stderr=None, - usage=None): - """Create an ArgumentParser instance. - - Args: - all_categories: The set of all available style categories. - default_options: See the corresponding attribute in the class - docstring. - Keyword Args: - base_filter_rules: The list of filter rules at the beginning of - the list of rules used to check style. This - list has the least precedence when checking - style and precedes any user-provided rules. - The class uses this parameter only for display - purposes to the user. Defaults to the empty list. - create_usage: See the documentation of the corresponding - attribute in the class docstring. - stderr_write: See the documentation of the corresponding - attribute in the class docstring. - - """ - if base_filter_rules is None: - base_filter_rules = [] - stderr = sys.stderr if mock_stderr is None else mock_stderr - if usage is None: - usage = _USAGE - - self._all_categories = all_categories - self._base_filter_rules = base_filter_rules - - # FIXME: Rename these to reflect that they are internal. - self.default_options = default_options - self.stderr_write = stderr.write - - self._parser = self._create_option_parser(stderr=stderr, - usage=usage, - default_min_confidence=self.default_options.min_confidence, - default_output_format=self.default_options.output_format) - - def _create_option_parser(self, stderr, usage, - default_min_confidence, default_output_format): - # Since the epilog string is short, it is not necessary to replace - # the epilog string with a mock epilog string when testing. - # For this reason, we use _EPILOG directly rather than passing it - # as an argument like we do for the usage string. - parser = OptionParser(usage=usage, epilog=_EPILOG) - - filter_help = ('set a filter to control what categories of style ' - 'errors to report. Specify a filter using a comma-' - 'delimited list of boolean filter rules, for example ' - '"--filter -whitespace,+whitespace/braces". To display ' - 'all categories and which are enabled by default, pass ' - """no value (e.g. '-f ""' or '--filter=').""") - parser.add_option("-f", "--filter-rules", metavar="RULES", - dest="filter_value", help=filter_help) - - git_commit_help = ("check all changes in the given commit. " - "Use 'commit_id..' to check all changes after commmit_id") - parser.add_option("-g", "--git-diff", "--git-commit", - metavar="COMMIT", dest="git_commit", help=git_commit_help,) - - diff_files_help = "diff the files passed on the command line rather than checking the style of every line" - parser.add_option("--diff-files", action="store_true", dest="diff_files", default=False, help=diff_files_help) - - min_confidence_help = ("set the minimum confidence of style errors " - "to report. Can be an integer 1-5, with 1 " - "displaying all errors. Defaults to %default.") - parser.add_option("-m", "--min-confidence", metavar="INT", - type="int", dest="min_confidence", - default=default_min_confidence, - help=min_confidence_help) - - output_format_help = ('set the output format, which can be "emacs" ' - 'or "vs7" (for Visual Studio). ' - 'Defaults to "%default".') - parser.add_option("-o", "--output-format", metavar="FORMAT", - choices=["emacs", "vs7"], - dest="output_format", default=default_output_format, - help=output_format_help) - - verbose_help = "enable verbose logging." - parser.add_option("-v", "--verbose", dest="is_verbose", default=False, - action="store_true", help=verbose_help) - - # Override OptionParser's error() method so that option help will - # also display when an error occurs. Normally, just the usage - # string displays and not option help. - parser.error = self._parse_error - - # Override OptionParser's print_help() method so that help output - # does not render to the screen while running unit tests. - print_help = parser.print_help - parser.print_help = lambda: print_help(file=stderr) - - return parser - - def _parse_error(self, error_message): - """Print the help string and an error message, and exit.""" - # The method format_help() includes both the usage string and - # the flag options. - help = self._parser.format_help() - # Separate help from the error message with a single blank line. - self.stderr_write(help + "\n") - if error_message: - _log.error(error_message) - - # Since we are using this method to replace/override the Python - # module optparse's OptionParser.error() method, we match its - # behavior and exit with status code 2. - # - # As additional background, Python documentation says-- - # - # "Unix programs generally use 2 for command line syntax errors - # and 1 for all other kind of errors." - # - # (from http://docs.python.org/library/sys.html#sys.exit ) - sys.exit(2) - - def _exit_with_categories(self): - """Exit and print the style categories and default filter rules.""" - self.stderr_write('\nAll categories:\n') - for category in sorted(self._all_categories): - self.stderr_write(' ' + category + '\n') - - self.stderr_write('\nDefault filter rules**:\n') - for filter_rule in sorted(self._base_filter_rules): - self.stderr_write(' ' + filter_rule + '\n') - self.stderr_write('\n**The command always evaluates the above rules, ' - 'and before any --filter flag.\n\n') - - sys.exit(0) - - def _parse_filter_flag(self, flag_value): - """Parse the --filter flag, and return a list of filter rules. - - Args: - flag_value: A string of comma-separated filter rules, for - example "-whitespace,+whitespace/indent". - - """ - filters = [] - for uncleaned_filter in flag_value.split(','): - filter = uncleaned_filter.strip() - if not filter: - continue - filters.append(filter) - return filters - - def parse(self, args): - """Parse the command line arguments to check-webkit-style. - - Args: - args: A list of command-line arguments as returned by sys.argv[1:]. - - Returns: - A tuple of (paths, options) - - paths: The list of paths to check. - options: A CommandOptionValues instance. - - """ - (options, paths) = self._parser.parse_args(args=args) - - filter_value = options.filter_value - git_commit = options.git_commit - diff_files = options.diff_files - is_verbose = options.is_verbose - min_confidence = options.min_confidence - output_format = options.output_format - - if filter_value is not None and not filter_value: - # Then the user explicitly passed no filter, for - # example "-f ''" or "--filter=". - self._exit_with_categories() - - # Validate user-provided values. - - min_confidence = int(min_confidence) - if (min_confidence < 1) or (min_confidence > 5): - self._parse_error('option --min-confidence: invalid integer: ' - '%s: value must be between 1 and 5' - % min_confidence) - - if filter_value: - filter_rules = self._parse_filter_flag(filter_value) - else: - filter_rules = [] - - try: - validate_filter_rules(filter_rules, self._all_categories) - except ValueError, err: - self._parse_error(err) - - options = CommandOptionValues(filter_rules=filter_rules, - git_commit=git_commit, - diff_files=diff_files, - is_verbose=is_verbose, - min_confidence=min_confidence, - output_format=output_format) - - return (paths, options) - |