summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
authorIvan A. Melnikov <imelnikov@griddynamics.com>2014-05-07 15:21:44 +0400
committerIvan A. Melnikov <imelnikov@griddynamics.com>2014-05-08 12:11:18 +0400
commitf986a82731b4402f6130365a13db711e4b779ef9 (patch)
treef3e3bade215b206c04b7e7a3d0f3126956630b25 /tools
parentee1e96d87d385baf3f583cabea94997b50130985 (diff)
downloadtaskflow-f986a82731b4402f6130365a13db711e4b779ef9.tar.gz
Check documentation for simple style requirements
What is checked: - lines should not be longer than 79 characters, also there are few exceptions; - no tabulation for indentation; - no trailing whitespace. Change-Id: Id5b5dff380460d1fb4ffeeb23f00864e7fc158ed
Diffstat (limited to 'tools')
-rw-r--r--tools/check_doc.py114
1 files changed, 114 insertions, 0 deletions
diff --git a/tools/check_doc.py b/tools/check_doc.py
new file mode 100644
index 0000000..04c70dc
--- /dev/null
+++ b/tools/check_doc.py
@@ -0,0 +1,114 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+# Copyright (C) 2014 Ivan Melnikov <iv at altlinux dot org>
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+
+"""Check documentation for simple style requirements.
+
+What is checked:
+ - lines should not be longer than 79 characters
+ - exception: line with no whitespace except maybe in the beginning
+ - exception: line that starts with '..' -- longer directives are allowed,
+ including footnotes
+ - no tabulation for indentation
+ - no trailing whitespace
+"""
+
+import fnmatch
+import os
+import re
+import sys
+
+
+FILE_PATTERNS = ['*.rst', '*.txt']
+MAX_LINE_LENGTH = 79
+TRAILING_WHITESPACE_REGEX = re.compile('\s$')
+STARTING_WHITESPACE_REGEX = re.compile('^(\s+)')
+
+
+def check_max_length(line):
+ if len(line) > MAX_LINE_LENGTH:
+ stripped = line.strip()
+ if not any((
+ line.startswith('..'), # this is directive
+ stripped.startswith('>>>'), # this is doctest
+ stripped.startswith('...'), # and this
+ stripped.startswith('taskflow.'),
+ ' ' not in stripped # line can't be split
+ )):
+ yield ('D001', 'Line too long')
+
+
+def check_trailing_whitespace(line):
+ if TRAILING_WHITESPACE_REGEX.search(line):
+ yield ('D002', 'Trailing whitespace')
+
+
+def check_indentation_no_tab(line):
+ match = STARTING_WHITESPACE_REGEX.search(line)
+ if match:
+ spaces = match.group(1)
+ if '\t' in spaces:
+ yield ('D003', 'Tabulation used for indentation')
+
+
+LINE_CHECKS = (check_max_length,
+ check_trailing_whitespace,
+ check_indentation_no_tab)
+
+
+def check_lines(lines):
+ for idx, line in enumerate(lines, 1):
+ line = line.rstrip('\n')
+ for check in LINE_CHECKS:
+ for code, message in check(line):
+ yield idx, code, message
+
+
+def check_files(filenames):
+ for fn in filenames:
+ with open(fn) as f:
+ for line_num, code, message in check_lines(f):
+ yield fn, line_num, code, message
+
+
+def find_files(pathes, patterns):
+ for path in pathes:
+ if os.path.isfile(path):
+ yield path
+ elif os.path.isdir(path):
+ for root, dirnames, filenames in os.walk(path):
+ for filename in filenames:
+ if any(fnmatch.fnmatch(filename, pattern)
+ for pattern in patterns):
+ yield os.path.join(root, filename)
+ else:
+ print('Invalid path: %s' % path)
+
+
+def main():
+ ok = True
+ if len(sys.argv) > 1:
+ dirs = sys.argv[1:]
+ else:
+ dirs = ['.']
+ for error in check_files(find_files(dirs, FILE_PATTERNS)):
+ ok = False
+ print('%s:%s: %s %s' % error)
+ sys.exit(0 if ok else 1)
+
+if __name__ == '__main__':
+ main()