view doc/docchecker @ 44893:95c832849955

setup: require that Python has TLS 1.1 or TLS 1.2 This ensures that Mercurial never downgrades the minimum TLS version from TLS 1.1+ to TLS 1.0+ and enables us to remove that compatibility code. It is reasonable to expect that distributions having Python 2.7.9+ or having backported modern features to the ssl module (which we require) have a OpenSSL version supporting TLS 1.1 or TLS 1.2, as this is the main reason why distributions would want to backport these features. TLS 1.1 and TLS 1.2 are often either both enabled or both not enabled. However, both can be disabled independently, at least on current Python / OpenSSL versions. For the record, I contacted the CPython developers to remark that unconditionally defining ssl.PROTOCOL_TLSv1_1 / ssl.PROTOCOL_TLSv1_2 is problematic: https://github.com/python/cpython/commit/6e8cda91d92da72800d891b2fc2073ecbc134d98#r39569316
author Manuel Jacob <me@manueljacob.de>
date Sat, 30 May 2020 23:42:19 +0200
parents 47ef023d0165
children c102b704edb5
line wrap: on
line source

#!/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 os
import re
import sys

try:
    import msvcrt

    msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY)
    msvcrt.setmode(sys.stderr.fileno(), os.O_BINARY)
except ImportError:
    pass

stdout = getattr(sys.stdout, 'buffer', sys.stdout)

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

checks = [
    (
        br""":hg:`[^`]*'[^`]*`""",
        b"""warning: please avoid nesting ' in :hg:`...`""",
    ),
    (br'\w:hg:`', b'warning: please have a space before :hg:'),
    (
        br"""(?:[^a-z][^'.])hg ([^,;"`]*'(?!hg)){2}""",
        b'''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:
        stdout.write(b'%s\n' % line)
        for msg in messages:
            stdout.write(b'%s\n' % msg)


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

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

        lead, line = match.group(1), match.group(2)
        if lead == llead:
            if lline != b'':
                lline += b' ' + 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, 'rb') as file:
                work(file)
        except BaseException as e:
            sys.stdout.write(r"failed to process %s: %s\n" % (f, e))


main()