Skip to content

Commit acbe107

Browse files
nmpowellsimonw
andauthored
--ignore patterns now include directory names unless --ignore-files-only (#30)
* Option to --include-directories otherwise ignored by an ignore pattern * --include-directories renamed to --ignore-files-only Refs #30 --------- Co-authored-by: Simon Willison <[email protected]>
1 parent c4f6fbe commit acbe107

File tree

3 files changed

+53
-5
lines changed

3 files changed

+53
-5
lines changed

README.md

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,13 +41,19 @@ This will output the contents of every file, with each file preceded by its rela
4141
files-to-prompt path/to/directory --include-hidden
4242
```
4343

44+
- `--ignore-files-only`: Include directory paths which would otherwise be ignored by an `--ignore` pattern.
45+
46+
```bash
47+
files-to-prompt path/to/directory --ignore-files-only --ignore "*dir*"
48+
```
49+
4450
- `--ignore-gitignore`: Ignore `.gitignore` files and include all files.
4551

4652
```bash
4753
files-to-prompt path/to/directory --ignore-gitignore
4854
```
4955

50-
- `--ignore <pattern>`: Specify one or more patterns to ignore. Can be used multiple times.
56+
- `--ignore <pattern>`: Specify one or more patterns to ignore. Can be used multiple times. Patterns may match file names and directory names, unless you also specify `--ignore-files-only`.
5157
```bash
5258
files-to-prompt path/to/directory --ignore "*.log" --ignore "temp*"
5359
```
@@ -138,6 +144,19 @@ Contents of file3.txt
138144
---
139145
```
140146

147+
If you run `files-to-prompt my_directory --ignore "sub*"`, the output will exclude all files in `subdirectory/` (unless you also specify `--ignore-files-only`):
148+
149+
```
150+
my_directory/file1.txt
151+
---
152+
Contents of file1.txt
153+
---
154+
my_directory/file2.txt
155+
---
156+
Contents of file2.txt
157+
---
158+
```
159+
141160
### Claude XML Output
142161

143162
Anthropic has provided [specific guidelines](https://docs.anthropic.com/claude/docs/long-context-window-tips) for optimally structuring prompts to take advantage of Claude's extended context window.

files_to_prompt/cli.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ def process_path(
6868
path,
6969
extensions,
7070
include_hidden,
71+
ignore_files_only,
7172
ignore_gitignore,
7273
gitignore_rules,
7374
ignore_patterns,
@@ -102,6 +103,12 @@ def process_path(
102103
]
103104

104105
if ignore_patterns:
106+
if not ignore_files_only:
107+
dirs[:] = [
108+
d
109+
for d in dirs
110+
if not any(fnmatch(d, pattern) for pattern in ignore_patterns)
111+
]
105112
files = [
106113
f
107114
for f in files
@@ -133,6 +140,11 @@ def process_path(
133140
is_flag=True,
134141
help="Include files and folders starting with .",
135142
)
143+
@click.option(
144+
"--ignore-files-only",
145+
is_flag=True,
146+
help="--ignore option only ignores files",
147+
)
136148
@click.option(
137149
"--ignore-gitignore",
138150
is_flag=True,
@@ -171,6 +183,7 @@ def cli(
171183
paths,
172184
extensions,
173185
include_hidden,
186+
ignore_files_only,
174187
ignore_gitignore,
175188
ignore_patterns,
176189
output_file,
@@ -223,6 +236,7 @@ def cli(
223236
path,
224237
extensions,
225238
include_hidden,
239+
ignore_files_only,
226240
ignore_gitignore,
227241
gitignore_rules,
228242
ignore_patterns,

tests/test_files_to_prompt.py

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ def test_multiple_paths(tmpdir):
8888
def test_ignore_patterns(tmpdir):
8989
runner = CliRunner()
9090
with tmpdir.as_cwd():
91-
os.makedirs("test_dir")
91+
os.makedirs("test_dir", exist_ok=True)
9292
with open("test_dir/file_to_ignore.txt", "w") as f:
9393
f.write("This file should be ignored due to ignore patterns")
9494
with open("test_dir/file_to_include.txt", "w") as f:
@@ -100,12 +100,27 @@ def test_ignore_patterns(tmpdir):
100100
assert "This file should be ignored due to ignore patterns" not in result.output
101101
assert "test_dir/file_to_include.txt" not in result.output
102102

103-
result = runner.invoke(cli, ["test_dir", "--ignore", "file_to_ignore.*"])
103+
os.makedirs("test_dir/test_subdir", exist_ok=True)
104+
with open("test_dir/test_subdir/any_file.txt", "w") as f:
105+
f.write("This entire subdirectory should be ignored due to ignore patterns")
106+
result = runner.invoke(cli, ["test_dir", "--ignore", "*subdir*"])
104107
assert result.exit_code == 0
105-
assert "test_dir/file_to_ignore.txt" not in result.output
106-
assert "This file should be ignored due to ignore patterns" not in result.output
108+
assert "test_dir/test_subdir/any_file.txt" not in result.output
109+
assert (
110+
"This entire subdirectory should be ignored due to ignore patterns"
111+
not in result.output
112+
)
107113
assert "test_dir/file_to_include.txt" in result.output
108114
assert "This file should be included" in result.output
115+
assert "This file should be included" in result.output
116+
117+
result = runner.invoke(
118+
cli, ["test_dir", "--ignore", "*subdir*", "--ignore-files-only"]
119+
)
120+
assert result.exit_code == 0
121+
assert "test_dir/test_subdir/any_file.txt" in result.output
122+
123+
result = runner.invoke(cli, ["test_dir", "--ignore", ""])
109124

110125

111126
def test_specific_extensions(tmpdir):

0 commit comments

Comments
 (0)