로고조성현

Contextify

Useful when providing context to LLMs.

import os
import fnmatch
import io

def get_gitignore_patterns(directory):
    gitignore_path = os.path.join(directory, '.gitignore')
    if os.path.exists(gitignore_path):
        with open(gitignore_path, 'r') as f:
            return [line.strip() for line in f if line.strip() and not line.startswith('#')]
    return []

def should_ignore(path, ignore_patterns):
    for pattern in ignore_patterns:
        if fnmatch.fnmatch(path, pattern) or fnmatch.fnmatch(os.path.basename(path), pattern):
            return True
    return False

def process_files(directory):
    directories_to_ignore = [
        '.git',
        '__pycache__',
        'node_modules',
        'venv',
        'env',
        'migrations',
        'staticfiles',
        'static',
        'media',
        'dist',
        'build',
        'coverage',
        'client',
        '.next'
    ]
    files_to_ignore = [
        __file__,
        'contextify.py',
        '.gitignore',
        '.gitattributes',
        '.gitmodules',
        'requirements.txt',
        'yarn.lock',
        'package-lock.json',
        'pnpm-lock.yaml',
    ]
    extensions_to_include = [
        'ts',
        'tsx',
    ]

    ignore_patterns = get_gitignore_patterns(directory)
    output = io.StringIO()

    for root, dirs, files in os.walk(directory, topdown=True):
        files[:] = [f for f in files if f not in files_to_ignore]
        files[:] = [f for f in files if any(f.endswith(ext) for ext in extensions_to_include)]
        dirs[:] = [d for d in dirs if not should_ignore(os.path.join(root, d), ignore_patterns)]
        dirs[:] = [d for d in dirs if not any(fnmatch.fnmatch(d, pattern) for pattern in directories_to_ignore)]

        for file in files:
            file_path = os.path.join(root, file)

            if should_ignore(file_path, ignore_patterns):
                continue

            # get full path, relative to the directory
            output.write("```" + os.path.relpath(file_path, directory) + "\n")

            try:
                with open(file_path, 'r', encoding='utf-8') as f:
                    content = f.read()
                    output.write(content)
            except Exception as e:
                output.write(f"Error reading file: {e}\n")

            output.write("```\n\n")

    return output.getvalue()

# Usage
directory_path = "."  # Current directory, change this to the desired starting directory
result = process_files(directory_path)

# Print the result
print(result)


try:
    import pyperclip
    pyperclip.copy(result)
    print("Output has been copied to clipboard.")
except ModuleNotFoundError:
    print("module pyperclip not found")

try:
    with open("output.md", "w") as f:
        f.write(result)
    print("Output has been saved to output.md.")
except Exception as e:
    print(f"Error saving output: {e}")