Add doc8 files
This commit is contained in:
parent
7bfaff1b4e
commit
870b28f86e
|
@ -0,0 +1 @@
|
|||
include README.rst
|
|
@ -0,0 +1,19 @@
|
|||
====
|
||||
Doc8
|
||||
====
|
||||
|
||||
Doc8 is a *opinionated* style checker for sphinx (or other) `rst`_
|
||||
documentation.
|
||||
|
||||
QuickStart
|
||||
==========
|
||||
|
||||
::
|
||||
|
||||
pip install doc8
|
||||
|
||||
To run doc8 just invoke it against any doc directory::
|
||||
|
||||
$ doc8 coolproject/docs
|
||||
|
||||
.. _rst: http://docutils.sourceforge.net/docs/ref/rst/introduction.html
|
|
@ -0,0 +1,148 @@
|
|||
#!/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 functools
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
|
||||
from six.moves import configparser
|
||||
|
||||
|
||||
FILE_PATTERNS = ['*.rst', '*.txt']
|
||||
MAX_LINE_LENGTH = 79
|
||||
TRAILING_WHITESPACE_REGEX = re.compile('\s$')
|
||||
STARTING_WHITESPACE_REGEX = re.compile('^(\s+)')
|
||||
|
||||
|
||||
def check_max_length(max_line_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')
|
||||
|
||||
|
||||
def check_lines(lines, line_checks):
|
||||
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, line_checks):
|
||||
for fn in filenames:
|
||||
with open(fn) as f:
|
||||
for line_num, code, message in check_lines(f, line_checks):
|
||||
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 extract_config():
|
||||
filenames = [
|
||||
os.path.join(os.getcwd(), "doc8.ini"),
|
||||
os.path.join(os.getcwd(), "tox.ini"),
|
||||
os.path.join(os.getcwd(), "pep8.ini"),
|
||||
]
|
||||
parser = configparser.RawConfigParser()
|
||||
parser.read(filenames)
|
||||
cfg = {}
|
||||
try:
|
||||
cfg['max_line_length'] = parser.getint("doc8", "max_line_length")
|
||||
except (configparser.NoSectionError, configparser.NoOptionError):
|
||||
cfg['max_line_length'] = MAX_LINE_LENGTH
|
||||
try:
|
||||
ignores = parser.get("doc8", "ignore")
|
||||
except (configparser.NoSectionError, configparser.NoOptionError):
|
||||
cfg['ignore'] = set()
|
||||
else:
|
||||
ignoreables = set()
|
||||
for i in ignores.split(","):
|
||||
i = i.strip()
|
||||
if not i:
|
||||
continue
|
||||
ignoreables.add(i)
|
||||
cfg['ignore'] = ignoreables
|
||||
return cfg
|
||||
|
||||
|
||||
def main():
|
||||
ok = True
|
||||
if len(sys.argv) > 1:
|
||||
dirs = sys.argv[1:]
|
||||
else:
|
||||
dirs = ['.']
|
||||
cfg = extract_config()
|
||||
line_checks = [
|
||||
functools.partial(check_max_length, cfg['max_line_length']),
|
||||
check_trailing_whitespace,
|
||||
check_indentation_no_tab,
|
||||
]
|
||||
for error in check_files(find_files(dirs, FILE_PATTERNS), line_checks):
|
||||
if error[2] in cfg['ignore']:
|
||||
continue
|
||||
ok = False
|
||||
print('%s:%s: %s %s' % error)
|
||||
sys.exit(0 if ok else 1)
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
|
@ -0,0 +1,55 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
|
||||
# Copyright (C) 2014 Yahoo! Inc. All Rights Reserved.
|
||||
#
|
||||
# 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.
|
||||
|
||||
import os
|
||||
|
||||
from setuptools import setup
|
||||
|
||||
|
||||
def _path(fn):
|
||||
return os.path.join(os.path.dirname(__file__), fn)
|
||||
|
||||
|
||||
def _readme():
|
||||
with open(_path("README.rst"), "rb") as handle:
|
||||
return handle.read()
|
||||
|
||||
|
||||
setup(name='doc8',
|
||||
version='0.1',
|
||||
description='style checker for sphinx (or other) rst documentation.',
|
||||
url='https://github.com/harlowja/doc8',
|
||||
scripts=[
|
||||
_path(os.path.join('scripts', 'doc8')),
|
||||
],
|
||||
license="ASL 2.0",
|
||||
install_requires=[
|
||||
'six',
|
||||
],
|
||||
classifiers=[
|
||||
"Development Status :: 3 - Alpha",
|
||||
"Topic :: Utilities",
|
||||
"License :: OSI Approved :: Apache Software License",
|
||||
"Operating System :: POSIX :: Linux",
|
||||
"Programming Language :: Python",
|
||||
],
|
||||
keywords="rst docs style checking",
|
||||
long_description=_readme(),
|
||||
)
|
Loading…
Reference in New Issue