Skip to content

Instantly share code, notes, and snippets.

@nandhu-44
Created October 31, 2024 16:43
Show Gist options
  • Save nandhu-44/d442a683a6103132da369a428b138e8c to your computer and use it in GitHub Desktop.
Save nandhu-44/d442a683a6103132da369a428b138e8c to your computer and use it in GitHub Desktop.

Path-Walker

Ever felt like you have to provide your file structure to ChatGPT or Claude so that they can better understand and help you in your project? Well, I used this script to do it for one of my recent projects and helped me to not overexplain every detail to the AI and help it understand where all I need to apply changes.

import os
import fnmatch

def print_file_structure(root_dir, exclude_dirs=None, exclude_files=None, save_to_file=False, output_filename="file_structure.txt", prefix="", file=None):
    """
    Prints the file structure of a directory, excluding specified folders and files, and optionally saves it to a file.

    Parameters:
    - root_dir (str): The root directory to scan.
    - exclude_dirs (list): List of folder names to exclude.
    - exclude_files (list): List of file patterns to exclude (e.g., "*.py").
    - save_to_file (bool): Whether to save the output to a file.
    - output_filename (str): The filename to save the output if save_to_file is True.
    - prefix (str): The prefix string for the current depth level.
    - file (file object): File object used for recursive writing to file if save_to_file is True.
    """
    if exclude_dirs is None:
        exclude_dirs = []
    
    if exclude_files is None:
        exclude_files = []

    # Open the file for writing if save_to_file is True and it's the first call
    if save_to_file and file is None:
        file = open(output_filename, "w", encoding="utf-8")  # Set encoding to UTF-8
    
    try:
        # Get a list of items in the directory, excluding specified folders
        items = os.listdir(root_dir)
        items = [item for item in items if item not in exclude_dirs]

        for i, item in enumerate(items):
            item_path = os.path.join(root_dir, item)
            is_last = i == len(items) - 1

            # Choose the branch character based on whether it's the last item
            branch = "└── " if is_last else "├── "
            next_prefix = "    " if is_last else "│   "

            # Exclude files based on patterns in exclude_files
            if os.path.isfile(item_path) and any(fnmatch.fnmatch(item, pattern) for pattern in exclude_files):
                continue  # Skip excluded files

            # Prepare line for directory or file
            line = f"{prefix}{branch}📁 {item}" if os.path.isdir(item_path) else f"{prefix}{branch}📄 {item}"
            print(line)  # Print to console
            
            # Write to file if saving
            if save_to_file:
                file.write(line + "\n")

            # Recurse into directories with updated prefix
            if os.path.isdir(item_path):
                print_file_structure(item_path, exclude_dirs, exclude_files, save_to_file, output_filename, prefix + next_prefix, file)
    except PermissionError:
        line = f"{prefix}🚫 [Permission Denied] {root_dir}"
        print(line)
        if save_to_file:
            file.write(line + "\n")
    finally:
        # Close the file after the initial call finishes if saving to file
        if file and prefix == "":
            file.close()

# Usage
root_directory = "."
excluded_folders = [".next", "node_modules", "__pycache__", ".git"]
excluded_files = ["*.py"]

print_file_structure(root_directory, excluded_folders, excluded_files, save_to_file=True, output_filename="project_structure.txt")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment