From 3721ed45f00edb6106d417d2b0f4171c7e2a8158 Mon Sep 17 00:00:00 2001 From: Kirill Markin Date: Sat, 25 Oct 2025 15:02:18 +0200 Subject: [PATCH 1/4] Fix tree command for Windows (fixes #26) - Add platform detection to run_tree_command - Use 'cmd /c tree /a /f' syntax on Windows - Keep 'tree -a -f --noreport' syntax on Unix/Linux/Mac - Modernize subprocess call with text=True and encoding='utf-8' - Add stderr=subprocess.PIPE for better error handling All 43 tests pass successfully. --- repo_to_text/core/core.py | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/repo_to_text/core/core.py b/repo_to_text/core/core.py index 6dfcda9..b786d8e 100644 --- a/repo_to_text/core/core.py +++ b/repo_to_text/core/core.py @@ -4,6 +4,7 @@ Core functionality for repo-to-text import os import subprocess +import platform from typing import Tuple, Optional, List, Dict, Any, Set from datetime import datetime, timezone from importlib.machinery import ModuleSpec @@ -36,12 +37,20 @@ def get_tree_structure( def run_tree_command(path: str) -> str: """Run the tree command and return its output.""" + if platform.system() == "Windows": + cmd = ["cmd", "/c", "tree", "/a", "/f", path] + else: + cmd = ["tree", "-a", "-f", "--noreport", path] + result = subprocess.run( - ['tree', '-a', '-f', '--noreport', path], + cmd, stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + text=True, + encoding='utf-8', check=True ) - return result.stdout.decode('utf-8') + return result.stdout def filter_tree_output( tree_output: str, From bcb0d82191dd5a7c4076984fc06e0b7866bc3815 Mon Sep 17 00:00:00 2001 From: Kirill Markin Date: Sat, 25 Oct 2025 15:11:43 +0200 Subject: [PATCH 2/4] refactor: reorganize cursor rules into .cursor directory - Move cursor rules from .cursorrules to .cursor/index.mdc - Create CLAUDE.md and AGENTS.md symlinks in project root - Delete deprecated .cursorrules file - Symlinks point to .cursor/index.mdc for consistent rule management --- .cursorrules => .cursor/index.mdc | 4 ++++ AGENTS.md | 1 + CLAUDE.md | 1 + 3 files changed, 6 insertions(+) rename .cursorrules => .cursor/index.mdc (95%) create mode 120000 AGENTS.md create mode 120000 CLAUDE.md diff --git a/.cursorrules b/.cursor/index.mdc similarity index 95% rename from .cursorrules rename to .cursor/index.mdc index 3ebccca..5b9200b 100644 --- a/.cursorrules +++ b/.cursor/index.mdc @@ -1,3 +1,7 @@ +--- +alwaysApply: true +--- + # repo-to-text ## Project Overview diff --git a/AGENTS.md b/AGENTS.md new file mode 120000 index 0000000..94443be --- /dev/null +++ b/AGENTS.md @@ -0,0 +1 @@ +.cursor/index.mdc \ No newline at end of file diff --git a/CLAUDE.md b/CLAUDE.md new file mode 120000 index 0000000..94443be --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1 @@ +.cursor/index.mdc \ No newline at end of file From 8a94182b3d26aa9edc76b1040c50745e3da8bb64 Mon Sep 17 00:00:00 2001 From: Kirill Markin Date: Sat, 25 Oct 2025 15:33:35 +0200 Subject: [PATCH 3/4] Bump version to 0.8.0 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 19e9e99..ff44c8d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "repo-to-text" -version = "0.7.0" +version = "0.8.0" authors = [ { name = "Kirill Markin", email = "markinkirill@gmail.com" }, ] From 77209f30aa98531436550ef334541af82273393d Mon Sep 17 00:00:00 2001 From: Luke Craig Date: Tue, 28 Oct 2025 04:27:44 -0400 Subject: [PATCH 4/4] Add minimal handling for broken symlinks in generate_output_content (#32) * Add minimal handling for broken symlinks in generate_output_content * core: simplify generate_output_content * pylint adjust no-else-return --- repo_to_text/core/core.py | 40 ++++++++++++++++++++++++++++----------- 1 file changed, 29 insertions(+), 11 deletions(-) diff --git a/repo_to_text/core/core.py b/repo_to_text/core/core.py index b786d8e..ccc9460 100644 --- a/repo_to_text/core/core.py +++ b/repo_to_text/core/core.py @@ -352,6 +352,33 @@ def save_repo_to_text( return output_filepaths[0] return "" +def _read_file_content(file_path: str) -> str: + """Read file content, handling binary files and broken symlinks. + + Args: + file_path: Path to the file to read + + Returns: + str: File content or appropriate message for special cases + """ + try: + with open(file_path, 'r', encoding='utf-8') as f: + return f.read() + except UnicodeDecodeError: + logging.debug('Handling binary file contents: %s', file_path) + with open(file_path, 'rb') as f_bin: + binary_content: bytes = f_bin.read() + return binary_content.decode('latin1') + except FileNotFoundError as e: + # Minimal handling for bad symlinks + if os.path.islink(file_path) and not os.path.exists(file_path): + try: + target = os.readlink(file_path) + except OSError: + target = '' + return f"[symlink] -> {target}" + raise e + def generate_output_content( path: str, @@ -426,17 +453,8 @@ def generate_output_content( cleaned_relative_path = relative_path.replace('./', '', 1) _add_chunk_to_output(f'\n\n') - - try: - with open(file_path, 'r', encoding='utf-8') as f: - file_content = f.read() - _add_chunk_to_output(file_content) - except UnicodeDecodeError: - logging.debug('Handling binary file contents: %s', file_path) - with open(file_path, 'rb') as f_bin: - binary_content: bytes = f_bin.read() - _add_chunk_to_output(binary_content.decode('latin1')) # Add decoded binary - + file_content = _read_file_content(file_path) + _add_chunk_to_output(file_content) _add_chunk_to_output('\n\n') _add_chunk_to_output('\n\n')