Skip to content

Commit 808b48f

Browse files
committed
Improve documentation of Python files.
- Add `generate_changelog.py`. - Improve typing and documentation.
1 parent a979b1e commit 808b48f

9 files changed

+267
-43
lines changed

tools/add_copyright_header.py

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@
2020
# SOFTWARE. #
2121
#####################################################################################################
2222

23+
"""
24+
Add a copyright header to all files.
25+
"""
26+
2327
import datetime
2428
import re
2529
from pathlib import Path
@@ -128,15 +132,32 @@
128132

129133

130134
def count_lines(text: str) -> int:
135+
"""
136+
Count the number of lines in a string.
137+
:param text: The string to count the lines of.
138+
:return: The number of lines.
139+
"""
140+
131141
return len(text.splitlines())
132142

133143

134144
def first_n_lines(text: str, n: int) -> str:
145+
"""
146+
Get the first n lines of a string.
147+
:param text: The string to get the first n lines of.
148+
:param n: The number of lines to get.
149+
:return: The first n lines of the string.
150+
"""
151+
135152
lines = text.splitlines()
136153
return "\n".join(lines[0:n])
137154

138155

139-
def process(file: Path):
156+
def process(file: Path) -> None:
157+
"""
158+
Process the file, adding or updating the header if necessary.
159+
:param file: The file to process.
160+
"""
140161
if (
141162
file.suffix in (".cpp", ".hpp") # C++ Source / Header
142163
or file.name == "cpp.hint" # C++ Hint file
@@ -189,7 +210,12 @@ def process(file: Path):
189210
f.write(contents)
190211

191212

192-
def walk_into_directory(path: Path):
213+
def walk_into_directory(path: Path) -> None:
214+
"""
215+
Walk into the directory and process all files.
216+
:param path: The directory to walk
217+
"""
218+
193219
for subpath in path.rglob("*"):
194220
if subpath.is_file():
195221
process(subpath)

tools/benchmark.py

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@
2020
# SOFTWARE. #
2121
#####################################################################################################
2222

23+
"""
24+
Benchmarking script for Steppable executables.
25+
"""
26+
2327
import argparse
2428
import random
2529
import subprocess
@@ -32,7 +36,7 @@
3236
BUILD_PATH_DEFAULT = "build"
3337

3438
FUNCTIONS = {
35-
"abs": lambda x, y: abs(x),
39+
"abs": lambda x, _: abs(x),
3640
"add": lambda x, y: x + y,
3741
"comparison": lambda x, y: x > y,
3842
"division": lambda x, y: x / y,
@@ -48,6 +52,14 @@ def _benchmark_function(
4852
input_1: int,
4953
input_2: int,
5054
) -> float:
55+
"""
56+
Benchmark a Python function.
57+
:param function: The function to benchmark.
58+
:param input_1: The first input.
59+
:param input_2: The second input.
60+
:return: The time taken to run the function.
61+
"""
62+
5163
start = time.time()
5264
try:
5365
function(input_1, input_2)
@@ -65,6 +77,16 @@ def _benchmark(
6577
verbose: bool = False,
6678
timeout: int = 10,
6779
) -> float:
80+
"""
81+
Benchmark a system executable.
82+
:param cmd: The executable to run.
83+
:param input_str1: The first input.
84+
:param input_str2: The second input.
85+
:param verbose: Whether to print the output.
86+
:param timeout: The timeout for the process.
87+
:return: The time taken to run the executable.
88+
"""
89+
6890
start = time.time()
6991
try:
7092
result = subprocess.run(
@@ -92,6 +114,16 @@ def _benchmark(
92114
def benchmark(
93115
cmd: str, inputs: List[str], limit: int, verbose: bool = False, timeout: int = 10
94116
) -> Tuple[List[float], List[float], bool]:
117+
"""
118+
Benchmark a Steppable executable.
119+
:param cmd: The executable to run.
120+
:param inputs: The inputs to run the executable on.
121+
:param limit: The limit for the inputs.
122+
:param verbose: Whether to print the output.
123+
:param timeout: The timeout for the process.
124+
:return: The time taken to run the executable.
125+
"""
126+
95127
random_number = random.randint(0, limit)
96128
random_number_str = str(random_number)
97129
time_needed = []
@@ -114,7 +146,11 @@ def benchmark(
114146
return time_needed, time_needed_system, system_available
115147

116148

117-
def main():
149+
def main() -> None:
150+
"""
151+
Main function for the benchmarking script.
152+
"""
153+
118154
parser = argparse.ArgumentParser(
119155
prog="benchmark.py",
120156
description="Performs benchmarks on Steppable executables",

tools/building/compiler_detection.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ def get_identification(compiler_path: Path, compiler_type: int) -> str:
7878
def register_compiler(path: Path) -> None:
7979
"""
8080
Adds the compiler path to the status.json file in the build directory. This is used to cache the compiler path.
81+
:param path: The path to the compiler executable.
8182
"""
8283
with open(BUILD_DIR / "status.json", "w") as f:
8384
json.dump({"compiler": str(path)}, f)

tools/building/project.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -338,6 +338,8 @@ def add_component(self, group: str, name: str) -> None:
338338
"""
339339
Adds a component to the project. Components are the building blocks of the project, and are linked together to
340340
build the final executables.
341+
:param group: The group to which the component belongs.
342+
:param name: The name of the component.
341343
"""
342344

343345
files = [

tools/generate_changelog.py

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import subprocess
2+
from typing import List
3+
4+
5+
def get_commits() -> List[str]:
6+
"""
7+
Get the commits between the main and develop branches.
8+
:return: A list of commits.
9+
"""
10+
11+
# git log main..develop --pretty="%B" --reverse
12+
try:
13+
output = subprocess.check_output(
14+
["git", "log", "main..develop", "--pretty=%B#", "--reverse"],
15+
universal_newlines=True,
16+
)
17+
except subprocess.CalledProcessError as e:
18+
print(f"ERROR: {e}")
19+
return []
20+
except FileNotFoundError:
21+
print(f"ERROR: Git not found on the system.")
22+
return []
23+
24+
# Do some processing, ie. split the output into a list of commits
25+
lines = output.split("\n#")
26+
commits = [line.strip() for line in lines if line.strip()]
27+
28+
return commits
29+
30+
31+
def process_changelog() -> None:
32+
"""
33+
Generate a changelog from the commits between the main and develop branches.
34+
"""
35+
36+
print("INFO: Generating changelog")
37+
commits = get_commits()
38+
39+
for commit in commits:
40+
lines = commit.split("\n")
41+
print(f"- **{lines[0]}**")
42+
lines.pop(0)
43+
44+
for line in lines:
45+
print(f" {line}")
46+
47+
48+
if __name__ == "__main__":
49+
process_changelog()

tools/new_component.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,10 @@
9292

9393

9494
def show_help() -> None:
95+
"""
96+
Show the help text for new contributors.
97+
"""
98+
9599
for idx, part in enumerate(HELP):
96100
print(part)
97101
if idx != (len(HELP) - 1):
@@ -107,6 +111,11 @@ def show_help() -> None:
107111

108112

109113
def validate_name(name: str) -> bool:
114+
"""
115+
Validate the name of the component. It cannot contain restricted characters.
116+
:param name: The name of the component.
117+
:return: True if the name is valid, False otherwise.
118+
"""
110119
if (
111120
"*" in name
112121
or '"' in name
@@ -124,6 +133,12 @@ def validate_name(name: str) -> bool:
124133

125134

126135
def make_dir(name: str, date: str, author: str) -> None:
136+
"""
137+
Create a new directory for the component.
138+
:param name: The name of the component.
139+
:param date: The date of creation.
140+
:param author: The author of the component.
141+
"""
127142
path: Path = SRC_DIR / name
128143

129144
if not path.is_dir():
@@ -305,6 +320,10 @@ def make_dir(name: str, date: str, author: str) -> None:
305320

306321

307322
def patch_cmakelists(name: str) -> None:
323+
"""
324+
Patch the CMakeLists.txt file to include the new component.
325+
:param name: The name of the component.
326+
"""
308327
with open(PROJECT_PATH / "CMakeLists.txt") as f:
309328
contents = f.read()
310329

@@ -318,7 +337,11 @@ def patch_cmakelists(name: str) -> None:
318337
def ordinal(n: int) -> str:
319338
"""
320339
Get the ordinal numeral for a given number n.
340+
:param n: The number.
341+
:return: The ordinal numeral.
321342
"""
343+
344+
# Credits to https://stackoverflow.com/a/20007730/14868780 for this crazy one-liner.
322345
return f"{n:d}{'tsnrhtdd'[(n // 10 % 10 != 1) * (n % 10 < 4) * n % 10::4]}"
323346

324347

@@ -328,6 +351,10 @@ def ordinal(n: int) -> str:
328351

329352

330353
def main():
354+
"""
355+
Main function for the new component wizard.
356+
"""
357+
331358
print(WELCOME_STRING)
332359
selection = getch().upper()
333360

tools/patch_compile_commands.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ def get_compile_commands() -> Path:
7171
raise RuntimeError("Cannot get the CMake build directory")
7272

7373

74-
def patch():
74+
def patch() -> None:
7575
"""Remove the NO_MAIN definition in compile_commands.json."""
7676

7777
try:

0 commit comments

Comments
 (0)