summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJenkins <jenkins@review.openstack.org>2015-04-09 15:08:02 +0000
committerGerrit Code Review <review@openstack.org>2015-04-09 15:08:03 +0000
commit24a3c9642ac5e4a1772773590d0e266e36879f3e (patch)
tree84e6090daef793cd03849a02a1756bbd6387b312
parent7ad4aaec88c130723409bc85ff3a3e6af53be574 (diff)
parentb2adee882b284bb9499c896e73988b622a329399 (diff)
Merge "Allow ignore specific error codes in files"
-rw-r--r--README.rst43
-rw-r--r--doc8/main.py43
2 files changed, 62 insertions, 24 deletions
diff --git a/README.rst b/README.rst
index c34d10a..46b8ce7 100644
--- a/README.rst
+++ b/README.rst
@@ -27,7 +27,8 @@ Command line usage
27 $ doc8 -h 27 $ doc8 -h
28 28
29 usage: doc8 [-h] [--config path] [--allow-long-titles] [--ignore code] 29 usage: doc8 [-h] [--config path] [--allow-long-titles] [--ignore code]
30 [--no-sphinx] [--ignore-path path] [--default-extension extension] 30 [--no-sphinx] [--ignore-path path] [--ignore-path-errors path]
31 [--default-extension extension] [--file-encoding encoding]
31 [--max-line-length int] [-e extension] [-v] [--version] 32 [--max-line-length int] [-e extension] [-v] [--version]
32 [path [path ...]] 33 [path [path ...]]
33 34
@@ -46,17 +47,20 @@ Command line usage
46 - no newline at end of file - D005 47 - no newline at end of file - D005
47 48
48 positional arguments: 49 positional arguments:
49 path path to scan for doc files (default: os.getcwd()) 50 path Path to scan for doc files (default: current
51 directory).
50 52
51 optional arguments: 53 optional arguments:
52 -h, --help show this help message and exit 54 -h, --help show this help message and exit
53 --config path user config file location (default: doc8.ini, tox.ini, 55 --config path User config file location (default: doc8.ini, tox.ini,
54 pep8.ini, setup.cfg) 56 pep8.ini, setup.cfg).
55 --allow-long-titles allow long section titles (default: False) 57 --allow-long-titles Allow long section titles (default: False).
56 --ignore code ignore the given errors code/codes 58 --ignore code Ignore the given error code(s).
57 --no-sphinx do not ignore sphinx specific false positives 59 --no-sphinx Do not ignore sphinx specific false positives.
58 --ignore-path path ignore the given directory or file (globs are 60 --ignore-path path Ignore the given directory or file (globs are
59 supported) 61 supported).
62 --ignore-path-errors path
63 Ignore the given specific errors in the provided file.
60 --default-extension extension 64 --default-extension extension
61 Default file extension to use when a file is found 65 Default file extension to use when a file is found
62 without a file extension. 66 without a file extension.
@@ -65,11 +69,11 @@ Command line usage
65 an input files text encoding (providing this avoids 69 an input files text encoding (providing this avoids
66 using `chardet` to automatically detect encoding/s) 70 using `chardet` to automatically detect encoding/s)
67 --max-line-length int 71 --max-line-length int
68 maximum allowed line length (default: 79) 72 Maximum allowed line length (default: 79).
69 -e extension, --extension extension 73 -e extension, --extension extension
70 check file extensions of the given type (default: 74 Check file extensions of the given type (default:
71 .rst, .txt) 75 .rst, .txt).
72 -v, --verbose run in verbose mode 76 -v, --verbose Run in verbose mode.
73 --version Show the version and exit. 77 --version Show the version and exit.
74 78
75Ini file usage 79Ini file usage
@@ -90,14 +94,14 @@ An example section that can be placed into one of these files::
90 94
91 [doc8] 95 [doc8]
92 96
93 ignore_path=/tmp/stuff,/tmp/other_stuff 97 ignore-path=/tmp/stuff,/tmp/other_stuff
94 max_line_length=99 98 max-line-length=99
95 verbose=1 99 verbose=1
100 ignore-path-errors=/tmp/other_thing.rst;D001;D002
96 101
97**Note:** The option names are the same as the command line ones but instead 102**Note:** The option names are the same as the command line ones (with the
98of dashes underscores are used instead (with the only variation of this being 103only variation of this being the ``no-sphinx`` option which from
99the ``no-sphinx`` option which from configuration file will be ``sphinx`` 104configuration file will be ``sphinx`` instead).
100instead).
101 105
102Option conflict resolution 106Option conflict resolution
103************************** 107**************************
@@ -110,6 +114,7 @@ of conflicts.
110Option Overrides Merges 114Option Overrides Merges
111===================== =========== ======== 115===================== =========== ========
112``allow-long-titles`` Yes No 116``allow-long-titles`` Yes No
117``ignore-path-errors`` No Yes
113``default-extension`` Yes No 118``default-extension`` Yes No
114``extension`` No Yes 119``extension`` No Yes
115``ignore-path`` No Yes 120``ignore-path`` No Yes
diff --git a/doc8/main.py b/doc8/main.py
index 19b5171..0196328 100644
--- a/doc8/main.py
+++ b/doc8/main.py
@@ -60,8 +60,8 @@ CONFIG_FILENAMES = [
60] 60]
61 61
62 62
63def split_set_type(text): 63def split_set_type(text, delimiter=","):
64 return set([i.strip() for i in text.split(",") if i.strip()]) 64 return set([i.strip() for i in text.split(delimiter) if i.strip()])
65 65
66 66
67def merge_sets(sets): 67def merge_sets(sets):
@@ -71,6 +71,16 @@ def merge_sets(sets):
71 return m 71 return m
72 72
73 73
74def parse_ignore_path_errors(entries):
75 ignore_path_errors = collections.defaultdict(set)
76 for path in entries:
77 path, ignored_errors = path.split(";", 1)
78 path = os.path.abspath(path.strip())
79 ignored_errors = split_set_type(ignored_errors, delimiter=";")
80 ignore_path_errors[path].update(ignored_errors)
81 return dict(ignore_path_errors)
82
83
74def extract_config(args): 84def extract_config(args):
75 parser = configparser.RawConfigParser() 85 parser = configparser.RawConfigParser()
76 read_files = [] 86 read_files = []
@@ -98,6 +108,13 @@ def extract_config(args):
98 except (configparser.NoSectionError, configparser.NoOptionError): 108 except (configparser.NoSectionError, configparser.NoOptionError):
99 pass 109 pass
100 try: 110 try:
111 ignore_path_errors = parser.get("doc8", "ignore-path-errors")
112 ignore_path_errors = split_set_type(ignore_path_errors)
113 ignore_path_errors = parse_ignore_path_errors(ignore_path_errors)
114 cfg['ignore_path_errors'] = ignore_path_errors
115 except (configparser.NoSectionError, configparser.NoOptionError):
116 pass
117 try:
101 cfg['allow_long_titles'] = parser.getboolean("doc8", 118 cfg['allow_long_titles'] = parser.getboolean("doc8",
102 "allow-long-titles") 119 "allow-long-titles")
103 except (configparser.NoSectionError, configparser.NoOptionError): 120 except (configparser.NoSectionError, configparser.NoOptionError):
@@ -186,10 +203,13 @@ def validate(cfg, files):
186 print("Validating...") 203 print("Validating...")
187 error_counts = {} 204 error_counts = {}
188 ignoreables = frozenset(cfg.get('ignore', [])) 205 ignoreables = frozenset(cfg.get('ignore', []))
206 ignore_targeted = cfg.get('ignore_path_errors', {})
189 while files: 207 while files:
190 f = files.popleft() 208 f = files.popleft()
191 if cfg.get('verbose'): 209 if cfg.get('verbose'):
192 print("Validating %s" % f) 210 print("Validating %s" % f)
211 targeted_ignoreables = set(ignore_targeted.get(f.filename, set()))
212 targeted_ignoreables.update(ignoreables)
193 for c in fetch_checks(cfg): 213 for c in fetch_checks(cfg):
194 try: 214 try:
195 # http://legacy.python.org/dev/peps/pep-3155/ 215 # http://legacy.python.org/dev/peps/pep-3155/
@@ -214,7 +234,7 @@ def validate(cfg, files):
214 except AttributeError: 234 except AttributeError:
215 pass 235 pass
216 else: 236 else:
217 reports = reports - ignoreables 237 reports = reports - targeted_ignoreables
218 if not reports: 238 if not reports:
219 if cfg.get('verbose'): 239 if cfg.get('verbose'):
220 print(" Skipping check '%s', determined to only" 240 print(" Skipping check '%s', determined to only"
@@ -224,7 +244,7 @@ def validate(cfg, files):
224 print(" Running check '%s'" % check_name) 244 print(" Running check '%s'" % check_name)
225 if isinstance(c, checks.ContentCheck): 245 if isinstance(c, checks.ContentCheck):
226 for line_num, code, message in c.report_iter(f): 246 for line_num, code, message in c.report_iter(f):
227 if code in ignoreables: 247 if code in targeted_ignoreables:
228 continue 248 continue
229 if not isinstance(line_num, (float, int)): 249 if not isinstance(line_num, (float, int)):
230 line_num = "?" 250 line_num = "?"
@@ -238,7 +258,7 @@ def validate(cfg, files):
238 elif isinstance(c, checks.LineCheck): 258 elif isinstance(c, checks.LineCheck):
239 for line_num, line in enumerate(f.lines_iter(), 1): 259 for line_num, line in enumerate(f.lines_iter(), 1):
240 for code, message in c.report_iter(line): 260 for code, message in c.report_iter(line):
241 if code in ignoreables: 261 if code in targeted_ignoreables:
242 continue 262 continue
243 if cfg.get('verbose'): 263 if cfg.get('verbose'):
244 print(' - %s:%s: %s %s' 264 print(' - %s:%s: %s %s'
@@ -280,6 +300,9 @@ def main():
280 parser.add_argument("--ignore-path", action="append", default=[], 300 parser.add_argument("--ignore-path", action="append", default=[],
281 help="Ignore the given directory or file (globs" 301 help="Ignore the given directory or file (globs"
282 " are supported).", metavar='path') 302 " are supported).", metavar='path')
303 parser.add_argument("--ignore-path-errors", action="append", default=[],
304 help="Ignore the given specific errors in the"
305 " provided file.", metavar='path')
283 parser.add_argument("--default-extension", action="store", 306 parser.add_argument("--default-extension", action="store",
284 help="Default file extension to use when a file is" 307 help="Default file extension to use when a file is"
285 " found without a file extension.", 308 " found without a file extension.",
@@ -317,6 +340,16 @@ def main():
317 args['sphinx'] = cfg.pop("sphinx") 340 args['sphinx'] = cfg.pop("sphinx")
318 args['extension'].extend(cfg.pop('extension', [])) 341 args['extension'].extend(cfg.pop('extension', []))
319 args['ignore_path'].extend(cfg.pop('ignore_path', [])) 342 args['ignore_path'].extend(cfg.pop('ignore_path', []))
343
344 cfg.setdefault('ignore_path_errors', {})
345 for tmp_ignore_path_error in args.pop('ignore_path_errors', []):
346 tmp_ignores = parse_ignore_path_errors(tmp_ignore_path_error)
347 for path, ignores in six.iteritems(tmp_ignores):
348 if path in cfg['ignore_path_errors']:
349 cfg['ignore_path_errors'][path].update(ignores)
350 else:
351 cfg['ignore_path_errors'][path] = set(ignores)
352
320 args.update(cfg) 353 args.update(cfg)
321 setup_logging(args.get('verbose')) 354 setup_logging(args.get('verbose'))
322 355