Rename artschedrov.yml to artschedrov.yaml
[rms-support-letter.git] / check-signatures-format.py
blob75ec7ea4898f3bad3eab1074bdf0d39bf81d0ef1
1 import json
2 import os
3 import re
6 ok = True
8 def report(arg):
9 global ok
10 ok = False
11 print(arg)
14 for file_name in sorted(os.listdir("_data/signed")):
15 if not file_name.endswith(".yaml"):
16 report(f"{file_name} has invalid extension: expected .yaml.")
18 if " " in file_name:
19 report(f"{file_name} file name contains spaces. Please remove them.")
21 if any(c.lower() not in "abcdefghijklmnopqrstuvwxyz0123456789_-. " for c in file_name):
22 report(f"{file_name} file name contains special characters, which may render the file unusable for Windows users. Please remove these characters.")
24 with open(f"_data/signed/{file_name}") as f:
25 contents = f.read().replace("\r", "")
27 if "\n\n" in contents.rstrip("\n") or contents.startswith("\n"):
28 report(f"{file_name} contains empty lines. Please remove them.")
30 if contents.endswith("\n\n\n"):
31 report(f"{file_name} contains too many trailing empty lines. Please remove them.")
33 existing_keys = {}
34 for i, line in enumerate(contents.split("\n")):
35 if not line:
36 continue
37 if line.strip() == "":
38 report(f"{file_name} has an empty line {i + 1} with whitespace. Please remove this line.")
39 continue
40 if line != line.rstrip():
41 report(f"{file_name} has excess whitespace at the end of line {i + 1}.")
42 if line != line.lstrip():
43 report(f"{file_name} has excess whitespace at the beginning of line {i + 1}.")
44 line = line.strip()
46 if ":" in line:
47 key = line[:line.index(":")]
48 value = line[line.index(":") + 1:]
49 if key.strip() == "" or any(c.lower() not in "abcdefghijklmnopqrstuvwxyz" for c in key):
50 key = None
51 value = line
52 else:
53 key = None
54 value = line
56 if key is None:
57 report(f"{file_name} has line {i + 1} which does not seem to specify a key, such as 'name:' or 'link:'. Please prepend the line with key or remove the line entirely.")
58 continue
60 if key != key.strip():
61 report(f"{file_name} contains a space between the key '{key}' and the colon, please remove it.")
62 key = key.strip()
64 if key != key.lower():
65 report(f"{file_name} contains a non-lowercase key {key} on line {i + 1}. Please convert it to lowercase.")
66 key = key.lower()
68 if not value.startswith(" "):
69 report(f"A space is missing after '{key}:' in {file_name} on line {i + 1}. Please add it.")
70 value = value[1:]
71 if value != value.strip():
72 report(f"{file_name} contains too many spaces after '{key}:' on line {i + 1}, please keep exactly one space.")
73 value = value.strip()
74 if value == "":
75 report(f"{file_name} contains an empty '{key}:' on line {i + 1}, please fix this.")
76 continue
78 if value.count("*") >= 2:
79 report(f"{file_name} contains an asterisk on line {i + 1}. The signatures are not rendered as Markdown, so formatting won't work. Please remove the asterisk.")
81 if key.lower() in existing_keys:
82 report(f"{file_name} contains duplicate key '{key}'.")
83 existing_keys[key.lower()] = i
85 if key == "name":
86 if any(c.strip() == "" and c != " " for c in value):
87 report(f"{file_name} contains an unexpected special whitespace character on line {i + 1}. Please replace it with a space.")
88 if len(" ".join(value.split())) < len(value):
89 report(f"{file_name} contains double space on line {i + 1}. Please keep a single space.")
90 if ": " in value and (value[0] != "\"" or value[-1] != "\""):
91 report(f"{file_name} contains a colon followed by a space (': ') in the name on line {i + 1}. This will cause the parser to parse the file incorrectly. Please wrap the name in double quotes.")
92 elif value.replace(" ", "").startswith("name"):
93 report(f"The name in {file_name} starts with 'name' on line {i + 1}. This may indicate a placeholder.")
94 if value[0] == "\"" and value[-1] == "\"":
95 try:
96 value = json.loads(value)
97 except Exception:
98 report(f"{file_name} contains an incorrectly encoded name on line {i + 1}. Please make sure the quoting is correct.")
99 elif key == "link":
100 if value[0] == "\"" and value[-1] == "\"":
101 try:
102 value = json.loads(value)
103 except Exception:
104 report(f"{file_name} contains an incorrectly encoded link on line {i + 1}. Please make sure the quoting is correct.")
105 if any(c.strip() == "" for c in value):
106 report(f"{file_name} contains unexpected whitespace on line {i + 1}. Please remove whitespace from the link.")
107 if value.startswith("mailto:"):
108 if "@" not in value:
109 report(f"{file_name} uses mailto: on line {i + 1}, but the part that follows doesn't look like e-mail and does not contain '@' character. Please fix the address.")
110 elif "://" in value:
111 protocol = value.split("://")[0]
112 if protocol not in ("http", "https"):
113 report(f"{file_name} uses a strange protocol '{protocol}' on line {i + 1}. Please use https:// or http://.")
114 elif "@" in value and not value.startswith("mailto:"):
115 report(f"{file_name} seems to use a e-mail in a link on line {i + 1}. Please add 'mailto:' before the e-mail.")
116 elif value == "/#":
117 pass
118 else:
119 report(f"{file_name} doesn't specify any link protocol on line {i + 1}. Please add https:// or http://.")
120 else:
121 report(f"{file_name} contains an unrecognized key {key} on line {i + 1}. Only 'name:' and 'link:' are supported.")
123 if "name" not in existing_keys:
124 report(f"{file_name} doesn't contain a name. Please specify your name or your alias.")
125 if "link" not in existing_keys:
126 report(f"{file_name} doesn't contain a link. Please specify a link to your online profile, e.g. on GitHub. If you really don't have a link, use /#")
127 if "name" in existing_keys and "link" in existing_keys and (existing_keys["name"] != 0 or existing_keys["link"] != 1):
128 report(f"{file_name} incorrectly orders name and link. Please put the name on the first line and the link on the second line.")
131 if not ok:
132 raise SystemExit(1)