summaryrefslogtreecommitdiff
path: root/archived/projt-launcher/tools
diff options
context:
space:
mode:
Diffstat (limited to 'archived/projt-launcher/tools')
-rwxr-xr-xarchived/projt-launcher/tools/generate_todo_report.py194
-rw-r--r--archived/projt-launcher/tools/get_commits.py37
2 files changed, 231 insertions, 0 deletions
diff --git a/archived/projt-launcher/tools/generate_todo_report.py b/archived/projt-launcher/tools/generate_todo_report.py
new file mode 100755
index 0000000000..6fc6f04b94
--- /dev/null
+++ b/archived/projt-launcher/tools/generate_todo_report.py
@@ -0,0 +1,194 @@
+#!/usr/bin/env python3
+"""
+Scan repository for TODO/FIXME comments and generate a Markdown report.
+
+Usage: python tools/generate_todo_report.py [--exclude-dir dir1,dir2] [--no-default-excludes]
+Produces: docs/TODO_FIXME_REPORT.md
+"""
+import argparse
+import os
+import re
+import sys
+from pathlib import Path
+
+SCRIPT_DIR = Path(__file__).resolve().parent
+ROOT = None
+
+DEFAULT_EXCLUDED_DIRS = {
+ '.git',
+ 'build',
+ 'qt',
+ 'toolchain',
+ 'ptinstaller',
+ 'docs',
+ 'tools',
+ 'gamemode',
+ 'libpng',
+ 'zlib',
+ 'quazip',
+ 'node_modules',
+ 'tomlplusplus',
+ 'json',
+ 'libqrencode',
+ 'extra-cmake-modules',
+ '.gitignore',
+ '.github',
+ 'cmark',
+ 'flatpak',
+ 'bzip2',
+ 'ci',
+}
+
+PATTERN = re.compile(r"\b(TODO|FIXME)\b", re.IGNORECASE)
+
+def is_text_file(path: Path) -> bool:
+ try:
+ with open(path, 'rb') as f:
+ chunk = f.read(4096)
+ if b"\0" in chunk:
+ return False
+ except Exception:
+ return False
+ return True
+
+def classify(text: str) -> str:
+ t = text.lower()
+ hints_complex = [
+ 'design', 'refactor', 'race', 'concurrent', 'abort', 'retry', 'performance',
+ 'memory', 'security', 'validate', 'schema', 'generic', 'nuke', 'inefficient',
+ 'algorithm', 'thread', 'blocking', 'async', 'validate', 'jwt', 'schema', 'hack'
+ ]
+ hints_trivial = ['typo', 'wrap', 'link', 'format', 'docs', 'documentation', 'spell', 'grammar', 'rename', 'cleanup', 'whitespace']
+ if any(h in t for h in hints_trivial):
+ return 'trivial'
+ if any(h in t for h in hints_complex):
+ return 'complex'
+ # Context-sensitive keyword matching for implementable items
+ implementable_keywords = ['should', 'maybe', 'add', 'implement', 'todo:', 'need', 'missing', 'want', 'consider', 'allow', 'support', 'fixme', 'refactor', 'update', 'remove', 'bug']
+ if any(k in t for k in implementable_keywords):
+ return 'implementable'
+ return 'unknown'
+
+def scan(root: Path, excluded_dirs):
+ results = []
+
+ for p in root.rglob('*'):
+ # Skip if any parent directory is in the excluded list
+ if any(part in excluded_dirs for part in p.parts):
+ continue
+
+ if p.is_dir():
+ continue
+
+ if p.suffix in {'.patch', '.diff'}:
+ continue
+
+ if not is_text_file(p):
+ continue
+
+ try:
+ text = p.read_text(encoding='utf-8')
+ except Exception:
+ try:
+ text = p.read_text(encoding='latin-1')
+ except Exception:
+ continue
+
+ lines = text.splitlines()
+ for i, line in enumerate(lines, start=1):
+ if PATTERN.search(line):
+ before = '\n'.join(lines[max(0, i-3):i-1])
+ after = '\n'.join(lines[i:i+2])
+ whole = '\n'.join(lines[max(0, i-3):min(len(lines), i+2)])
+ tag = PATTERN.search(line).group(1)
+ cls = classify(line + ' ' + whole)
+ results.append({
+ 'path': str(p.relative_to(root)),
+ 'line': i,
+ 'tag': tag,
+ 'text': line.strip(),
+ 'context': whole,
+ 'classification': cls,
+ })
+ return results
+
+def generate_md(results, out_path: Path):
+ out_path.parent.mkdir(parents=True, exist_ok=True)
+ by_class = {}
+ for r in results:
+ by_class.setdefault(r['classification'], []).append(r)
+
+ with open(out_path, 'w', encoding='utf-8') as f:
+ f.write('# TODO/FIXME Report\n\n')
+ f.write('Generated by `tools/generate_todo_report.py`.\n\n')
+ f.write('Summary:\n\n')
+ for k in sorted(by_class.keys()):
+ f.write(f'- **{k}**: {len(by_class[k])} items\n')
+ f.write('\n---\n\n')
+
+ for k in sorted(by_class.keys()):
+ f.write(f'## {k.capitalize()} ({len(by_class[k])})\n\n')
+ for item in by_class[k]:
+ f.write(f'- **{item["tag"]}** in `{item["path"]}`:{item["line"]} — {item["text"]}\n')
+ f.write('```\n')
+ f.write(item['context'] + '\n')
+ f.write('```\n\n')
+
+ f.write('\n---\n\n')
+ f.write('Notes:\n')
+ f.write('- `trivial`: likely simple fixes (typos, docs).\n')
+ f.write('- `implementable`: small code changes may resolve.\n')
+ f.write('- `complex`: needs design review or larger refactor.\n')
+ f.write('- `unknown`: manual review recommended.\n')
+
+ print(f'Wrote report to {out_path}')
+
+def parse_excludes(exclude_args):
+ excludes = set()
+ for item in exclude_args or []:
+ for part in item.split(','):
+ part = part.strip()
+ if part:
+ excludes.add(part)
+ return excludes
+
+def main():
+ parser = argparse.ArgumentParser(description="Generate TODO/FIXME report for the repository.")
+ parser.add_argument(
+ "--exclude-dir",
+ action="append",
+ default=[],
+ help="Directory name(s) to exclude. Repeat or provide comma-separated values.",
+ )
+ parser.add_argument(
+ "--no-default-excludes",
+ action="store_true",
+ help="Do not use the built-in excluded directory list.",
+ )
+ parser.add_argument(
+ "--root",
+ default=None,
+ help="Root directory to scan (defaults to $PWD).",
+ )
+ parser.add_argument(
+ "--output",
+ default=None,
+ help="Output markdown path (defaults to <root>/docs/TODO_FIXME_REPORT.md).",
+ )
+ args = parser.parse_args()
+
+ # Use PWD to match user's shell location (avoids resolving symlinks to Trash/cloud storage)
+ root_path_str = args.root or os.getenv('PWD') or os.getcwd()
+ root = Path(root_path_str)
+ out_path = Path(args.output) if args.output else root / "docs" / "TODO_FIXME_REPORT.md"
+
+ excludes = set()
+ if not args.no_default_excludes:
+ excludes.update(DEFAULT_EXCLUDED_DIRS)
+ excludes.update(parse_excludes(args.exclude_dir))
+
+ results = scan(root, excludes)
+ generate_md(results, out_path)
+
+if __name__ == '__main__':
+ main()
diff --git a/archived/projt-launcher/tools/get_commits.py b/archived/projt-launcher/tools/get_commits.py
new file mode 100644
index 0000000000..0d4b403e47
--- /dev/null
+++ b/archived/projt-launcher/tools/get_commits.py
@@ -0,0 +1,37 @@
+#!/usr/bin/env python3
+import requests
+from bs4 import BeautifulSoup
+import re
+
+URL = "https://sourceware.org/git/bzip2.git/log/?ofs=0"
+
+HEADERS = {
+ "User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 "
+ "(KHTML, like Gecko) Chrome/120.0 Safari/537.36",
+ "Accept": "text/html",
+}
+
+r = requests.get(URL, headers=HEADERS, timeout=30)
+r.raise_for_status()
+
+soup = BeautifulSoup(r.text, "html.parser")
+
+commits = []
+seen = set()
+
+for a in soup.select('a[href*="commit/?id="]'):
+ href = a.get("href", "")
+ commit = href.split("commit/?id=")[-1]
+ if re.fullmatch(r"[0-9a-f]{7,40}", commit):
+ if commit not in seen:
+ commits.append(commit)
+ seen.add(commit)
+
+# newest → oldest geliyor
+commits.reverse()
+
+if not commits:
+ raise RuntimeError("Commit bulunamadı — sourceware HTML hâlâ filtreliyor")
+
+for c in commits:
+ print(c) \ No newline at end of file