lint: Check docs/THIRDPARTY for format errors.

Signed-off-by: Anders Kaseorg <anders@zulip.com>
This commit is contained in:
Anders Kaseorg 2020-05-01 17:36:23 -07:00 committed by Tim Abbott
parent b094534319
commit 82f629091a
5 changed files with 78 additions and 3 deletions

View File

@ -68,3 +68,6 @@ importlib-resources
# Needed for using integration logo svg files as bot avatars
cairosvg
# Needed for tools/check-thirdparty
python-debian

View File

@ -164,7 +164,7 @@ cfn-lint==0.29.5 \
chardet==3.0.4 \
--hash=sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae \
--hash=sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691 \
# via requests, talon
# via python-debian, requests, talon
click==7.0 \
--hash=sha256:2335065e6395b9e67ca716de5f7526736bfa6ceead690adf616d925bdc622b13 \
--hash=sha256:5b94b49521f6456670fdb30cd82a4eca9412788a93fa6dd6df72c94d5a8ff2d7 \
@ -725,6 +725,10 @@ python-dateutil==2.8.1 \
--hash=sha256:73ebfe9dbf22e832286dafa60473e4cd239f8592f699aa5adaf10050e6e1823c \
--hash=sha256:75bb3f31ea686f1197762692a9ee6a7550b59fc6ca3a1f4b5d7e32fb98e2da2a \
# via -r requirements/common.in, arrow, botocore, hypchat, moto
python-debian==0.1.37 \
--hash=sha256:847890c158ae77f3d09bc6da10ae6cb4f2c2a5fb6d874528c6e076417d5fd333 \
--hash=sha256:ab04f535155810c46c8abf3f7d46364b67b034c49ff8690cdb510092eee56750 \
# via -r requirements/dev.in
python-digitalocean==1.15.0 \
--hash=sha256:e318fe7b866ae00820f7ecec690a9320337f88c6e645310bf92f9b491148122a \
# via -r requirements/dev.in
@ -846,7 +850,7 @@ sh==1.12.14 \
six==1.14.0 \
--hash=sha256:236bdbdce46e6e6a3d61a337c0f8b763ca1e8717c03b369e87a7ec7ce1319c0a \
--hash=sha256:8f3cd2e254d8f793e7f3d6d9df77b92252b52637291d0f0da013c76ea2724b6c \
# via -r requirements/common.in, argon2-cffi, automat, aws-sam-translator, cfn-lint, cryptography, django-bitfield, docker, ecdsa, hypchat, isodate, jsonschema, libthumbor, mock, moto, packaging, parsel, pip-tools, prompt-toolkit, protego, pyopenssl, python-dateutil, python-jose, qrcode, responses, social-auth-app-django, social-auth-core, talon, traitlets, twilio, w3lib, websocket-client, zulint, zulip
# via -r requirements/common.in, argon2-cffi, automat, aws-sam-translator, cfn-lint, cryptography, django-bitfield, docker, ecdsa, hypchat, isodate, jsonschema, libthumbor, mock, moto, packaging, parsel, pip-tools, prompt-toolkit, protego, pyopenssl, python-dateutil, python-debian, python-jose, qrcode, responses, social-auth-app-django, social-auth-core, talon, traitlets, twilio, w3lib, websocket-client, zulint, zulip
snakeviz==2.0.1 \
--hash=sha256:5e30f144edb17d875b46cb5f82bd3e67fb5018e534ecc1a94e092ef3ce932c25 \
--hash=sha256:80acc9c204aeb1e089f209a4c79bb5940dc40b6536a5184c1778a3f448634885 \

65
tools/check-thirdparty Executable file
View File

@ -0,0 +1,65 @@
#!/usr/bin/env python3
"""Check the docs/THIRDPARTY file against the DEP-5 copyright format.
https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Disclaimer: This script is not a lawyer. It cannot validate that the
claimed licenses are correct. It can only check for basic syntactic
issues.
"""
import difflib
import io
import os
import subprocess
import sys
from debian import copyright
COPYRIGHT_FILENAME = "docs/THIRDPARTY"
os.chdir(os.path.join(os.path.dirname(__file__), ".."))
status = 0
*files, empty = subprocess.check_output(
["git", "ls-files", "-z"], encoding="utf-8",
).split("\0")
assert empty == ""
files += [
"static/generated/emoji/images/emoji/unicode/ignore-this-path",
]
with open(COPYRIGHT_FILENAME) as f:
lines = list(f)
c = copyright.Copyright(lines)
if not c.header.known_format():
print(f"{COPYRIGHT_FILENAME}: Unknown header format {c.header.format}")
status = 1
defined_licenses = {
p.license.synopsis for p in c.all_license_paragraphs() if p.license.text
}
for p in c.all_files_paragraphs():
for g in p.files:
if not any(map(copyright.globs_to_re([g]).fullmatch, files)):
print(f"{COPYRIGHT_FILENAME}: No such file {g}")
status = 1
if not p.license.text and p.license.synopsis not in defined_licenses:
print(f"{COPYRIGHT_FILENAME}: Missing license text for {p.license.synopsis}")
status = 1
dumped = c.dump()
if dumped != "".join(lines):
print(f"{COPYRIGHT_FILENAME}: Changes expected:")
sys.stdout.writelines(
difflib.unified_diff(
lines,
io.StringIO(dumped).readlines(),
COPYRIGHT_FILENAME,
COPYRIGHT_FILENAME,
),
)
status = 1
sys.exit(status)

View File

@ -94,6 +94,9 @@ def run() -> None:
description="Syntactic Grep (semgrep) Code Search Tool "
"(config: ./tools/semgrep.yml)")
linter_config.external_linter('thirdparty', ['tools/check-thirdparty'],
description="Check docs/THIRDPARTY copyright file syntax")
@linter_config.lint
def custom_py() -> int:
"""Runs custom checks for python files (config: tools/linter_lib/custom_check.py)"""

View File

@ -44,4 +44,4 @@ API_FEATURE_LEVEL = 2
# historical commits sharing the same major version, in which case a
# minor version bump suffices.
PROVISION_VERSION = '81.3'
PROVISION_VERSION = '81.4'