Skip to content

Commit bc8e401

Browse files
committed
feat: added scripts
1 parent 5eb83cf commit bc8e401

File tree

6 files changed

+745
-0
lines changed

6 files changed

+745
-0
lines changed

scripts/bump_year/main.py

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
#!/usr/bin/env python3
2+
"""
3+
bump_year.py
4+
5+
A script to bump the year part of the version in pyproject.toml.
6+
Resets major and minor versions to 0 when the year is incremented.
7+
8+
Usage:
9+
bump_year.py
10+
"""
11+
12+
import datetime
13+
import toml
14+
import sys
15+
16+
17+
def bump_year() -> None:
18+
"""
19+
Bumps the year in pyproject.toml and resets major and minor versions to 0.
20+
"""
21+
current_year = datetime.datetime.now().year
22+
pyproject_path = "pyproject.toml"
23+
24+
try:
25+
with open(pyproject_path, "r", encoding="utf-8") as file:
26+
data = toml.load(file)
27+
except FileNotFoundError:
28+
print(f"Error: {pyproject_path} not found.")
29+
sys.exit(1)
30+
except toml.TomlDecodeError:
31+
print(f"Error: Failed to parse {pyproject_path}.")
32+
sys.exit(1)
33+
34+
try:
35+
version = data["tool"]["poetry"]["version"]
36+
year, major, minor = version.split(".")
37+
except (KeyError, ValueError):
38+
print("Error: Version format is incorrect in pyproject.toml.")
39+
sys.exit(1)
40+
41+
if int(year) < current_year:
42+
print(f"Updating year from {year} to {current_year}")
43+
year = str(current_year)
44+
major = "0"
45+
minor = "0"
46+
new_version = f"{year}.{major}.{minor}"
47+
data["tool"]["poetry"]["version"] = new_version
48+
try:
49+
with open(pyproject_path, "w", encoding="utf-8") as file:
50+
toml.dump(data, file)
51+
print(f"Year bumped to {new_version}")
52+
except Exception as e:
53+
print(f"Error writing to {pyproject_path}: {e}")
54+
sys.exit(1)
55+
else:
56+
print("Year is up-to-date. No need to bump.")
57+
58+
59+
def main() -> None:
60+
"""
61+
Main function to execute the year bumping process.
62+
"""
63+
bump_year()
64+
65+
66+
if __name__ == "__main__":
67+
main()
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
#!/usr/bin/env python3
2+
"""
3+
commit_msg_version_bump.py
4+
5+
A script to bump the version in pyproject.toml based on commit message keywords.
6+
Handles major, minor, and patch releases.
7+
8+
Usage:
9+
commit_msg_version_bump.py <commit_msg_file>
10+
"""
11+
12+
import sys
13+
import re
14+
import subprocess
15+
import toml
16+
17+
DEBUG = False
18+
19+
20+
def bump_version(part: str) -> None:
21+
"""
22+
Bumps the specified part of the version using bump2version and commits the change.
23+
24+
Args:
25+
part (str): The part of the version to bump ('major', 'minor', 'patch').
26+
27+
Raises:
28+
subprocess.CalledProcessError: If bump2version or git commands fail.
29+
"""
30+
try:
31+
subprocess.run(["bump2version", part], check=True)
32+
print(f"Successfully bumped the {part} version.")
33+
except subprocess.CalledProcessError:
34+
print(f"Failed to bump the {part} version.")
35+
sys.exit(1)
36+
37+
# Retrieve the new version from pyproject.toml
38+
new_version = get_new_version()
39+
40+
if DEBUG:
41+
print(f"Target version {new_version}")
42+
43+
# Stage the changed pyproject.toml
44+
try:
45+
subprocess.run(["git", "add", "pyproject.toml"], check=True)
46+
except subprocess.CalledProcessError:
47+
print("Failed to stage pyproject.toml.")
48+
sys.exit(1)
49+
50+
# Commit the change
51+
try:
52+
subprocess.run(["git", "commit", "-m", f"Bump {part} version to {new_version}"], check=True)
53+
print(f"Committed the bumped {part} version to {new_version}.")
54+
except subprocess.CalledProcessError:
55+
print(f"Failed to commit the bumped {part} version.")
56+
sys.exit(1)
57+
58+
59+
def get_new_version() -> str:
60+
"""
61+
Retrieves the new version from pyproject.toml.
62+
63+
Returns:
64+
str: The new version string.
65+
66+
Raises:
67+
SystemExit: If the version cannot be retrieved.
68+
"""
69+
pyproject_path = "pyproject.toml"
70+
try:
71+
with open(pyproject_path, "r", encoding="utf-8") as file:
72+
data = toml.load(file)
73+
version = data["tool"]["poetry"]["version"]
74+
return version
75+
except (FileNotFoundError, KeyError, ValueError, toml.TomlDecodeError):
76+
print(f"Error: Unable to retrieve the version from {pyproject_path}.")
77+
sys.exit(1)
78+
79+
80+
def main() -> None:
81+
"""
82+
Main function to parse the commit message and perform version bumping.
83+
"""
84+
if DEBUG:
85+
print(f"Sys: {sys}")
86+
87+
if len(sys.argv) < 2:
88+
print("Usage: commit_msg_version_bump.py <commit_msg_file>")
89+
sys.exit(1)
90+
91+
commit_msg_file = sys.argv[1]
92+
93+
try:
94+
with open(commit_msg_file, "r", encoding="utf-8") as file:
95+
commit_msg = file.read().strip()
96+
except FileNotFoundError:
97+
print(f"Commit message file not found: {commit_msg_file}")
98+
sys.exit(1)
99+
100+
if DEBUG:
101+
print(f"Commit message file: {commit_msg_file}")
102+
print(f"commit_msg: {commit_msg}")
103+
104+
# Define patterns for candidate types
105+
major_pattern = re.compile(r"\bmajor candidate\b", re.IGNORECASE)
106+
minor_pattern = re.compile(r"\bminor candidate\b", re.IGNORECASE)
107+
patch_pattern = re.compile(r"\bpatch candidate\b", re.IGNORECASE)
108+
109+
if major_pattern.search(commit_msg):
110+
print("Major candidate release detected. Bumping major version...")
111+
bump_version("major")
112+
elif minor_pattern.search(commit_msg):
113+
print("Minor candidate release detected. Bumping minor version...")
114+
bump_version("minor")
115+
elif patch_pattern.search(commit_msg):
116+
print("Patch candidate release detected. Bumping patch version...")
117+
bump_version("patch")
118+
else:
119+
print("No version bump detected in commit message.")
120+
121+
122+
if __name__ == "__main__":
123+
main()

scripts/format_yaml/main.py

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
# scripts/validate_docker_compose.py
2+
import re
3+
import sys
4+
import os
5+
6+
DEBUG = False
7+
8+
9+
def format_yaml_file(file_path):
10+
"""
11+
Format a yaml file
12+
13+
Args:
14+
:param file_path:
15+
"""
16+
with open(file_path, "r", encoding="utf-8") as f:
17+
content = f.read()
18+
19+
lines = content.splitlines()
20+
21+
if not lines or not lines[0].strip().startswith("---"):
22+
lines.insert(0, "---")
23+
print(f"[FORMAT] Added '---' at the beginning of {file_path}.")
24+
25+
for i, line in enumerate(lines):
26+
original_line = line
27+
line = re.sub(r"\[\s+", "[", line)
28+
line = re.sub(r"\s+]", "]", line)
29+
line = re.sub(r"\(\s+", "(", line)
30+
line = re.sub(r"\s+\)", ")", line)
31+
if line != original_line:
32+
lines[i] = line
33+
print(f"[FORMAT] Removed extra spaces inside brackets in line {i+1} of {file_path}.")
34+
35+
inside_run_block = False
36+
new_lines = []
37+
for i, line in enumerate(lines):
38+
if re.match(r"^run:\s*\|", line):
39+
inside_run_block = True
40+
new_lines.append(line)
41+
continue
42+
if inside_run_block and re.match(r"^\S", line):
43+
inside_run_block = False
44+
45+
if inside_run_block and len(line) > 120:
46+
split_pos = line.rfind(" ", 0, 120)
47+
if split_pos != -1:
48+
split_line1 = line[:split_pos]
49+
split_line2 = " " + line[split_pos + 1 :].lstrip()
50+
new_lines.append(split_line1)
51+
new_lines.append(split_line2)
52+
print(f"[FORMAT] Split long line in 'run' block at line {i+1} of {file_path}.")
53+
continue
54+
if not split_pos != -1:
55+
split_line1 = line[:120]
56+
split_line2 = " " + line[120:].lstrip()
57+
new_lines.append(split_line1)
58+
new_lines.append(split_line2)
59+
print(f"[FORMAT] Split long line in 'run' block at line {i+1} of {file_path}.")
60+
continue
61+
62+
new_lines.append(line)
63+
64+
formatted_content = "\n".join(lines) + "\n"
65+
66+
with open(file_path, "w", newline="\n", encoding="utf-8") as f:
67+
f.write(formatted_content)
68+
69+
print(f"[FORMAT] Formatted {file_path} with LF line endings.")
70+
sys.exit(0)
71+
72+
73+
def main():
74+
"""Main void function to format yaml files."""
75+
76+
if len(sys.argv) < 2:
77+
print("[ERROR] Incorrect usage. Must specify at least one file.")
78+
sys.exit(1)
79+
80+
files_to_validate = sys.argv[1:]
81+
for file in files_to_validate:
82+
file_path = os.path.abspath(file)
83+
if os.path.isfile(file_path):
84+
format_yaml_file(file_path)
85+
else:
86+
print(f"[ERROR] File {file_path} does not exist.")
87+
sys.exit(1)
88+
89+
print("[OK] All checks passed successfully.")
90+
sys.exit(0)
91+
92+
93+
if __name__ == "__main__":
94+
if sys.stdout.encoding.lower() != "utf-8":
95+
try:
96+
sys.stdout.reconfigure(encoding="utf-8")
97+
except AttributeError:
98+
import io
99+
100+
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding="utf-8")
101+
main()

scripts/format_yml/main.py

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
# scripts/validate_docker_compose.py
2+
import re
3+
import sys
4+
import os
5+
6+
DEBUG = False
7+
8+
9+
def format_yml_file(file_path):
10+
"""
11+
Function to format yml files
12+
13+
Args:
14+
file_path (str):
15+
"""
16+
with open(file_path, "r", encoding="utf-8") as f:
17+
content = f.read()
18+
19+
lines = content.splitlines()
20+
new_lines = []
21+
22+
if not lines or not lines[0].strip().startswith("---"):
23+
lines.insert(0, "---")
24+
print(f"[FORMAT] Added '---' at the beginning of {file_path}.")
25+
26+
for i, line in enumerate(lines):
27+
original_line = line
28+
line = re.sub(r"\[\s+", "[", line)
29+
line = re.sub(r"\s+]", "]", line)
30+
line = re.sub(r"\(\s+", "(", line)
31+
line = re.sub(r"\s+\)", ")", line)
32+
if line != original_line:
33+
lines[i] = line
34+
print(f"[FORMAT] Removed extra spaces inside brackets in line {i+1} of {file_path}.")
35+
36+
for i, line in enumerate(lines, start=1):
37+
current_indent = len(line) - len(line.lstrip(" "))
38+
39+
while len(line) > 120:
40+
split_pos = line.rfind(" ", 0, 120)
41+
if split_pos != -1:
42+
split_line1 = line[:split_pos] + " \\"
43+
split_line2 = " " * current_indent + " " + line[split_pos + 1 :].lstrip()
44+
new_lines.append(split_line1)
45+
new_lines.append(split_line2)
46+
print(f"[FORMAT] Split long line at line {i} in {file_path}.")
47+
continue
48+
if not split_pos != -1:
49+
split_line1 = line[:120] + " \\"
50+
split_line2 = " " * current_indent + " " + line[120 + 1 :].lstrip()
51+
new_lines.append(split_line1)
52+
new_lines.append(split_line2)
53+
print(f"[FORMAT] Force split long line at line {i} in {file_path}.")
54+
continue
55+
56+
new_lines.append(line)
57+
58+
formatted_content = "\n".join(new_lines) + "\n"
59+
60+
with open(file_path, "w", newline="\n", encoding="utf-8") as f:
61+
f.write(formatted_content)
62+
63+
print(f"[FORMAT] Formatted {file_path} with LF line endings.")
64+
sys.exit(0)
65+
66+
67+
def main():
68+
"""Main void function to format yml files."""
69+
70+
if len(sys.argv) < 2:
71+
print("[ERROR] Incorrect usage. Must specify at least one file.")
72+
sys.exit(1)
73+
74+
files_to_validate = sys.argv[1:]
75+
for file in files_to_validate:
76+
file_path = os.path.abspath(file)
77+
if os.path.isfile(file_path):
78+
format_yml_file(file_path)
79+
else:
80+
print(f"[ERROR] File {file_path} does not exist.")
81+
sys.exit(1)
82+
83+
print("[OK] All checks passed successfully.")
84+
sys.exit(0)
85+
86+
87+
if __name__ == "__main__":
88+
main()

0 commit comments

Comments
 (0)