File size: 4,600 Bytes
71a9077
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
#!/usr/bin/env python3
"""
Script to detect empty cells in marimo notebooks.

An empty cell is defined as:
@app.cell
def _():
    return

This script will:
1. Find all Python files in the repository
2. Check if they contain marimo app definitions
3. Look for empty cell patterns
4. Report any empty cells found
"""

import os
import re
import sys
from pathlib import Path
from typing import List, Tuple


def is_marimo_notebook(file_path: Path) -> bool:
    """Check if a Python file is a marimo notebook."""
    try:
        with open(file_path, 'r', encoding='utf-8') as f:
            content = f.read()
            # Look for marimo app defn
            return 'marimo.App' in content and '@app.cell' in content
    except (UnicodeDecodeError, IOError):
        return False


def find_empty_cells(file_path: Path) -> List[Tuple[int, str]]:
    """Find empty cells in a marimo notebook."""
    empty_cells = []
    
    try:
        with open(file_path, 'r', encoding='utf-8') as f:
            lines = f.readlines()
    except (UnicodeDecodeError, IOError):
        return empty_cells
    
    i = 0
    while i < len(lines):
        line = lines[i].strip()
        
        # if line starts with @app.cell decorator
        if line.startswith('@app.cell'):
            # look for the function definition on the next non-empty line
            j = i + 1
            while j < len(lines) and not lines[j].strip():
                j += 1
            
            if j < len(lines) and lines[j].strip() == 'def _():':
                # found function definition, now look for return statement
                k = j + 1
                while k < len(lines) and not lines[k].strip():
                    k += 1
                
                if k < len(lines) and lines[k].strip() == 'return':
                    # if any content after return (before next @app.cell or end of file)
                    has_content = False
                    m = k + 1
                    while m < len(lines):
                        line_content = lines[m].strip()
                        if line_content.startswith('@app.cell'):
                            break
                        if line_content and not line_content.startswith('#'):
                            has_content = True
                            break
                        m += 1
                    
                    if not has_content:
                        empty_cells.append((i + 1, lines[i].strip()))
                
                i = k + 1
            else:
                i += 1
        else:
            i += 1
    
    return empty_cells


def main():
    """Main function to check for empty cells."""
    print("πŸ” Checking for empty cells in marimo notebooks...")
    
    python_files = []
    for root, dirs, files in os.walk('.'):
        # skip hidden directories and common build/cache
        dirs[:] = [d for d in dirs if not d.startswith('.') and d not in ['__pycache__', 'node_modules', 'build', 'dist']]
        
        for file in files:
            if file.endswith('.py'):
                python_files.append(Path(root) / file)
    
    marimo_notebooks = []
    for file_path in python_files:
        if is_marimo_notebook(file_path):
            marimo_notebooks.append(file_path)
    
    print(f"πŸ“ Found {len(marimo_notebooks)} marimo notebooks")
    
    # each notebook checked for empty cells
    total_empty_cells = 0
    files_with_empty_cells = []
    
    for notebook_path in marimo_notebooks:
        empty_cells = find_empty_cells(notebook_path)
        if empty_cells:
            total_empty_cells += len(empty_cells)
            files_with_empty_cells.append((notebook_path, empty_cells))
            print(f"❌ {notebook_path}: {len(empty_cells)} empty cell(s)")
            for line_num, line_content in empty_cells:
                print(f"   Line {line_num}: {line_content}")
    
    if files_with_empty_cells:
        print(f"\nπŸ’₯ Found {total_empty_cells} empty cells in {len(files_with_empty_cells)} files")
        print("\nEmpty cells should be removed or contain meaningful content.")
        print("An empty cell looks like:")
        print("@app.cell")
        print("def _():")
        print("    return")
        print("\nConsider either:")
        print("1. Removing the empty cell entirely")
        print("2. Adding meaningful content to the cell")
        print("3. Adding a comment explaining why the cell is empty")
        
        sys.exit(1)
    else:
        print("βœ… No empty cells found!")
        sys.exit(0)


if __name__ == "__main__":
    main()