Commit
ยท
2d58037
1
Parent(s):
8f95629
feat: Create CLI-BLUPRINTER tool for project reporting
Browse files- pyproject.toml +1 -0
- src/crom_efficientllm/bluprinter.py +103 -0
pyproject.toml
CHANGED
|
@@ -42,6 +42,7 @@ Homepage = "https://github.com/Flamehaven/CRoM-Context-Rot-Mitigation--Efficient
|
|
| 42 |
[project.scripts]
|
| 43 |
"crom-demo" = "crom_efficientllm.demo:main"
|
| 44 |
"crom-bench" = "crom_efficientllm.cli:main"
|
|
|
|
| 45 |
|
| 46 |
[tool.setuptools]
|
| 47 |
package-dir = {"" = "src"}
|
|
|
|
| 42 |
[project.scripts]
|
| 43 |
"crom-demo" = "crom_efficientllm.demo:main"
|
| 44 |
"crom-bench" = "crom_efficientllm.cli:main"
|
| 45 |
+
"cli-bluprinter" = "crom_efficientllm.bluprinter:main"
|
| 46 |
|
| 47 |
[tool.setuptools]
|
| 48 |
package-dir = {"" = "src"}
|
src/crom_efficientllm/bluprinter.py
ADDED
|
@@ -0,0 +1,103 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import os
|
| 2 |
+
import argparse
|
| 3 |
+
from pathlib import Path
|
| 4 |
+
from typing import List, Set
|
| 5 |
+
|
| 6 |
+
# ๊ธฐ๋ณธ์ ์ผ๋ก ์ ์ธํ ๋๋ ํ ๋ฆฌ ๋ฐ ํ์ผ ํจํด
|
| 7 |
+
DEFAULT_EXCLUDES = {
|
| 8 |
+
"__pycache__",
|
| 9 |
+
".git",
|
| 10 |
+
".pytest_cache",
|
| 11 |
+
".vscode",
|
| 12 |
+
".idea",
|
| 13 |
+
"node_modules",
|
| 14 |
+
".env",
|
| 15 |
+
"*.pyc",
|
| 16 |
+
"*.pyo",
|
| 17 |
+
"*.egg-info",
|
| 18 |
+
"dist",
|
| 19 |
+
"build",
|
| 20 |
+
}
|
| 21 |
+
|
| 22 |
+
def generate_tree(directory: Path, excludes: Set[str]) -> (str, List[Path]):
|
| 23 |
+
"""๋๋ ํ ๋ฆฌ ๊ตฌ์กฐ ํธ๋ฆฌ์ ํ์ผ ๋ชฉ๋ก์ ์์ฑํฉ๋๋ค."""
|
| 24 |
+
tree_str = f"```\n{directory.name}/\n"
|
| 25 |
+
file_paths = []
|
| 26 |
+
|
| 27 |
+
def build_tree(current_path: Path, prefix: str = ""):
|
| 28 |
+
nonlocal tree_str
|
| 29 |
+
# listdir๋ฅผ ์ฌ์ฉํ์ฌ ํ์ฌ ๊ฒฝ๋ก์ ๋ด์ฉ์ ๊ฐ์ ธ์ต๋๋ค.
|
| 30 |
+
try:
|
| 31 |
+
entries = sorted(os.listdir(current_path))
|
| 32 |
+
except FileNotFoundError:
|
| 33 |
+
return
|
| 34 |
+
|
| 35 |
+
# ํํฐ๋ง: ์ ์ธ ๋ชฉ๋ก์ ํฌํจ๋ ํญ๋ชฉ์ ๊ฑธ๋ฌ๋
๋๋ค.
|
| 36 |
+
filtered_entries = []
|
| 37 |
+
for entry in entries:
|
| 38 |
+
if entry not in excludes:
|
| 39 |
+
# ์ฌ๊ธฐ์ ์ถ๊ฐ์ ์ธ glob ํจํด ๋งค์นญ์ ํ ์๋ ์์ต๋๋ค.
|
| 40 |
+
filtered_entries.append(entry)
|
| 41 |
+
|
| 42 |
+
for i, entry in enumerate(filtered_entries):
|
| 43 |
+
is_last = i == (len(filtered_entries) - 1)
|
| 44 |
+
connector = "โโโ " if is_last else "โโโ "
|
| 45 |
+
tree_str += f"{prefix}{connector}{entry}\n"
|
| 46 |
+
|
| 47 |
+
new_path = current_path / entry
|
| 48 |
+
if new_path.is_dir():
|
| 49 |
+
new_prefix = prefix + (" " if is_last else "โ ")
|
| 50 |
+
build_tree(new_path, new_prefix)
|
| 51 |
+
else:
|
| 52 |
+
file_paths.append(new_path)
|
| 53 |
+
|
| 54 |
+
build_tree(directory)
|
| 55 |
+
tree_str += "```\n"
|
| 56 |
+
return tree_str, file_paths
|
| 57 |
+
|
| 58 |
+
def get_file_content(file_path: Path) -> str:
|
| 59 |
+
"""ํ์ผ ๋ด์ฉ์ ์ฝ์ด์ต๋๋ค. ํ
์คํธ ํ์ผ์ด ์๋ ๊ฒฝ์ฐ๋ฅผ ๋๋นํด ์์ธ ์ฒ๋ฆฌ๋ฅผ ํฌํจํฉ๋๋ค."""
|
| 60 |
+
try:
|
| 61 |
+
with file_path.open("r", encoding="utf-8") as f:
|
| 62 |
+
return f.read()
|
| 63 |
+
except Exception:
|
| 64 |
+
return "[Error: Could not read file content, possibly a binary file.]\n"
|
| 65 |
+
|
| 66 |
+
def main():
|
| 67 |
+
parser = argparse.ArgumentParser(description="Generate a project blueprint in a single Markdown file.")
|
| 68 |
+
parser.add_argument("--input-dir", type=str, required=True, help="The root directory of the project to scan.")
|
| 69 |
+
parser.add_argument("--output-file", type=str, default="project_blueprint.md", help="The name of the output Markdown file.")
|
| 70 |
+
args = parser.parse_args()
|
| 71 |
+
|
| 72 |
+
input_path = Path(args.input_dir).resolve()
|
| 73 |
+
output_path = Path(args.output_file).resolve()
|
| 74 |
+
|
| 75 |
+
print(f"Scanning project at: {input_path}")
|
| 76 |
+
|
| 77 |
+
# 1. ๋๋ ํ ๋ฆฌ ๊ตฌ์กฐ ๋ฐ ํ์ผ ๋ชฉ๋ก ์์ฑ
|
| 78 |
+
tree_structure, file_paths = generate_tree(input_path, DEFAULT_EXCLUDES)
|
| 79 |
+
|
| 80 |
+
# 2. ์ต์ข
๋ฆฌํฌํธ ์์ฑ
|
| 81 |
+
with output_path.open("w", encoding="utf-8") as f:
|
| 82 |
+
f.write(f"# Project Blueprint: {input_path.name}\n\n")
|
| 83 |
+
f.write("## 1. Project Directory Tree\n\n")
|
| 84 |
+
f.write(tree_structure)
|
| 85 |
+
f.write("\n## 2. File Contents\n\n")
|
| 86 |
+
|
| 87 |
+
for path in file_paths:
|
| 88 |
+
print(f" - Processing: {path.relative_to(input_path)}")
|
| 89 |
+
f.write(f"---\n### **File:** `{path}`\n")
|
| 90 |
+
|
| 91 |
+
# ํ์ผ ํ์ฅ์์ ๋ฐ๋ผ ์ฝ๋ ๋ธ๋ก ์ธ์ด ์ง์
|
| 92 |
+
lang = path.suffix.lstrip('.')
|
| 93 |
+
if not lang:
|
| 94 |
+
lang = "text"
|
| 95 |
+
|
| 96 |
+
f.write(f"```{lang}\n")
|
| 97 |
+
f.write(get_file_content(path))
|
| 98 |
+
f.write(f"\n```\n\n")
|
| 99 |
+
|
| 100 |
+
print(f"\nSuccessfully generated project blueprint at: {output_path}")
|
| 101 |
+
|
| 102 |
+
if __name__ == "__main__":
|
| 103 |
+
main()
|