From fb0548b7d514338961bed23822e90a14cd349075 Mon Sep 17 00:00:00 2001 From: Daniel Henry Date: Sat, 24 Jan 2026 15:26:41 -0600 Subject: [PATCH] Initial Commit Signed-off-by: Daniel Henry --- .gitignore | 10 ++++++ .python-version | 1 + README.md | 0 dumpy.py | 83 +++++++++++++++++++++++++++++++++++++++++++++++++ pyproject.toml | 9 ++++++ uv.lock | 23 ++++++++++++++ 6 files changed, 126 insertions(+) create mode 100644 .gitignore create mode 100644 .python-version create mode 100644 README.md create mode 100644 dumpy.py create mode 100644 pyproject.toml create mode 100644 uv.lock diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..88efd90 --- /dev/null +++ b/.gitignore @@ -0,0 +1,10 @@ +# Python-generated files +__pycache__/ +*.py[oc] +build/ +dist/ +wheels/ +*.egg-info + +# Virtual environments +.venv \ No newline at end of file diff --git a/.python-version b/.python-version new file mode 100644 index 0000000..6324d40 --- /dev/null +++ b/.python-version @@ -0,0 +1 @@ +3.14 diff --git a/README.md b/README.md new file mode 100644 index 0000000..e69de29 diff --git a/dumpy.py b/dumpy.py new file mode 100644 index 0000000..40a449c --- /dev/null +++ b/dumpy.py @@ -0,0 +1,83 @@ +from pathlib import Path +import pathspec +import argparse +import mimetypes + +def get_file_description(path: Path): + mime_type, _ = mimetypes.guess_type(path) + return mime_type or "Unknown mimetype" + +def output_metadata(path: Path, root: Path): + desc = get_file_description(path) + relative_path = path.relative_to(root) + print("#################") + print(f"## Filename: {relative_path}") + print(f"## Mimetype: {desc}") + print("#################") + +def get_ignore_spec(root: Path): + gitignore_path = root / ".gitignore" + if gitignore_path.exists(): + with gitignore_path.open("r") as f: + return pathspec.PathSpec.from_lines('gitwildmatch', f) + return None + +def should_include(path: Path, spec: pathspec.PathSpec | None, root: Path, include_git_dir: bool = False): + relative_path = path.relative_to(root) + if ".git" in path.parts and not include_git_dir: + return False + + if spec is None: + return True + + return not spec.match_file(str(relative_path)) + +def walk_filesystem(ignore_gitignore: bool, include_git_dir: bool = False): + root = Path(".") + + spec = None + if not ignore_gitignore: + spec = get_ignore_spec(root) + + for path in root.rglob("*"): + if path.is_file(): + # print the filename (for now) + if should_include(path, spec, root, include_git_dir): + output_metadata(path, root) + success, content = get_file_contents(path) + if success: + print("## File Contents:") + print(content) + print("\n") + +def get_file_contents(path: Path) -> tuple[bool, str]: + + try: + with path.open("r", encoding="utf-8") as f: + return (True, f.read()) + except (UnicodeDecodeError, PermissionError): + return (False, "") + +def main(): + + parser = argparse.ArgumentParser(description="Dumpy: A tool for providing a text representation of a project formatted in a way that LLMs will understand.") + + parser.add_argument( + "--no-gitignore", + action="store_true", + help="Ignore the .gitignore file and include all files" + ) + + parser.add_argument( + "--include-git-dir", + action="store_true", + help="Include the .git directory in the output" + ) + + args = parser.parse_args() + + walk_filesystem(ignore_gitignore=args.no_gitignore) + +if __name__ == "__main__": + main() + diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..4c37e01 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,9 @@ +[project] +name = "dumpy" +version = "0.1.0" +description = "Used for dumping directories into the command prompt in a way that LLMs will understand" +readme = "README.md" +requires-python = ">=3.14" +dependencies = [ + "pathspec>=1.0.3", +] diff --git a/uv.lock b/uv.lock new file mode 100644 index 0000000..b0b71bb --- /dev/null +++ b/uv.lock @@ -0,0 +1,23 @@ +version = 1 +revision = 3 +requires-python = ">=3.14" + +[[package]] +name = "dumpy" +version = "0.1.0" +source = { virtual = "." } +dependencies = [ + { name = "pathspec" }, +] + +[package.metadata] +requires-dist = [{ name = "pathspec", specifier = ">=1.0.3" }] + +[[package]] +name = "pathspec" +version = "1.0.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/4c/b2/bb8e495d5262bfec41ab5cb18f522f1012933347fb5d9e62452d446baca2/pathspec-1.0.3.tar.gz", hash = "sha256:bac5cf97ae2c2876e2d25ebb15078eb04d76e4b98921ee31c6f85ade8b59444d", size = 130841, upload-time = "2026-01-09T15:46:46.009Z" } +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" }, +]