Model: claude-3-opus-20240229
import os
import click
@click.command()
@click.argument(
"path",
type=click.Path(exists=True, file_okay=False, dir_okay=True, readable=True),
)
@click.option(
"--include-hidden",
is_flag=True,
help="Include files and folders starting with .",
)
@click.version_option()
def cli(path, include_hidden):
"""
Takes a path to a folder and outputs every file in that folder,
recursively, each one preceded with its filename like this:
path/to/file.py
----
Contents of file.py goes here
---
path/to/file2.py
---
...
"""
for root, dirs, files in os.walk(path):
if not include_hidden:
dirs[:] = [d for d in dirs if not d.startswith(".")]
files = [f for f in files if not f.startswith(".")]
for file in files:
file_path = os.path.join(root, file)
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("---")
modify this code to add a --ignore-gitignore flag which defaults to False. Without this flag the code should read any .gitignore files and filter content based on the rules within them. With the flag it should not do that.
Here's the modified code that adds the --ignore-gitignore
flag and filters the content based on the rules in the .gitignore
files:
import os
import click
from pathlib import Path
from fnmatch import fnmatch
def should_ignore(path, gitignore_rules):
for rule in gitignore_rules:
if fnmatch(path, rule):
return True
return False
def read_gitignore(path):
gitignore_path = os.path.join(path, ".gitignore")
if os.path.isfile(gitignore_path):
with open(gitignore_path, "r") as f:
return [line.strip() for line in f if line.strip() and not line.startswith("#")]
return []
@click.command()
@click.argument(
"path",
type=click.Path(exists=True, file_okay=False, dir_okay=True, readable=True),
)
@click.option(
"--include-hidden",
is_flag=True,
help="Include files and folders starting with .",
)
@click.option(
"--ignore-gitignore",
is_flag=True,
help="Ignore .gitignore files and include all files",
)
@click.version_option()
def cli(path, include_hidden, ignore_gitignore):
"""
Takes a path to a folder and outputs every file in that folder,
recursively, each one preceded with its filename like this:
path/to/file.py
----
Contents of file.py goes here
---
path/to/file2.py
---
...
"""
gitignore_rules = [] if ignore_gitignore else read_gitignore(path)
for root, dirs, files in os.walk(path):
if not include_hidden:
dirs[:] = [d for d in dirs if not d.startswith(".")]
files = [f for f in files if not f.startswith(".")]
if not ignore_gitignore:
gitignore_rules.extend(read_gitignore(root))
dirs[:] = [d for d in dirs if not should_ignore(os.path.join(root, d), gitignore_rules)]
files = [f for f in files if not should_ignore(os.path.join(root, f), gitignore_rules)]
for file in files:
file_path = os.path.join(root, file)
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("---")
The main changes made to the code are:
-
A new
--ignore-gitignore
flag is added, which defaults toFalse
. When set toTrue
, it ignores the.gitignore
files and includes all files. -
Two new functions are introduced:
should_ignore(path, gitignore_rules)
: Checks if a given path should be ignored based on the gitignore rules.read_gitignore(path)
: Reads the.gitignore
file in the given path and returns a list of rules.
-
Inside the
cli
function, thegitignore_rules
variable is initialized based on theignore_gitignore
flag. If the flag isFalse
, it reads the.gitignore
file in the root path. -
If
ignore_gitignore
isFalse
, the code extends thegitignore_rules
with the rules from each subdirectory's.gitignore
file. It then filters the directories and files based on the gitignore rules using theshould_ignore
function.
With these modifications, the code will respect the rules in the .gitignore
files by default. If the --ignore-gitignore
flag is provided, it will ignore the .gitignore
files and include all files.