Created
October 12, 2024 18:23
-
-
Save shmup/395dba6f8f8451d5d84a1d7a509c1f59 to your computer and use it in GitHub Desktop.
slurpfiles
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
""" | |
This script concatenates files in a directory and prints the content. | |
The filename and relative path is atop each text blob. | |
$ slurpfiles /optional/path | |
$ slurpfiles -r /path/with/nested/dirs | |
$ slurpfiles --ignore *.css *.txt /path | |
$ slurpfiles -o path/to/foo.js path/to/another/thing.js | |
""" | |
import os | |
import argparse | |
import fnmatch | |
import subprocess | |
def is_binary(file_path): | |
with open(file_path, 'rb') as f: | |
chunk = f.read(1024) | |
return b'\0' in chunk | |
def is_file_modified(file_path): | |
cmd = f'git status --porcelain {file_path}' | |
result = subprocess.run(cmd, shell=True, capture_output=True, text=True) | |
return result.stdout.strip() != "" | |
def concatenate_files(files, ignore_patterns=[], modified_only=False): | |
for file_path in files: | |
if os.path.isfile(file_path): | |
if any(fnmatch.fnmatch(os.path.basename(file_path), pattern) for pattern in ignore_patterns): | |
continue | |
if modified_only and not is_file_modified(file_path): | |
continue | |
if not is_binary(file_path): | |
print(f'# {file_path}\n') | |
with open(file_path, 'r', encoding='utf-8') as f: | |
print(f.read()) | |
def get_files(target_dir, recursive=False): | |
files = [] | |
if recursive: | |
for root, _, filenames in os.walk(target_dir): | |
files.extend(os.path.join(root, filename) for filename in filenames) | |
else: | |
files = [os.path.join(target_dir, f) for f in os.listdir(target_dir) if os.path.isfile(os.path.join(target_dir, f))] | |
return files | |
if __name__ == "__main__": | |
parser = argparse.ArgumentParser(description="Concatenate files in a directory") | |
parser.add_argument("target_dir", help="Target directory (default: current directory)", nargs="?", default=".") | |
parser.add_argument("-r", "--recursive", help="Recursively process subdirectories", action="store_true") | |
parser.add_argument("-m", "--modified", help="Only include modified files (in git)", action="store_true") | |
parser.add_argument("--ignore", help="Ignore files matching patterns (e.g., *.css)", nargs="*", default=[]) | |
parser.add_argument("-o", "--only", help="Only process specified files", nargs="+") | |
args = parser.parse_args() | |
if args.only: | |
files = args.only | |
else: | |
files = get_files(args.target_dir, args.recursive) | |
concatenate_files(files, args.ignore, args.modified) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment