import datetime
import os
import sys
from typing import List, Tuple
FOLDERS = ["src", "etc", "examples", "docs/src"]
FILES = ["build.rs", "Cargo.toml"]
MINIMUM_LINES = 2
MAXIMUM_LINES = 50
MARKERS = ["Trivet", "Copyright"]
COMMENT_STARTS = ["#", "//"]
COPYRIGHT = """\
Trivet
Copyright (c) YYYY by Stacy Prowell. All rights reserved.
https://gitlab.com/binary-tools/trivet
"""
def extract_comment_block(
lines: List[str], lno: int, start: str
) -> Tuple[List[str], int, bool]:
block = []
marks = set(mark.lower() for mark in MARKERS)
found_marks = set()
while lines[lno].startswith(start):
line = lines[lno].lower()
block.append(lines[lno])
lno += 1
for marker in marks:
if marker in line:
found_marks.add(marker)
marks -= found_marks
if lno < MAXIMUM_LINES and len(block) >= MINIMUM_LINES and len(marks) == 0:
newblock = []
for line in COPYRIGHT.splitlines(True):
line = line.replace("YYYY", str(datetime.datetime.now().year))
line = f"{start} {line}".strip() + "\n"
newblock.append(line)
return (newblock, lno, True)
return (block, lno, False)
def process_file(file: str) -> bool:
newlines = []
found_marker = False
try:
with open(file, "rt", encoding="utf-8") as file_in:
lines = file_in.readlines()
lno = 0
while lno < len(lines):
if not found_marker and lno < MAXIMUM_LINES:
hasstart = ""
for start in COMMENT_STARTS:
if lines[lno].startswith(start):
hasstart = start
if len(hasstart) == 0:
newlines.append(lines[lno])
lno += 1
else:
(block, lno, found_marker) = extract_comment_block(
lines, lno, hasstart
)
newlines.extend(block)
else:
newlines.append(lines[lno])
lno += 1
if found_marker:
with open(file, "wt", encoding="utf-8") as file_in:
for line in newlines:
file_in.write(line)
except UnicodeDecodeError:
print("Not readable text file... ", end="")
except FileNotFoundError:
print(f"Did not find '{file}'... ", end="")
except IOError:
print("Unexpected error:", sys.exc_info()[0])
return found_marker
def main() -> None:
print("This will update the comment block in all files under these folders:")
for folder in FOLDERS:
print(f" * {folder}")
print()
print("The following additional files will be updated, also:")
for filename in FILES:
print(f" * {filename}")
print()
print("No backups are made. Please commit or stash all work before continuing!")
print()
proceed = input("Proceed? (y/N) ")
if proceed.startswith("y"):
for filename in FILES:
print(f"Processing file {filename}...", end="")
found_marker = process_file(filename)
if found_marker:
print("Updated")
else:
print("Ignored")
for folder in FOLDERS:
for root, _dirs, files in os.walk(folder):
for basename in files:
filename = os.path.join(root, basename)
print(f"Processing file {filename}... ", end="")
found_marker = process_file(filename)
if found_marker:
print("Updated")
else:
print("Ignored")
if __name__ == "__main__":
main()