doc/docchecker
author Pierre-Yves David <pierre-yves.david@octobus.net>
Sun, 21 May 2017 16:01:20 +0200
changeset 32477 20c1c2fb8106
parent 29169 c9ab5a0bc7c5
child 41006 9bfbb9fc5871
permissions -rwxr-xr-x
hidden: simplify the computation of consistency blocker For a couple of years, we now have precomputed set for all mutable phases. We can use this set restrict our search and quickly detect non-hideable children of hideable changesets. This speeds up the hidden computation. See docstring of the new function for details. This new version reuses the '_domainancestors' function to keep the computation of revealed changeset in O(len(visible)) Below are perfvolatilesets timing from two Mozilla repositories with different contents. hidden cache is disabled while obtaining them. 1) Mozilla repository with: * 400667 changesets * 35 hidden changesets (first rev-268334) * 288 visible drafts * 1 unstable changeset Before: ! visible ! wall 0.001744 comb 0.000000 user 0.000000 sys 0.000000 (best of 1563) After: ! visible ! wall 0.000742 comb 0.000000 user 0.000000 sys 0.000000 (best of 3755) The timing above include the computation of obsolete changeset: ! obsolete ! wall 0.000396 comb 0.000000 user 0.000000 sys 0.000000 (best of 6816) So adjusted time give 1.3ms before versus 0.3ms after. A 4x speedup. 2) Mozilla repository with: * 405645 changesets * 4312 hidden changesets (first rev-326004) * 264 visible drafts * 1 unstable changeset Before: ! visible ! wall 0.025476 comb 0.030000 user 0.030000 sys 0.000000 (best of 111) After ! visible ! wall 0.007703 comb 0.010000 user 0.010000 sys 0.000000 (best of 358) The timing above include the computation of obsolete changeset: ! obsolete ! wall 0.006408 comb 0.010000 user 0.010000 sys 0.000000 (best of 404) So adjusted time give 19ms before versus 1.3ms after. A 17x speedup.

#!/usr/bin/env python
#
# docchecker - look for problematic markup
#
# Copyright 2016 timeless <timeless@mozdev.org> and others
#
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.

from __future__ import absolute_import, print_function

import re
import sys

leadingline = re.compile(r'(^\s*)(\S.*)$')

checks = [
  (r""":hg:`[^`]*'[^`]*`""",
    """warning: please avoid nesting ' in :hg:`...`"""),
  (r'\w:hg:`',
    'warning: please have a space before :hg:'),
  (r"""(?:[^a-z][^'.])hg ([^,;"`]*'(?!hg)){2}""",
    '''warning: please use " instead of ' for hg ... "..."'''),
]

def check(line):
    messages = []
    for match, msg in checks:
        if re.search(match, line):
            messages.append(msg)
    if messages:
        print(line)
        for msg in messages:
            print(msg)

def work(file):
    (llead, lline) = ('', '')

    for line in file:
        # this section unwraps lines
        match = leadingline.match(line)
        if not match:
            check(lline)
            (llead, lline) = ('', '')
            continue

        lead, line = match.group(1), match.group(2)
        if (lead == llead):
            if (lline != ''):
                lline += ' ' + line
            else:
                lline = line
        else:
            check(lline)
            (llead, lline) = (lead, line)
    check(lline)

def main():
    for f in sys.argv[1:]:
        try:
            with open(f) as file:
                work(file)
        except BaseException as e:
            print("failed to process %s: %s" % (f, e))

main()