Add stats to the output

Signed-off-by: Daniel Henry <iamdanhenry@gmail.com>
This commit is contained in:
2026-01-24 19:01:23 -06:00
parent 21780473cc
commit 1911685e30
3 changed files with 93 additions and 8 deletions

View File

@@ -1,4 +1,9 @@
from pathlib import Path from pathlib import Path
from rich import print as rprint
from rich.console import Console
from rich.text import Text
import pathspec import pathspec
import argparse import argparse
import mimetypes import mimetypes
@@ -36,7 +41,7 @@ def should_include(path: Path, spec: pathspec.PathSpec | None, root: Path, inclu
return not spec.match_file(str(relative_path)) return not spec.match_file(str(relative_path))
def walk_filesystem(ignore_gitignore: bool, include_git_dir: bool = False) -> list[str]: def walk_filesystem(ignore_gitignore: bool, include_git_dir: bool = False) -> tuple[int, list[str]]:
root = Path(".") root = Path(".")
spec = None spec = None
@@ -44,18 +49,20 @@ def walk_filesystem(ignore_gitignore: bool, include_git_dir: bool = False) -> li
spec = get_ignore_spec(root) spec = get_ignore_spec(root)
final_content: list[str] = [] final_content: list[str] = []
file_count: int = 0
for path in root.rglob("*"): for path in root.rglob("*"):
if path.is_file(): if path.is_file():
# print the filename (for now) # print the filename (for now)
if should_include(path, spec, root, include_git_dir): if should_include(path, spec, root, include_git_dir):
final_content += generate_metadata_string(path, root) final_content += generate_metadata_string(path, root)
file_count += 1
success, content = get_file_contents(path) success, content = get_file_contents(path)
if success: if success:
final_content.append("## File Contents:\n```") final_content.append("## File Contents:\n```")
final_content.append(content) final_content.append(content)
final_content.append("```\n") final_content.append("```\n")
return final_content return (file_count, final_content)
def get_file_contents(path: Path) -> tuple[bool, str]: def get_file_contents(path: Path) -> tuple[bool, str]:
@@ -87,20 +94,52 @@ def main():
help="Skip putting content into the clipboard and ouput directly to the console" help="Skip putting content into the clipboard and ouput directly to the console"
) )
parser.add_argument(
"--no-stats",
action="store_true",
help="Skip printing stats at the end of the output"
)
args = parser.parse_args() args = parser.parse_args()
content: list[str] = [] content: list[str] = []
content.append(f"Root Directory: {Path(".").absolute()}\n") content.append(f"Root Directory: {Path(".").absolute()}\n")
content = walk_filesystem(ignore_gitignore=args.no_gitignore) count, content = walk_filesystem(ignore_gitignore=args.no_gitignore)
string_content = "\n".join(content)
if args.no_clipboard: if args.no_clipboard:
print("\n".join(content)) print(string_content)
else: else:
pyperclip.copy("\n".join(content)) pyperclip.copy(string_content)
if not args.no_stats:
rprint("\n[bold green]Directoy contents copied to clipboard...[/]")
if not args.no_clipboard:
print() # Fix styling from the "contents copied" message
if not args.no_stats:
token_estimate = round(len(string_content) / 4)
if token_estimate > 3000:
tokens_color = "orange3"
elif token_estimate > 4000:
tokens_color = "red"
else:
tokens_color = "green"
console = Console()
# Output stats to the command line
rprint(f"[bold blue]Total Files:[/] [white]{count}[/white]")
rprint(f"[bold blue]Total Characters:[/] [white]{len(string_content)}[/white]")
label = Text("Estimated Tokens: ", style="bold blue")
label.append(Text(f"~{token_estimate}", style=tokens_color))
console.print(label + "\n")
if not content:
return
if __name__ == "__main__": if __name__ == "__main__":
main() main()

View File

@@ -7,4 +7,5 @@ requires-python = ">=3.14"
dependencies = [ dependencies = [
"pathspec>=1.0.3", "pathspec>=1.0.3",
"pyperclip>=1.11.0", "pyperclip>=1.11.0",
"rich>=14.3.1",
] ]

45
uv.lock generated
View File

@@ -9,12 +9,35 @@ source = { virtual = "." }
dependencies = [ dependencies = [
{ name = "pathspec" }, { name = "pathspec" },
{ name = "pyperclip" }, { name = "pyperclip" },
{ name = "rich" },
] ]
[package.metadata] [package.metadata]
requires-dist = [ requires-dist = [
{ name = "pathspec", specifier = ">=1.0.3" }, { name = "pathspec", specifier = ">=1.0.3" },
{ name = "pyperclip", specifier = ">=1.11.0" }, { name = "pyperclip", specifier = ">=1.11.0" },
{ name = "rich", specifier = ">=14.3.1" },
]
[[package]]
name = "markdown-it-py"
version = "4.0.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "mdurl" },
]
sdist = { url = "https://files.pythonhosted.org/packages/5b/f5/4ec618ed16cc4f8fb3b701563655a69816155e79e24a17b651541804721d/markdown_it_py-4.0.0.tar.gz", hash = "sha256:cb0a2b4aa34f932c007117b194e945bd74e0ec24133ceb5bac59009cda1cb9f3", size = 73070, upload-time = "2025-08-11T12:57:52.854Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/94/54/e7d793b573f298e1c9013b8c4dade17d481164aa517d1d7148619c2cedbf/markdown_it_py-4.0.0-py3-none-any.whl", hash = "sha256:87327c59b172c5011896038353a81343b6754500a08cd7a4973bb48c6d578147", size = 87321, upload-time = "2025-08-11T12:57:51.923Z" },
]
[[package]]
name = "mdurl"
version = "0.1.2"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/d6/54/cfe61301667036ec958cb99bd3efefba235e65cdeb9c84d24a8293ba1d90/mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba", size = 8729, upload-time = "2022-08-14T12:40:10.846Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", size = 9979, upload-time = "2022-08-14T12:40:09.779Z" },
] ]
[[package]] [[package]]
@@ -26,6 +49,15 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/32/2b/121e912bd60eebd623f873fd090de0e84f322972ab25a7f9044c056804ed/pathspec-1.0.3-py3-none-any.whl", hash = "sha256:e80767021c1cc524aa3fb14bedda9c34406591343cc42797b386ce7b9354fb6c", size = 55021, upload-time = "2026-01-09T15:46:44.652Z" }, { url = "https://files.pythonhosted.org/packages/32/2b/121e912bd60eebd623f873fd090de0e84f322972ab25a7f9044c056804ed/pathspec-1.0.3-py3-none-any.whl", hash = "sha256:e80767021c1cc524aa3fb14bedda9c34406591343cc42797b386ce7b9354fb6c", size = 55021, upload-time = "2026-01-09T15:46:44.652Z" },
] ]
[[package]]
name = "pygments"
version = "2.19.2"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/b0/77/a5b8c569bf593b0140bde72ea885a803b82086995367bf2037de0159d924/pygments-2.19.2.tar.gz", hash = "sha256:636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887", size = 4968631, upload-time = "2025-06-21T13:39:12.283Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/pygments-2.19.2-py3-none-any.whl", hash = "sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b", size = 1225217, upload-time = "2025-06-21T13:39:07.939Z" },
]
[[package]] [[package]]
name = "pyperclip" name = "pyperclip"
version = "1.11.0" version = "1.11.0"
@@ -34,3 +66,16 @@ sdist = { url = "https://files.pythonhosted.org/packages/e8/52/d87eba7cb129b8156
wheels = [ wheels = [
{ url = "https://files.pythonhosted.org/packages/df/80/fc9d01d5ed37ba4c42ca2b55b4339ae6e200b456be3a1aaddf4a9fa99b8c/pyperclip-1.11.0-py3-none-any.whl", hash = "sha256:299403e9ff44581cb9ba2ffeed69c7aa96a008622ad0c46cb575ca75b5b84273", size = 11063, upload-time = "2025-09-26T14:40:36.069Z" }, { url = "https://files.pythonhosted.org/packages/df/80/fc9d01d5ed37ba4c42ca2b55b4339ae6e200b456be3a1aaddf4a9fa99b8c/pyperclip-1.11.0-py3-none-any.whl", hash = "sha256:299403e9ff44581cb9ba2ffeed69c7aa96a008622ad0c46cb575ca75b5b84273", size = 11063, upload-time = "2025-09-26T14:40:36.069Z" },
] ]
[[package]]
name = "rich"
version = "14.3.1"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "markdown-it-py" },
{ name = "pygments" },
]
sdist = { url = "https://files.pythonhosted.org/packages/a1/84/4831f881aa6ff3c976f6d6809b58cdfa350593ffc0dc3c58f5f6586780fb/rich-14.3.1.tar.gz", hash = "sha256:b8c5f568a3a749f9290ec6bddedf835cec33696bfc1e48bcfecb276c7386e4b8", size = 230125, upload-time = "2026-01-24T21:40:44.847Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/87/2a/a1810c8627b9ec8c57ec5ec325d306701ae7be50235e8fd81266e002a3cc/rich-14.3.1-py3-none-any.whl", hash = "sha256:da750b1aebbff0b372557426fb3f35ba56de8ef954b3190315eb64076d6fb54e", size = 309952, upload-time = "2026-01-24T21:40:42.969Z" },
]