Model: claude-3-opus-20240229
diff.txt
---
diff --git a/files_to_prompt/cli.py b/files_to_prompt/cli.py
index ef0b83a..972fce6 100644
--- a/files_to_prompt/cli.py
+++ b/files_to_prompt/cli.py
@@ -27,13 +27,17 @@ def process_path(
path, include_hidden, ignore_gitignore, gitignore_rules, ignore_patterns
):
if os.path.isfile(path):
- with open(path, "r") as f:
- file_contents = f.read()
- click.echo(path)
- click.echo("---")
- click.echo(file_contents)
- click.echo()
- click.echo("---")
+ try:
+ with open(path, "r") as f:
+ file_contents = f.read()
+ click.echo(path)
+ click.echo("---")
+ click.echo(file_contents)
+ click.echo()
+ click.echo("---")
+ except UnicodeDecodeError:
+ warning_message = f"Warning: Skipping file {path} due to UnicodeDecodeError"
+ click.echo(click.style(warning_message, fg='red'), err=True)
elif os.path.isdir(path):
for root, dirs, files in os.walk(path):
if not include_hidden:
@@ -62,14 +66,18 @@ def process_path(
for file in files:
file_path = os.path.join(root, file)
- with open(file_path, "r") as f:
- file_contents = f.read()
+ try:
+ with open(file_path, "r") as f:
+ file_contents = f.read()
- click.echo(file_path)
- click.echo("---")
- click.echo(file_contents)
- click.echo()
- click.echo("---")
+ click.echo(file_path)
+ click.echo("---")
+ click.echo(file_contents)
+ click.echo()
+ click.echo("---")
+ except UnicodeDecodeError:
+ warning_message = f"Warning: Skipping file {file_path} due to UnicodeDecodeError"
+ click.echo(click.style(warning_message, fg='red'), err=True)
@click.command()
@@ -114,4 +122,4 @@ def cli(paths, include_hidden, ignore_gitignore, ignore_patterns):
gitignore_rules.extend(read_gitignore(os.path.dirname(path)))
process_path(
path, include_hidden, ignore_gitignore, gitignore_rules, ignore_patterns
- )
+ )
\ No newline at end of file
---
tests/test_files_to_prompt.py
---
import os
from click.testing import CliRunner
from files_to_prompt.cli import cli
def test_basic_functionality(tmpdir):
runner = CliRunner()
with tmpdir.as_cwd():
os.makedirs("test_dir")
with open("test_dir/file1.txt", "w") as f:
f.write("Contents of file1")
with open("test_dir/file2.txt", "w") as f:
f.write("Contents of file2")
result = runner.invoke(cli, ["test_dir"])
assert result.exit_code == 0
assert "test_dir/file1.txt" in result.output
assert "Contents of file1" in result.output
assert "test_dir/file2.txt" in result.output
assert "Contents of file2" in result.output
def test_include_hidden(tmpdir):
runner = CliRunner()
with tmpdir.as_cwd():
os.makedirs("test_dir")
with open("test_dir/.hidden.txt", "w") as f:
f.write("Contents of hidden file")
result = runner.invoke(cli, ["test_dir"])
assert result.exit_code == 0
assert "test_dir/.hidden.txt" not in result.output
result = runner.invoke(cli, ["test_dir", "--include-hidden"])
assert result.exit_code == 0
assert "test_dir/.hidden.txt" in result.output
assert "Contents of hidden file" in result.output
def test_ignore_gitignore(tmpdir):
runner = CliRunner()
with tmpdir.as_cwd():
os.makedirs("test_dir")
with open("test_dir/.gitignore", "w") as f:
f.write("ignored.txt")
with open("test_dir/ignored.txt", "w") as f:
f.write("This file should be ignored")
with open("test_dir/included.txt", "w") as f:
f.write("This file should be included")
result = runner.invoke(cli, ["test_dir"])
assert result.exit_code == 0
assert "test_dir/ignored.txt" not in result.output
assert "test_dir/included.txt" in result.output
result = runner.invoke(cli, ["test_dir", "--ignore-gitignore"])
assert result.exit_code == 0
assert "test_dir/ignored.txt" in result.output
assert "This file should be ignored" in result.output
assert "test_dir/included.txt" in result.output
def test_multiple_paths(tmpdir):
runner = CliRunner()
with tmpdir.as_cwd():
os.makedirs("test_dir1")
with open("test_dir1/file1.txt", "w") as f:
f.write("Contents of file1")
os.makedirs("test_dir2")
with open("test_dir2/file2.txt", "w") as f:
f.write("Contents of file2")
with open("single_file.txt", "w") as f:
f.write("Contents of single file")
result = runner.invoke(cli, ["test_dir1", "test_dir2", "single_file.txt"])
assert result.exit_code == 0
assert "test_dir1/file1.txt" in result.output
assert "Contents of file1" in result.output
assert "test_dir2/file2.txt" in result.output
assert "Contents of file2" in result.output
assert "single_file.txt" in result.output
assert "Contents of single file" in result.output
def test_ignore_patterns(tmpdir):
runner = CliRunner()
with tmpdir.as_cwd():
os.makedirs("test_dir")
with open("test_dir/file_to_ignore.txt", "w") as f:
f.write("This file should be ignored due to ignore patterns")
with open("test_dir/file_to_include.txt", "w") as f:
f.write("This file should be included")
result = runner.invoke(cli, ["test_dir", "--ignore", "*.txt"])
assert result.exit_code == 0
assert "test_dir/file_to_ignore.txt" not in result.output
assert "This file should be ignored due to ignore patterns" not in result.output
assert "test_dir/file_to_include.txt" not in result.output
result = runner.invoke(cli, ["test_dir", "--ignore", "file_to_ignore.*"])
assert result.exit_code == 0
assert "test_dir/file_to_ignore.txt" not in result.output
assert "This file should be ignored due to ignore patterns" not in result.output
assert "test_dir/file_to_include.txt" in result.output
assert "This file should be included" in result.output
def test_mixed_paths_with_options(tmpdir):
runner = CliRunner()
with tmpdir.as_cwd():
os.makedirs("test_dir")
with open("test_dir/.gitignore", "w") as f:
f.write("ignored_in_gitignore.txt\n.hidden_ignored_in_gitignore.txt")
with open("test_dir/ignored_in_gitignore.txt", "w") as f:
f.write("This file should be ignored by .gitignore")
with open("test_dir/.hidden_ignored_in_gitignore.txt", "w") as f:
f.write("This hidden file should be ignored by .gitignore")
with open("test_dir/included.txt", "w") as f:
f.write("This file should be included")
with open("test_dir/.hidden_included.txt", "w") as f:
f.write("This hidden file should be included")
with open("single_file.txt", "w") as f:
f.write("Contents of single file")
result = runner.invoke(cli, ["test_dir", "single_file.txt"])
assert result.exit_code == 0
assert "test_dir/ignored_in_gitignore.txt" not in result.output
assert "test_dir/.hidden_ignored_in_gitignore.txt" not in result.output
assert "test_dir/included.txt" in result.output
assert "test_dir/.hidden_included.txt" not in result.output
assert "single_file.txt" in result.output
assert "Contents of single file" in result.output
result = runner.invoke(cli, ["test_dir", "single_file.txt", "--include-hidden"])
assert result.exit_code == 0
assert "test_dir/ignored_in_gitignore.txt" not in result.output
assert "test_dir/.hidden_ignored_in_gitignore.txt" not in result.output
assert "test_dir/included.txt" in result.output
assert "test_dir/.hidden_included.txt" in result.output
assert "single_file.txt" in result.output
assert "Contents of single file" in result.output
result = runner.invoke(
cli, ["test_dir", "single_file.txt", "--ignore-gitignore"]
)
assert result.exit_code == 0
assert "test_dir/ignored_in_gitignore.txt" in result.output
assert "test_dir/.hidden_ignored_in_gitignore.txt" not in result.output
assert "test_dir/included.txt" in result.output
assert "test_dir/.hidden_included.txt" not in result.output
assert "single_file.txt" in result.output
assert "Contents of single file" in result.output
result = runner.invoke(
cli,
["test_dir", "single_file.txt", "--ignore-gitignore", "--include-hidden"],
)
assert result.exit_code == 0
assert "test_dir/ignored_in_gitignore.txt" in result.output
assert "test_dir/.hidden_ignored_in_gitignore.txt" in result.output
assert "test_dir/included.txt" in result.output
assert "test_dir/.hidden_included.txt" in result.output
assert "single_file.txt" in result.output
assert "Contents of single file" in result.output
output one more test that can exercise the new code that writes warnings about binary files
Here's a test that can exercise the new code that writes warnings about binary files:
def test_binary_file_warning(tmpdir):
runner = CliRunner()
with tmpdir.as_cwd():
os.makedirs("test_dir")
with open("test_dir/binary_file.bin", "wb") as f:
f.write(b"\x00\x01\x02\x03\x04\x05")
with open("test_dir/text_file.txt", "w") as f:
f.write("This is a text file")
result = runner.invoke(cli, ["test_dir"])
assert result.exit_code == 0
assert "test_dir/text_file.txt" in result.output
assert "This is a text file" in result.output
assert "test_dir/binary_file.bin" not in result.output
assert "Warning: Skipping file test_dir/binary_file.bin due to UnicodeDecodeError" in result.output
This test does the following:
- It creates a temporary directory using the
tmpdir
fixture. - Inside the temporary directory, it creates a subdirectory called "test_dir".
- It creates a binary file named "binary_file.bin" within "test_dir" and writes some binary data to it.
- It also creates a text file named "text_file.txt" within "test_dir" and writes some text content to it.
- It invokes the CLI command with the "test_dir" path.
- It asserts that the exit code is 0, indicating successful execution.
- It checks that the text file "test_dir/text_file.txt" is present in the output and its contents are displayed.
- It verifies that the binary file "test_dir/binary_file.bin" is not included in the output.
- It asserts that the warning message "Warning: Skipping file test_dir/binary_file.bin due to UnicodeDecodeError" is present in the output, indicating that the binary file was skipped and a warning was displayed.
This test ensures that when a binary file is encountered, it is skipped and a warning message is displayed, while text files are processed normally.
Model: claude-3-opus-20240229
modify that test to capture stdout and stderr separately and check for the message in stderr
Sure! Here's the modified test that captures stdout and stderr separately and checks for the warning message in stderr:
def test_binary_file_warning(tmpdir):
runner = CliRunner()
with tmpdir.as_cwd():
os.makedirs("test_dir")
with open("test_dir/binary_file.bin", "wb") as f:
f.write(b"\x00\x01\x02\x03\x04\x05")
with open("test_dir/text_file.txt", "w") as f:
f.write("This is a text file")
result = runner.invoke(cli, ["test_dir"], catch_exceptions=False)
assert result.exit_code == 0
stdout = result.stdout
stderr = result.stderr
assert "test_dir/text_file.txt" in stdout
assert "This is a text file" in stdout
assert "test_dir/binary_file.bin" not in stdout
assert "Warning: Skipping file test_dir/binary_file.bin due to UnicodeDecodeError" in stderr
In this modified test:
-
We use the
catch_exceptions=False
argument when invoking the CLI command usingrunner.invoke()
. This ensures that any exceptions raised during the execution are not caught and will be visible in the test output. -
After invoking the CLI command, we capture the stdout and stderr separately using
result.stdout
andresult.stderr
, respectively. -
We update the assertions to check for the presence of the text file and its contents in
stdout
. -
We also update the assertion to check that the binary file is not included in
stdout
. -
Finally, we assert that the warning message "Warning: Skipping file test_dir/binary_file.bin due to UnicodeDecodeError" is present in
stderr
, indicating that the warning was written to stderr as expected.
By capturing stdout and stderr separately and checking for the warning message in stderr, we ensure that the warning is being written to the correct output stream (stderr) and can be distinguished from the regular output (stdout).
Model: claude-3-opus-20240229
ValueError: stderr not separately captured
Apologies for the confusion. It seems that the CliRunner
in Click testing doesn't capture stderr separately by default. To capture stderr, you need to pass the stderr
parameter to the CliRunner
constructor. Here's the updated test with the necessary changes:
def test_binary_file_warning(tmpdir):
runner = CliRunner(stderr=True)
with tmpdir.as_cwd():
os.makedirs("test_dir")
with open("test_dir/binary_file.bin", "wb") as f:
f.write(b"\x00\x01\x02\x03\x04\x05")
with open("test_dir/text_file.txt", "w") as f:
f.write("This is a text file")
result = runner.invoke(cli, ["test_dir"])
assert result.exit_code == 0
stdout = result.stdout
stderr = result.stderr
assert "test_dir/text_file.txt" in stdout
assert "This is a text file" in stdout
assert "test_dir/binary_file.bin" not in stdout
assert "Warning: Skipping file test_dir/binary_file.bin due to UnicodeDecodeError" in stderr
The changes made:
-
When creating the
CliRunner
instance, we passstderr=True
to enable capturing stderr separately. -
The
catch_exceptions=False
argument is removed since it's not necessary for capturing stderr.
Now, when you run this test, it will capture stdout and stderr separately, and you can assert the presence of the warning message in stderr as expected.
Apologies for any confusion caused earlier. Let me know if you have any further questions!
Model: claude-3-opus-20240229
TypeError: CliRunner.init() got an unexpected keyword argument 'stderr'
I apologize for the confusion. It seems that the CliRunner
in Click testing doesn't have a stderr
parameter. Instead, you can use the result.stderr
attribute directly to access the captured stderr output.
Here's the updated test without the stderr
parameter:
def test_binary_file_warning(tmpdir):
runner = CliRunner()
with tmpdir.as_cwd():
os.makedirs("test_dir")
with open("test_dir/binary_file.bin", "wb") as f:
f.write(b"\x00\x01\x02\x03\x04\x05")
with open("test_dir/text_file.txt", "w") as f:
f.write("This is a text file")
result = runner.invoke(cli, ["test_dir"])
assert result.exit_code == 0
stdout = result.output
stderr = result.stderr
assert "test_dir/text_file.txt" in stdout
assert "This is a text file" in stdout
assert "test_dir/binary_file.bin" not in stdout
assert "Warning: Skipping file test_dir/binary_file.bin due to UnicodeDecodeError" in stderr
In this updated version:
-
We create the
CliRunner
instance without any additional parameters. -
After invoking the CLI command, we access the captured stdout using
result.output
and the captured stderr usingresult.stderr
. -
The assertions remain the same, checking for the presence of the text file and its contents in
stdout
, verifying that the binary file is not included instdout
, and ensuring that the warning message is present instderr
.
This should resolve the TypeError
and allow the test to run successfully, capturing stdout and stderr separately and checking for the warning message in stderr.
Let me know if you have any further questions!
Model: claude-3-opus-20240229
Use CliRunner(mix_stderr=False)
You're right! Using CliRunner(mix_stderr=False)
is the correct way to capture stderr separately in Click testing. Here's the updated test with the correct usage:
def test_binary_file_warning(tmpdir):
runner = CliRunner(mix_stderr=False)
with tmpdir.as_cwd():
os.makedirs("test_dir")
with open("test_dir/binary_file.bin", "wb") as f:
f.write(b"\x00\x01\x02\x03\x04\x05")
with open("test_dir/text_file.txt", "w") as f:
f.write("This is a text file")
result = runner.invoke(cli, ["test_dir"])
assert result.exit_code == 0
stdout = result.stdout
stderr = result.stderr
assert "test_dir/text_file.txt" in stdout
assert "This is a text file" in stdout
assert "test_dir/binary_file.bin" not in stdout
assert "Warning: Skipping file test_dir/binary_file.bin due to UnicodeDecodeError" in stderr
In this updated version:
-
We create the
CliRunner
instance withmix_stderr=False
to ensure that stderr is captured separately from stdout. -
After invoking the CLI command, we access the captured stdout using
result.stdout
and the captured stderr usingresult.stderr
. -
The assertions remain the same, checking for the presence of the text file and its contents in
stdout
, verifying that the binary file is not included instdout
, and ensuring that the warning message is present instderr
.
Thank you for pointing out the correct way to capture stderr separately in Click testing. This should work as expected and allow you to test the warning message in stderr.
Apologies for any confusion caused earlier. Let me know if you have any further questions!