From nobody Sun Feb 8 18:49:09 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of redhat.com designates 170.10.133.124 as permitted sender) client-ip=170.10.133.124; envelope-from=libvir-list-bounces@redhat.com; helo=us-smtp-delivery-124.mimecast.com; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of redhat.com designates 170.10.133.124 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass(p=none dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1642758148; cv=none; d=zohomail.com; s=zohoarc; b=M2p0ApKM+YHtG88X7GczbH024ee2xV0A+xWOobWy3iKys6819T6gBSa5hENYnZUVMooHyT5kkbWZN0f5R5sfsLJBxpe6hAiZ7llNIXgpBVLjewW8X05Bat4qb7x/2UzMGwvJjAYngU++cnwP+hhOVG8Vg6jPihFAcBhT9z1zcas= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1642758148; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=EnLj6vz2W27gjuQyWmeJ4brxrPGNdQxUq6qXK+HNUa8=; b=kfEzNYY7WN2PU45OTf4KD6771P23AFw+8cJDoAc4lvVLtEb9gCyh7qYheo8MIRxMbWQqmy0QhU58AYRVWBvfmWblOVFt+AMdPDg9btKV1ZNynSWksqnocUoersP5rLHSviOr6ic9Td3F9BkSbL+tchCre6AQQPe8fDLJEH4PKXs= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of redhat.com designates 170.10.133.124 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by mx.zohomail.com with SMTPS id 1642758148412162.24847800495002; Fri, 21 Jan 2022 01:42:28 -0800 (PST) Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-460-3_vAE_6nNqqa1NG6tX4KNw-1; Fri, 21 Jan 2022 04:42:25 -0500 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id E890283DEB5; Fri, 21 Jan 2022 09:42:20 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.20]) by smtp.corp.redhat.com (Postfix) with ESMTPS id C320B7A225; Fri, 21 Jan 2022 09:42:20 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id 900B01806D1D; Fri, 21 Jan 2022 09:42:20 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id 20L9g1iD028061 for ; Fri, 21 Jan 2022 04:42:01 -0500 Received: by smtp.corp.redhat.com (Postfix) id 8CD906D032; Fri, 21 Jan 2022 09:42:01 +0000 (UTC) Received: from work.speedport.ip (unknown [10.39.193.100]) by smtp.corp.redhat.com (Postfix) with ESMTP id D36F94F87E; Fri, 21 Jan 2022 09:42:00 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1642758147; h=from:from:sender:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references:list-id:list-help: list-unsubscribe:list-subscribe:list-post; bh=EnLj6vz2W27gjuQyWmeJ4brxrPGNdQxUq6qXK+HNUa8=; b=N0+uD2UPzcOfe+fwqWoCpHpe0A1LCMfybh/sf078Us3+OWbo8Ij3YQM4uwoP++rfUEtYP1 g/5C5+yOqeVo98ty7YydM0oYHC60+TNVKH06PWjnodm4pZOoMYYKULhA9Ls3PQDTm+tQAJ ABDowCIPdwj8o5JvXZMMjC79u0wfnUA= X-MC-Unique: 3_vAE_6nNqqa1NG6tX4KNw-1 From: Tim Wiederhake To: libvir-list@redhat.com Subject: [libvirt PATCH v3 1/3] scripts: Check spelling Date: Fri, 21 Jan 2022 10:41:48 +0100 Message-Id: <20220121094150.15878-2-twiederh@redhat.com> In-Reply-To: <20220121094150.15878-1-twiederh@redhat.com> References: <20220121094150.15878-1-twiederh@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-loop: libvir-list@redhat.com Cc: Tim Wiederhake X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=libvir-list-bounces@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1642758150204100002 Content-Type: text/plain; charset="utf-8" This is a wrapper for codespell [1], a spell checker for source code. Codespell does not compare words to a dictionary, but rather works by checking words against a list of common typos, making it produce fewer false positives than other solutions. The script in this patch works around the lack of per-directory ignore lists and some oddities regarding capitalization in ignore lists. The ".codespellrc" file is used to coarsly filter out translation and git files, as scanning those makes up for roughly 50% of the run time otherwise. [1] (https://github.com/codespell-project/codespell/) Signed-off-by: Tim Wiederhake --- .codespellrc | 2 + scripts/check-spelling.py | 135 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 137 insertions(+) create mode 100644 .codespellrc create mode 100755 scripts/check-spelling.py diff --git a/.codespellrc b/.codespellrc new file mode 100644 index 0000000000..0c45be445b --- /dev/null +++ b/.codespellrc @@ -0,0 +1,2 @@ +[codespell] +skip =3D .git/,*.po diff --git a/scripts/check-spelling.py b/scripts/check-spelling.py new file mode 100755 index 0000000000..ce3e7d89f0 --- /dev/null +++ b/scripts/check-spelling.py @@ -0,0 +1,135 @@ +#!/usr/bin/env python3 + +import argparse +import re +import subprocess +import os + + +IGNORE_LIST =3D [ + # ignore this script + ("scripts/check-spelling.py", []), + + # 3rd-party: keycodemapdb + ("src/keycodemapdb/", []), + + # 3rd-party: VirtualBox SDK + ("src/vbox/vbox_CAPI", []), + + # 3rd-party: qemu + ("tests/qemucapabilitiesdata/caps_", []), + + # other + ("", ["msdos", "MSDOS", "wan", "WAN", "hda", "HDA", "inout"]), + ("NEWS.rst", "crashers"), + ("docs/gitdm/companies/others", "Archiv"), + ("docs/glib-adoption.rst", "preferrable"), + ("docs/js/main.js", "whats"), + ("examples/polkit/libvirt-acl.rules", ["userA", "userB", "userC"]), + ("src/libvirt-domain.c", "PTD"), + ("src/libxl/libxl_logger.c", "purposedly"), + ("src/nwfilter/nwfilter_dhcpsnoop.c", "ether"), + ("src/nwfilter/nwfilter_ebiptables_driver.c", "parm"), + ("src/nwfilter/nwfilter_learnipaddr.c", "ether"), + ("src/qemu/qemu_agent.c", "crypted"), + ("src/qemu/qemu_agent.h", "crypted"), + ("src/qemu/qemu_process.c", "wee"), + ("src/security/apparmor/libvirt-lxc", "devic"), + ("src/security/apparmor/libvirt-qemu", "readby"), + ("src/storage_file/storage_file_probe.c", "conectix"), + ("src/util/virnetdevmacvlan.c", "calld"), + ("src/util/virtpm.c", "parm"), + ("tests/qemuagenttest.c", "IST"), + ("tests/storagepoolxml2xml", "cant"), + ("tests/sysinfodata/", "sie"), + ("tests/testutils.c", "nIn"), + ("tests/vircgroupdata/ovirt-node-6.6.mounts", "hald"), + ("tests/virhostcpudata/", "sie"), + ("tools/virt-host-validate-common.c", "sie"), +] + + +def ignore(filename, linenumber, word, suggestion): + if len(word) <=3D 2: + return True + + for f, w in IGNORE_LIST: + if not filename.startswith(f): + continue + if word in w or not w: + return True + return False + + +def main(): + line_pattern =3D re.compile("^(.*):(.*): (.*) =3D=3D> (.*)$") + output_template =3D "(\"{0}\", \"{2}\"),\t# line {1}, \"{3}\"?" + + parser =3D argparse.ArgumentParser(description=3D"Check spelling") + parser.add_argument( + "dir", + help=3D"Path to source directory. " + "Defaults to parent directory of this script", + type=3Dos.path.realpath, + nargs=3D'?') + parser.add_argument( + "-i", + "--ignore", + help=3D"File to ignore. Can be specified more than once", + metavar=3D"FILE", + default=3Dlist(), + action=3D"append") + parser.add_argument( + "--ignore-untracked", + help=3D"Ignore all files not tracked by git", + action=3D"store_true") + args =3D parser.parse_args() + + if not args.dir: + args.dir =3D os.path.dirname(os.path.dirname(os.path.realpath(__fi= le__))) + + if args.ignore_untracked: + args.ignore.extend(subprocess.check_output( + ["git", "-C", args.dir, "ls-files", "--others"], + universal_newlines=3DTrue).split("\n")) + + try: + process =3D subprocess.run( + [ + "codespell", + args.dir, + "--config", + os.path.join(args.dir, ".codespellrc")], + stdout=3Dsubprocess.PIPE, + stderr=3Dsubprocess.PIPE, + universal_newlines=3DTrue) + except FileNotFoundError: + exit("error: codespell not found") + if process.returncode not in (0, 65): + exit("error: unexpected returncode %s" % process.returncode) + + if process.stderr: + exit("error: unexpected output to stderr: \"%s\"" % process.stderr) + + findings =3D 0 + for line in process.stdout.split("\n"): + line =3D line.strip().replace(args.dir, "").lstrip("/") + if not line: + continue + + match =3D line_pattern.match(line) + if not match: + exit("error: unexpected line: \"%s\"" % line) + + if match.group(1) in args.ignore or ignore(*match.groups()): + continue + + print(output_template.format(*match.groups())) + findings +=3D 1 + + if findings: + exit("error: %s spelling errors" % findings) + + +if __name__ =3D=3D "__main__": + main() --=20 2.31.1