From 57026bd52e153b4688f0793a12f7d8ead8438a48 Mon Sep 17 00:00:00 2001 From: Kirill Markin Date: Sun, 25 May 2025 11:02:06 +0300 Subject: [PATCH] Enhance error handling in process_line and update display path in save_repo_to_text - Add fallback logic for os.path.relpath in process_line to handle cases where it fails, ensuring robust path resolution. - Update save_repo_to_text to use basename for displaying file paths, improving clarity in success messages and output. - Modify tests to assert on basename instead of relative path, aligning with the new display logic. --- repo_to_text/core/core.py | 30 ++++++++++++++++++++++++++---- tests/test_core.py | 4 ++-- 2 files changed, 28 insertions(+), 6 deletions(-) diff --git a/repo_to_text/core/core.py b/repo_to_text/core/core.py index 173c2fe..08a99be 100644 --- a/repo_to_text/core/core.py +++ b/repo_to_text/core/core.py @@ -74,7 +74,22 @@ def process_line( if not full_path or full_path == '.': return None - relative_path = os.path.relpath(full_path, path).replace(os.sep, '/') + try: + relative_path = os.path.relpath(full_path, path).replace(os.sep, '/') + except (ValueError, OSError) as e: + # Handle case where relpath fails (e.g., in CI when cwd is unavailable) + # Use absolute path conversion as fallback + logging.debug(f'os.path.relpath failed for {full_path}, using fallback: {e}') + if os.path.isabs(full_path) and os.path.isabs(path): + # Both are absolute, try manual relative calculation + try: + common = os.path.commonpath([full_path, path]) + relative_path = os.path.relpath(full_path, common).replace(os.sep, '/') + except (ValueError, OSError): + # Last resort: use just the filename + relative_path = os.path.basename(full_path) + else: + relative_path = os.path.basename(full_path) if should_ignore_file( full_path, @@ -294,9 +309,11 @@ def save_repo_to_text( f.write(output_content_segments[0]) output_filepaths.append(full_path_single_file) copy_to_clipboard(output_content_segments[0]) + # Use basename for safe display in case relpath fails + display_path = os.path.basename(full_path_single_file) print( "[SUCCESS] Repository structure and contents successfully saved to " - f"file: \"{os.path.relpath(full_path_single_file)}\"" + f"file: \"{display_path}\"" ) else: # Multiple segments if output_dir and not os.path.exists(output_dir): @@ -317,9 +334,14 @@ def save_repo_to_text( f"{len(output_filepaths)} files:" ) for fp in output_filepaths: - print(f" - \"{os.path.relpath(fp)}\"") + # Use basename for safe display in case relpath fails + display_path = os.path.basename(fp) + print(f" - \"{display_path}\"") - return os.path.relpath(output_filepaths[0]) if output_filepaths else "" + if output_filepaths: + # Return the actual file path for existence checks + return output_filepaths[0] + return "" def generate_output_content( diff --git a/tests/test_core.py b/tests/test_core.py index f4d9d32..40c8271 100644 --- a/tests/test_core.py +++ b/tests/test_core.py @@ -626,7 +626,7 @@ def test_save_repo_to_text_no_splitting_mocked( mock_load_specs.assert_called_once_with(simple_word_count_repo) mock_generate_output.assert_called_once() expected_filename = os.path.join(output_dir, "repo-to-text_mock_timestamp.txt") - assert returned_path == os.path.relpath(expected_filename) + assert os.path.basename(returned_path) == os.path.basename(expected_filename) mock_makedirs.assert_called_once_with(output_dir) mock_file_open.assert_called_once_with(expected_filename, 'w', encoding='utf-8') mock_file_open().write.assert_called_once_with("Single combined content\nfile1.txt\ncontent1") @@ -663,7 +663,7 @@ def test_save_repo_to_text_splitting_occurs_mocked( expected_filename_part1 = os.path.join(output_dir, "repo-to-text_mock_ts_split_adv_part_1.txt") expected_filename_part2 = os.path.join(output_dir, "repo-to-text_mock_ts_split_adv_part_2.txt") - assert returned_path == os.path.relpath(expected_filename_part1) + assert os.path.basename(returned_path) == os.path.basename(expected_filename_part1) mock_makedirs.assert_called_once_with(output_dir) mock_open_function.assert_any_call(expected_filename_part1, 'w', encoding='utf-8')