Skip to content

scaffold_kit.checklist

Generates a checklist of files in a directory.

This module scans the current directory and creates a text-based checklist of all files, excluding those specified in an ignore file (e.g., .gitignore). Each file in the checklist is marked with an ‘[x]’ if it contains content or ‘[ ]’ if it is empty. The final checklist is saved to a file and printed to the console.

Usage

To run this script, navigate to your project’s root directory and execute it as a module:

$ uv run python -m scaffold_kit.checklist

file_is_empty(file_path) #

Checks if a file is empty by checking its size.

Parameters:

Name Type Description Default
file_path str

The path to the file.

required

Returns:

Type Description
bool

True if the file’s size is 0 bytes, False otherwise.

Source code in src/scaffold_kit/checklist.py
def file_is_empty(file_path: str) -> bool:
    """Checks if a file is empty by checking its size.

    Args:
        file_path: The path to the file.

    Returns:
        True if the file's size is 0 bytes, False otherwise.
    """
    try:
        # Use os.stat to get file size directly without opening the file.
        return os.stat(file_path).st_size == 0
    except OSError as e:
        print(f"Error getting file stats for {file_path}: {e}", file=sys.stderr)
        return False

generate_checklist(ignore_file='.gitignore', output_file='checklist.txt', output_dir=None) #

Generates a checklist of files and directories in the current directory.

The traversal is hierarchical. Within each directory, entries are sorted case-insensitively with directories first and then files. Directories are always marked “[x]”. Files are marked “[ ]” if empty and “[x]” otherwise. Paths matching patterns from the ignore file are skipped. The checklist is written to the output location and printed to stdout.

Parameters:

Name Type Description Default
ignore_file str

Name of the ignore file with patterns (e.g., “.gitignore”).

'.gitignore'
output_file str

Name of the output checklist file.

'checklist.txt'
output_dir Optional[str]

Directory for the output file. Created if it does not exist.

None

Raises:

Type Description
OSError

If writing the checklist file fails due to I/O errors.

Source code in src/scaffold_kit/checklist.py
def generate_checklist(
    ignore_file: str = ".gitignore",
    output_file: str = "checklist.txt",
    output_dir: Optional[str] = None,
):
    """Generates a checklist of files and directories in the current directory.

    The traversal is hierarchical. Within each directory, entries are sorted
    case-insensitively with directories first and then files. Directories are
    always marked "[x]". Files are marked "[ ]" if empty and "[x]" otherwise.
    Paths matching patterns from the ignore file are skipped. The checklist is
    written to the output location and printed to stdout.

    Args:
        ignore_file: Name of the ignore file with patterns (e.g., ".gitignore").
        output_file: Name of the output checklist file.
        output_dir: Directory for the output file. Created if it does not exist.

    Raises:
        OSError: If writing the checklist file fails due to I/O errors.
    """
    parser = IgnoreParser.from_file(ignore_file)

    # Walk from current directory, hierarchical & sorted
    all_paths = walk_sorted(Path.cwd())

    lines = []
    for path in all_paths:
        p = Path(path)

        if parser.matches(path):
            continue

        if p.is_dir():
            # Directories always non-empty
            lines.append(f"[x] {path}/")
        else:
            mark = " " if file_is_empty(str(p)) else "x"
            lines.append(f"[{mark}] {path}")

    content = "\n".join(lines)

    if output_dir and not os.path.exists(output_dir):
        os.makedirs(output_dir)
        print(f"Directory '{output_dir}' created successfully!")

    output_filename = (
        f"{slugify(Path(output_file).stem)}{Path(output_file).suffix}"
    )
    output_path = Path(output_dir) / output_filename

    print(f"Writing {output_path}...")
    with open(output_path, "w", encoding="utf-8") as f:
        f.write(content)

    print(f"{content}\n")
    print(f"\nSuccessfully wrote checklist to {output_path}")

main() #

Main entry point to run the checklist generation process.

Source code in src/scaffold_kit/checklist.py
def main():
    """Main entry point to run the checklist generation process."""
    generate_checklist(
        ignore_file=IGNORE_FILE,
        output_file=CHECKLIST_FILE,
        output_dir=CHECKLIST_DIRECTORY,
    )

walk_sorted(base, root=None) #

Walks a directory tree and returns relative paths in hierarchical order.

Directories appear before files within each directory, both sorted case-insensitively. Parent directories are listed before their children.

Parameters:

Name Type Description Default
base Path

The base path to walk.

required
root Path | None

The root used to compute relative paths. Defaults to the base.

None

Returns:

Type Description
list[str]

A list of relative paths as strings in stable, hierarchical order.

Source code in src/scaffold_kit/checklist.py
def walk_sorted(base: Path, root: Path | None = None) -> list[str]:
    """Walks a directory tree and returns relative paths in hierarchical order.

    Directories appear before files within each directory, both sorted
    case-insensitively. Parent directories are listed before their children.

    Args:
        base: The base path to walk.
        root: The root used to compute relative paths. Defaults to the base.

    Returns:
        A list of relative paths as strings in stable, hierarchical order.
    """
    if root is None:
        root = base

    results: list[str] = []

    # Sort entries: directories first, then files, both alphabetically
    # (casefold).
    entries = sorted(
        base.iterdir(),
        key=lambda p: (p.is_file(), p.name.casefold()),
    )

    for entry in entries:
        rel = str(entry.relative_to(root))
        results.append(rel)
        if entry.is_dir():
            results.extend(walk_sorted(entry, root))
    return results