mirror of
https://github.com/MLSysBook/TinyTorch.git
synced 2026-03-11 19:03:34 -05:00
Adds CLI tool for project setup and management
Introduces a command-line interface (CLI) named 'tito' to streamline project setup, testing, and information retrieval. Includes a setup script to automate virtual environment creation and dependency installation. Improves the user experience by providing clear instructions and status indicators within the CLI.
This commit is contained in:
29
bin/activate-tinytorch.sh
Executable file
29
bin/activate-tinytorch.sh
Executable file
@@ -0,0 +1,29 @@
|
||||
#!/bin/bash
|
||||
# TinyTorch Environment Activation & Setup
|
||||
|
||||
# Check if virtual environment exists, create if not
|
||||
if [ ! -d "tinytorch-env" ]; then
|
||||
echo "🆕 First time setup - creating environment..."
|
||||
python3 -m venv tinytorch-env || {
|
||||
echo "❌ Failed to create virtual environment"
|
||||
exit 1
|
||||
}
|
||||
echo "📦 Installing dependencies..."
|
||||
tinytorch-env/bin/pip install -r requirements.txt || {
|
||||
echo "❌ Failed to install dependencies"
|
||||
exit 1
|
||||
}
|
||||
echo "✅ Environment created!"
|
||||
fi
|
||||
|
||||
echo "🔥 Activating TinyTorch environment..."
|
||||
source tinytorch-env/bin/activate
|
||||
|
||||
# Create tito alias for convenience
|
||||
alias tito="python3 bin/tito.py"
|
||||
|
||||
echo "✅ Ready to build ML systems!"
|
||||
echo "💡 Quick commands:"
|
||||
echo " tito info - Check system status"
|
||||
echo " tito test - Run tests"
|
||||
echo " tito doctor - Diagnose issues"
|
||||
567
bin/tito.py
567
bin/tito.py
@@ -12,119 +12,517 @@ import sys
|
||||
import os
|
||||
import argparse
|
||||
from pathlib import Path
|
||||
import numpy as np
|
||||
|
||||
# Rich imports for beautiful terminal output
|
||||
from rich.console import Console
|
||||
from rich.table import Table
|
||||
from rich.panel import Panel
|
||||
from rich.text import Text
|
||||
from rich.tree import Tree
|
||||
from rich.progress import Progress, SpinnerColumn, BarColumn, TextColumn
|
||||
|
||||
# Add the project root to Python path
|
||||
sys.path.insert(0, str(Path(__file__).parent.parent))
|
||||
|
||||
# Create Rich console instance
|
||||
console = Console()
|
||||
|
||||
def print_banner():
|
||||
"""Print the TinyTorch banner."""
|
||||
print("🔥 Tiny🔥Torch: Build ML Systems from Scratch 🔥")
|
||||
print("=" * 50)
|
||||
"""Print the TinyTorch banner using Rich."""
|
||||
banner_text = Text("Tiny🔥Torch: Build ML Systems from Scratch", style="bold red")
|
||||
console.print(Panel(banner_text, style="bright_blue", padding=(1, 2)))
|
||||
|
||||
def check_setup_status():
|
||||
"""Check if setup project is complete."""
|
||||
try:
|
||||
from tinytorch.core.utils import hello_tinytorch
|
||||
return "✅ Implemented"
|
||||
except ImportError:
|
||||
return "❌ Not Implemented"
|
||||
|
||||
def check_tensor_status():
|
||||
"""Check if tensor project is complete."""
|
||||
try:
|
||||
from tinytorch.core.tensor import Tensor
|
||||
# Test actual functionality, not just import
|
||||
t1 = Tensor([1, 2, 3])
|
||||
t2 = Tensor([4, 5, 6])
|
||||
result = t1 + t2 # Should work if implemented
|
||||
return "✅ Implemented"
|
||||
except (ImportError, NotImplementedError):
|
||||
return "⏳ Not Started"
|
||||
|
||||
def check_mlp_status():
|
||||
"""Check if MLP project is complete."""
|
||||
try:
|
||||
from tinytorch.core.modules import MLP
|
||||
# Test actual functionality
|
||||
mlp = MLP(input_size=10, hidden_size=5, output_size=2)
|
||||
from tinytorch.core.tensor import Tensor
|
||||
x = Tensor([[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]])
|
||||
output = mlp(x) # Should work if implemented
|
||||
return "✅ Implemented"
|
||||
except (ImportError, NotImplementedError, AttributeError):
|
||||
return "⏳ Not Started"
|
||||
|
||||
def check_cnn_status():
|
||||
"""Check if CNN project is complete."""
|
||||
try:
|
||||
from tinytorch.core.modules import Conv2d
|
||||
# Test actual functionality
|
||||
conv = Conv2d(in_channels=3, out_channels=16, kernel_size=3)
|
||||
from tinytorch.core.tensor import Tensor
|
||||
x = Tensor(np.random.randn(1, 3, 32, 32))
|
||||
output = conv(x) # Should work if implemented
|
||||
return "✅ Implemented"
|
||||
except (ImportError, NotImplementedError, AttributeError):
|
||||
return "⏳ Not Started"
|
||||
|
||||
def check_data_status():
|
||||
"""Check if data project is complete."""
|
||||
try:
|
||||
from tinytorch.core.dataloader import DataLoader
|
||||
# Test actual functionality
|
||||
data = [(np.random.randn(3, 32, 32), 0) for _ in range(10)]
|
||||
loader = DataLoader(data, batch_size=2, shuffle=True)
|
||||
batch = next(iter(loader)) # Should work if implemented
|
||||
return "✅ Implemented"
|
||||
except (ImportError, NotImplementedError, AttributeError, StopIteration):
|
||||
return "⏳ Not Started"
|
||||
|
||||
def check_training_status():
|
||||
"""Check if training project is complete."""
|
||||
try:
|
||||
from tinytorch.core.optimizer import SGD
|
||||
from tinytorch.core.tensor import Tensor
|
||||
# Test actual functionality
|
||||
t = Tensor([1.0, 2.0, 3.0], requires_grad=True)
|
||||
optimizer = SGD([t], lr=0.01)
|
||||
t.backward() # Should work if autograd is implemented
|
||||
optimizer.step() # Should work if optimizer is implemented
|
||||
return "✅ Implemented"
|
||||
except (ImportError, NotImplementedError, AttributeError):
|
||||
return "⏳ Not Started"
|
||||
|
||||
def check_profiling_status():
|
||||
"""Check if profiling project is complete."""
|
||||
try:
|
||||
from tinytorch.core.profiler import Profiler
|
||||
# Test basic functionality
|
||||
profiler = Profiler()
|
||||
profiler.start("test")
|
||||
profiler.end("test")
|
||||
return "✅ Implemented"
|
||||
except (ImportError, NotImplementedError, AttributeError):
|
||||
return "⏳ Not Started"
|
||||
|
||||
def check_compression_status():
|
||||
"""Check if compression project is complete."""
|
||||
try:
|
||||
from tinytorch.core.compression import Pruner
|
||||
# Test basic functionality
|
||||
pruner = Pruner(sparsity=0.5)
|
||||
return "✅ Implemented"
|
||||
except (ImportError, NotImplementedError, AttributeError):
|
||||
return "⏳ Not Started"
|
||||
|
||||
def check_kernels_status():
|
||||
"""Check if kernels project is complete."""
|
||||
try:
|
||||
from tinytorch.core.kernels import optimized_matmul
|
||||
# Test basic functionality
|
||||
a = np.random.randn(3, 3)
|
||||
b = np.random.randn(3, 3)
|
||||
result = optimized_matmul(a, b)
|
||||
return "✅ Implemented"
|
||||
except (ImportError, NotImplementedError, AttributeError):
|
||||
return "⏳ Not Started"
|
||||
|
||||
def check_benchmarking_status():
|
||||
"""Check if benchmarking project is complete."""
|
||||
try:
|
||||
from tinytorch.core.benchmark import Benchmark
|
||||
# Test basic functionality
|
||||
benchmark = Benchmark()
|
||||
return "✅ Implemented"
|
||||
except (ImportError, NotImplementedError, AttributeError):
|
||||
return "⏳ Not Started"
|
||||
|
||||
def check_mlops_status():
|
||||
"""Check if MLOps project is complete."""
|
||||
try:
|
||||
from tinytorch.core.mlops import ModelMonitor
|
||||
from tinytorch.core.tensor import Tensor
|
||||
# Test that the methods are actually implemented, not just placeholders
|
||||
monitor = ModelMonitor(model=None, baseline_metrics={})
|
||||
# Try to use a method that should be implemented
|
||||
test_inputs = Tensor([1.0, 2.0, 3.0])
|
||||
test_predictions = Tensor([0.5, 0.8, 0.2])
|
||||
monitor.log_prediction(test_inputs, test_predictions)
|
||||
return "✅ Implemented"
|
||||
except (ImportError, NotImplementedError, AttributeError, TypeError):
|
||||
return "⏳ Not Started"
|
||||
|
||||
def validate_environment():
|
||||
"""Validate environment setup before running commands."""
|
||||
issues = []
|
||||
|
||||
# Check virtual environment
|
||||
in_venv = (hasattr(sys, 'real_prefix') or
|
||||
(hasattr(sys, 'base_prefix') and sys.base_prefix != sys.prefix))
|
||||
if not in_venv:
|
||||
issues.append("Virtual environment not activated. Run: source tinytorch-env/bin/activate")
|
||||
|
||||
# Check Python version
|
||||
if sys.version_info < (3, 8):
|
||||
issues.append(f"Python 3.8+ required, found {sys.version_info.major}.{sys.version_info.minor}")
|
||||
|
||||
# Check core dependencies
|
||||
try:
|
||||
import numpy
|
||||
import pytest
|
||||
except ImportError as e:
|
||||
issues.append(f"Missing dependency: {e.name}. Run: pip install -r requirements.txt")
|
||||
|
||||
# Check TinyTorch package structure
|
||||
tinytorch_path = Path(__file__).parent.parent / "tinytorch"
|
||||
if not tinytorch_path.exists():
|
||||
issues.append("TinyTorch package not found. Check project structure.")
|
||||
|
||||
if issues:
|
||||
issue_text = Text()
|
||||
issue_text.append("❌ Environment Issues Detected\n\n", style="bold red")
|
||||
for issue in issues:
|
||||
issue_text.append(f" • {issue}\n", style="yellow")
|
||||
issue_text.append("\nRun 'python3 bin/tito.py doctor' for detailed diagnosis", style="dim")
|
||||
|
||||
console.print(Panel(issue_text, title="Environment Problems", border_style="red"))
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
def cmd_version(args):
|
||||
"""Show TinyTorch version."""
|
||||
print("Tiny🔥Torch v0.1.0")
|
||||
print("Machine Learning Systems Course")
|
||||
version_text = Text()
|
||||
version_text.append("Tiny🔥Torch v0.1.0\n", style="bold red")
|
||||
version_text.append("Machine Learning Systems Course", style="cyan")
|
||||
console.print(Panel(version_text, title="Version Info", border_style="bright_blue"))
|
||||
|
||||
def cmd_info(args):
|
||||
"""Show system information and status."""
|
||||
print_banner()
|
||||
print()
|
||||
console.print()
|
||||
|
||||
# Python environment info
|
||||
print("📋 System Information")
|
||||
print("-" * 30)
|
||||
print(f"Python: {sys.version.split()[0]}")
|
||||
print(f"Platform: {sys.platform}")
|
||||
print(f"Working Directory: {os.getcwd()}")
|
||||
# System Information Panel
|
||||
info_text = Text()
|
||||
info_text.append(f"Python: {sys.version.split()[0]}\n", style="cyan")
|
||||
info_text.append(f"Platform: {sys.platform}\n", style="cyan")
|
||||
info_text.append(f"Working Directory: {os.getcwd()}\n", style="cyan")
|
||||
|
||||
# Virtual environment check
|
||||
in_venv = (hasattr(sys, 'real_prefix') or
|
||||
(hasattr(sys, 'base_prefix') and sys.base_prefix != sys.prefix))
|
||||
venv_status = "✅ Active" if in_venv else "❌ Not Active"
|
||||
print(f"Virtual Environment: {venv_status}")
|
||||
# Virtual environment check - use same robust detection as doctor
|
||||
venv_path = Path("tinytorch-env")
|
||||
venv_exists = venv_path.exists()
|
||||
in_venv = (
|
||||
# Method 1: Check VIRTUAL_ENV environment variable (most reliable for activation)
|
||||
os.environ.get('VIRTUAL_ENV') is not None or
|
||||
# Method 2: Check sys.prefix vs sys.base_prefix (works for running Python in venv)
|
||||
(hasattr(sys, 'base_prefix') and sys.base_prefix != sys.prefix) or
|
||||
# Method 3: Check for sys.real_prefix (older Python versions)
|
||||
hasattr(sys, 'real_prefix')
|
||||
)
|
||||
|
||||
print()
|
||||
if venv_exists and in_venv:
|
||||
venv_style = "green"
|
||||
venv_icon = "✅"
|
||||
venv_status = "Ready & Active"
|
||||
elif venv_exists:
|
||||
venv_style = "yellow"
|
||||
venv_icon = "✅"
|
||||
venv_status = "Ready (Not Active)"
|
||||
else:
|
||||
venv_style = "red"
|
||||
venv_icon = "❌"
|
||||
venv_status = "Not Found"
|
||||
|
||||
# Course navigation
|
||||
print("📋 Course Navigation")
|
||||
print("-" * 30)
|
||||
print("📖 Course Overview: README.md")
|
||||
print("🎯 Detailed Guide: COURSE_GUIDE.md")
|
||||
print("🚀 Start Here: projects/setup/README.md")
|
||||
info_text.append(f"Virtual Environment: {venv_icon} ", style=venv_style)
|
||||
info_text.append(venv_status, style=f"bold {venv_style}")
|
||||
|
||||
print()
|
||||
console.print(Panel(info_text, title="📋 System Information", border_style="bright_blue"))
|
||||
console.print()
|
||||
|
||||
# Course Navigation Panel
|
||||
nav_text = Text()
|
||||
nav_text.append("📖 Course Overview: ", style="dim")
|
||||
nav_text.append("README.md\n", style="cyan underline")
|
||||
nav_text.append("🎯 Detailed Guide: ", style="dim")
|
||||
nav_text.append("COURSE_GUIDE.md\n", style="cyan underline")
|
||||
nav_text.append("🚀 Start Here: ", style="dim")
|
||||
nav_text.append("projects/setup/README.md", style="cyan underline")
|
||||
|
||||
console.print(Panel(nav_text, title="📋 Course Navigation", border_style="bright_green"))
|
||||
console.print()
|
||||
|
||||
# Implementation status
|
||||
print("🚀 Implementation Status")
|
||||
print("-" * 30)
|
||||
projects = [
|
||||
("Setup", "hello_tinytorch function", check_setup_status),
|
||||
("Tensor", "basic tensor operations", check_tensor_status),
|
||||
("MLP", "multi-layer perceptron (manual)", check_mlp_status),
|
||||
("CNN", "convolutional networks (basic)", check_cnn_status),
|
||||
("Data", "data loading pipeline", check_data_status),
|
||||
("Training", "autograd engine & optimization", check_training_status),
|
||||
("Profiling", "performance profiling", check_profiling_status),
|
||||
("Compression", "model compression", check_compression_status),
|
||||
("Kernels", "custom compute kernels", check_kernels_status),
|
||||
("Benchmarking", "performance benchmarking", check_benchmarking_status),
|
||||
("MLOps", "production monitoring", check_mlops_status),
|
||||
]
|
||||
|
||||
# Check if hello function exists
|
||||
try:
|
||||
from tinytorch.core.utils import hello_tinytorch
|
||||
hello_status = "✅ Implemented"
|
||||
if args.hello:
|
||||
print(f"Hello Message: {hello_tinytorch()}")
|
||||
except ImportError:
|
||||
hello_status = "❌ Not Implemented"
|
||||
# Project Status Table
|
||||
status_table = Table(title="🚀 Project Implementation Status", show_header=True, header_style="bold blue")
|
||||
status_table.add_column("ID", style="dim", width=3, justify="center")
|
||||
status_table.add_column("Project", style="bold cyan", width=12)
|
||||
status_table.add_column("Status", width=18, justify="center")
|
||||
status_table.add_column("Description", style="dim", width=40)
|
||||
|
||||
print(f"hello_tinytorch(): {hello_status}")
|
||||
for i, (name, desc, check_func) in enumerate(projects):
|
||||
status_text = check_func()
|
||||
if "✅" in status_text:
|
||||
status_style = "[green]✅ Implemented[/green]"
|
||||
elif "❌" in status_text:
|
||||
status_style = "[red]❌ Not Implemented[/red]"
|
||||
else:
|
||||
status_style = "[yellow]⏳ Not Started[/yellow]"
|
||||
|
||||
status_table.add_row(str(i), name, status_style, desc)
|
||||
|
||||
# TODO: Add checks for other components as they're implemented
|
||||
print("tensor operations: ⏳ Coming in Project 1")
|
||||
print("autograd engine: ⏳ Coming in Project 4")
|
||||
print("neural networks: ⏳ Coming in Project 2")
|
||||
print("training system: ⏳ Coming in Project 6")
|
||||
console.print(status_table)
|
||||
|
||||
if args.hello and check_setup_status() == "✅ Implemented":
|
||||
try:
|
||||
from tinytorch.core.utils import hello_tinytorch
|
||||
hello_text = Text(hello_tinytorch(), style="bold red")
|
||||
console.print()
|
||||
console.print(Panel(hello_text, style="bright_red", padding=(1, 2)))
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
if args.show_architecture:
|
||||
print()
|
||||
print("🏗️ System Architecture")
|
||||
print("-" * 30)
|
||||
print("""
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ TinyTorch System │
|
||||
├─────────────────────────────────────────────────────────────┤
|
||||
│ CLI Interface (bin/tito.py) │
|
||||
├─────────────────────────────────────────────────────────────┤
|
||||
│ Training Orchestration (trainer.py) │
|
||||
├─────────────────────────────────────────────────────────────┤
|
||||
│ Model Definition │ Data Pipeline │ Optimization │
|
||||
│ (modules.py) │ (dataloader.py) │ (optimizer.py) │
|
||||
├─────────────────────────────────────────────────────────────┤
|
||||
│ Automatic Differentiation Engine (autograd) │
|
||||
├─────────────────────────────────────────────────────────────┤
|
||||
│ Tensor Operations & Storage (tensor.py) │
|
||||
├─────────────────────────────────────────────────────────────┤
|
||||
│ Profiling & MLOps (profiler.py, mlops.py) │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
""")
|
||||
console.print()
|
||||
|
||||
# Create architecture tree
|
||||
arch_tree = Tree("🏗️ TinyTorch System Architecture", style="bold blue")
|
||||
|
||||
cli_branch = arch_tree.add("CLI Interface", style="cyan")
|
||||
cli_branch.add("bin/tito.py - Command line tools", style="dim")
|
||||
|
||||
training_branch = arch_tree.add("Training Orchestration", style="cyan")
|
||||
training_branch.add("trainer.py - Training loop management", style="dim")
|
||||
|
||||
core_branch = arch_tree.add("Core Components", style="cyan")
|
||||
model_sub = core_branch.add("Model Definition", style="yellow")
|
||||
model_sub.add("modules.py - Neural network layers", style="dim")
|
||||
|
||||
data_sub = core_branch.add("Data Pipeline", style="yellow")
|
||||
data_sub.add("dataloader.py - Efficient data loading", style="dim")
|
||||
|
||||
opt_sub = core_branch.add("Optimization", style="yellow")
|
||||
opt_sub.add("optimizer.py - SGD, Adam, etc.", style="dim")
|
||||
|
||||
autograd_branch = arch_tree.add("Automatic Differentiation Engine", style="cyan")
|
||||
autograd_branch.add("autograd.py - Gradient computation", style="dim")
|
||||
|
||||
tensor_branch = arch_tree.add("Tensor Operations & Storage", style="cyan")
|
||||
tensor_branch.add("tensor.py - Core tensor implementation", style="dim")
|
||||
|
||||
system_branch = arch_tree.add("System Tools", style="cyan")
|
||||
system_branch.add("profiler.py - Performance measurement", style="dim")
|
||||
system_branch.add("mlops.py - Production monitoring", style="dim")
|
||||
|
||||
console.print(Panel(arch_tree, title="🏗️ System Architecture", border_style="bright_blue"))
|
||||
|
||||
def cmd_test(args):
|
||||
"""Run tests for a specific project."""
|
||||
print(f"🧪 Running tests for project: {args.project}")
|
||||
valid_projects = ["setup", "tensor", "mlp", "cnn", "data", "training",
|
||||
"profiling", "compression", "kernels", "benchmarking", "mlops"]
|
||||
|
||||
if args.project == "setup":
|
||||
# Run setup tests
|
||||
if args.all:
|
||||
# Run all tests with progress bar
|
||||
import subprocess
|
||||
test_file = "projects/setup/test_setup.py"
|
||||
failed_projects = []
|
||||
|
||||
# Count existing test files
|
||||
existing_tests = [p for p in valid_projects if Path(f"projects/{p}/test_{p}.py").exists()]
|
||||
|
||||
console.print(Panel(f"🧪 Running tests for {len(existing_tests)} projects",
|
||||
title="Test Suite", border_style="bright_cyan"))
|
||||
|
||||
with Progress(
|
||||
SpinnerColumn(),
|
||||
TextColumn("[progress.description]{task.description}"),
|
||||
BarColumn(),
|
||||
TextColumn("[progress.percentage]{task.percentage:>3.0f}%"),
|
||||
console=console
|
||||
) as progress:
|
||||
|
||||
task = progress.add_task("Running tests...", total=len(existing_tests))
|
||||
|
||||
for project in existing_tests:
|
||||
progress.update(task, description=f"Testing {project}...")
|
||||
|
||||
test_file = f"projects/{project}/test_{project}.py"
|
||||
result = subprocess.run([sys.executable, "-m", "pytest", test_file, "-v"],
|
||||
capture_output=True, text=True)
|
||||
|
||||
if result.returncode != 0:
|
||||
failed_projects.append(project)
|
||||
console.print(f"[red]❌ {project} tests failed[/red]")
|
||||
else:
|
||||
console.print(f"[green]✅ {project} tests passed[/green]")
|
||||
|
||||
progress.advance(task)
|
||||
|
||||
# Results summary
|
||||
if failed_projects:
|
||||
console.print(Panel(f"[red]❌ Failed projects: {', '.join(failed_projects)}[/red]",
|
||||
title="Test Results", border_style="red"))
|
||||
return 1
|
||||
else:
|
||||
console.print(Panel("[green]✅ All tests passed![/green]",
|
||||
title="Test Results", border_style="green"))
|
||||
return 0
|
||||
|
||||
elif args.project in valid_projects:
|
||||
# Run specific project tests
|
||||
import subprocess
|
||||
test_file = f"projects/{args.project}/test_{args.project}.py"
|
||||
|
||||
console.print(Panel(f"🧪 Running tests for project: [bold cyan]{args.project}[/bold cyan]",
|
||||
title="Single Project Test", border_style="bright_cyan"))
|
||||
|
||||
if not Path(test_file).exists():
|
||||
console.print(Panel(f"[yellow]⏳ Test file not found: {test_file}\n"
|
||||
f"Project '{args.project}' may not be implemented yet.[/yellow]",
|
||||
title="Test Not Found", border_style="yellow"))
|
||||
return 1
|
||||
|
||||
console.print(f"[dim]Running: pytest {test_file} -v[/dim]")
|
||||
console.print()
|
||||
|
||||
result = subprocess.run([sys.executable, "-m", "pytest", test_file, "-v"],
|
||||
capture_output=False)
|
||||
|
||||
# Show result summary
|
||||
if result.returncode == 0:
|
||||
console.print(Panel(f"[green]✅ All tests passed for {args.project}![/green]",
|
||||
title="Test Results", border_style="green"))
|
||||
else:
|
||||
console.print(Panel(f"[red]❌ Some tests failed for {args.project}[/red]",
|
||||
title="Test Results", border_style="red"))
|
||||
|
||||
return result.returncode
|
||||
else:
|
||||
print(f"Tests for project '{args.project}' not yet implemented.")
|
||||
console.print(Panel(f"[red]❌ Unknown project: {args.project}[/red]\n"
|
||||
f"Valid projects: {', '.join(valid_projects)}",
|
||||
title="Invalid Project", border_style="red"))
|
||||
return 1
|
||||
|
||||
def cmd_submit(args):
|
||||
"""Submit project for grading."""
|
||||
print(f"📤 Submitting project: {args.project}")
|
||||
print("🚧 Submission system not yet implemented.")
|
||||
print("For now, make sure all tests pass with:")
|
||||
print(f" python -m pytest projects/{args.project}/test_*.py -v")
|
||||
submit_text = Text()
|
||||
submit_text.append(f"📤 Submitting project: {args.project}\n\n", style="bold cyan")
|
||||
submit_text.append("🚧 Submission system not yet implemented.\n\n", style="yellow")
|
||||
submit_text.append("For now, make sure all tests pass with:\n", style="dim")
|
||||
submit_text.append(f" python -m pytest projects/{args.project}/test_*.py -v", style="bold white")
|
||||
|
||||
console.print(Panel(submit_text, title="Project Submission", border_style="bright_yellow"))
|
||||
|
||||
def cmd_status(args):
|
||||
"""Check project status."""
|
||||
print(f"📊 Status for project: {args.project}")
|
||||
print("🚧 Status system not yet implemented.")
|
||||
status_text = Text()
|
||||
status_text.append(f"📊 Status for project: {args.project}\n\n", style="bold cyan")
|
||||
status_text.append("🚧 Status system not yet implemented.", style="yellow")
|
||||
|
||||
console.print(Panel(status_text, title="Project Status", border_style="bright_yellow"))
|
||||
|
||||
|
||||
|
||||
|
||||
def cmd_doctor(args):
|
||||
"""Run comprehensive environment diagnosis."""
|
||||
console.print(Panel("🔬 TinyTorch Environment Diagnosis",
|
||||
title="System Doctor", border_style="bright_magenta"))
|
||||
console.print()
|
||||
|
||||
# Environment checks table
|
||||
env_table = Table(title="Environment Check", show_header=True, header_style="bold blue")
|
||||
env_table.add_column("Component", style="cyan", width=20)
|
||||
env_table.add_column("Status", justify="left")
|
||||
env_table.add_column("Details", style="dim", width=30)
|
||||
|
||||
# Python environment
|
||||
env_table.add_row("Python", "[green]✅ OK[/green]", f"{sys.version.split()[0]} ({sys.platform})")
|
||||
|
||||
# Virtual environment - check if it exists and if we're using it
|
||||
venv_path = Path("tinytorch-env")
|
||||
venv_exists = venv_path.exists()
|
||||
in_venv = (
|
||||
# Method 1: Check VIRTUAL_ENV environment variable (most reliable for activation)
|
||||
os.environ.get('VIRTUAL_ENV') is not None or
|
||||
# Method 2: Check sys.prefix vs sys.base_prefix (works for running Python in venv)
|
||||
(hasattr(sys, 'base_prefix') and sys.base_prefix != sys.prefix) or
|
||||
# Method 3: Check for sys.real_prefix (older Python versions)
|
||||
hasattr(sys, 'real_prefix')
|
||||
)
|
||||
|
||||
if venv_exists and in_venv:
|
||||
venv_status = "[green]✅ Ready & Active[/green]"
|
||||
elif venv_exists:
|
||||
venv_status = "[yellow]✅ Ready (Not Active)[/yellow]"
|
||||
else:
|
||||
venv_status = "[red]❌ Not Found[/red]"
|
||||
env_table.add_row("Virtual Environment", venv_status, "tinytorch-env")
|
||||
|
||||
# Dependencies
|
||||
dependencies = ['numpy', 'matplotlib', 'pytest', 'yaml', 'black', 'rich']
|
||||
for dep in dependencies:
|
||||
try:
|
||||
module = __import__(dep)
|
||||
version = getattr(module, '__version__', 'unknown')
|
||||
env_table.add_row(dep.title(), "[green]✅ OK[/green]", f"v{version}")
|
||||
except ImportError:
|
||||
env_table.add_row(dep.title(), "[red]❌ Missing[/red]", "Not installed")
|
||||
|
||||
console.print(env_table)
|
||||
console.print()
|
||||
|
||||
# Project structure table
|
||||
struct_table = Table(title="Project Structure", show_header=True, header_style="bold magenta")
|
||||
struct_table.add_column("Path", style="cyan", width=25)
|
||||
struct_table.add_column("Status", justify="left")
|
||||
struct_table.add_column("Type", style="dim", width=25)
|
||||
|
||||
required_paths = [
|
||||
('tinytorch/', 'Package directory'),
|
||||
('tinytorch/core/', 'Core module directory'),
|
||||
('projects/', 'Project directory'),
|
||||
('bin/tito.py', 'CLI script'),
|
||||
('requirements.txt', 'Dependencies file')
|
||||
]
|
||||
|
||||
for path, desc in required_paths:
|
||||
if Path(path).exists():
|
||||
struct_table.add_row(path, "[green]✅ Found[/green]", desc)
|
||||
else:
|
||||
struct_table.add_row(path, "[red]❌ Missing[/red]", desc)
|
||||
|
||||
console.print(struct_table)
|
||||
console.print()
|
||||
|
||||
# Project implementations
|
||||
console.print(Panel("📋 Implementation Status",
|
||||
title="Project Status", border_style="bright_blue"))
|
||||
cmd_info(argparse.Namespace(hello=False, show_architecture=False))
|
||||
|
||||
def main():
|
||||
"""Main CLI entry point."""
|
||||
@@ -136,6 +534,8 @@ def main():
|
||||
|
||||
subparsers = parser.add_subparsers(dest="command", help="Available commands")
|
||||
|
||||
|
||||
|
||||
# Info command
|
||||
info_parser = subparsers.add_parser("info", help="Show system information")
|
||||
info_parser.add_argument("--hello", action="store_true", help="Show hello message")
|
||||
@@ -143,7 +543,8 @@ def main():
|
||||
|
||||
# Test command
|
||||
test_parser = subparsers.add_parser("test", help="Run project tests")
|
||||
test_parser.add_argument("--project", required=True, help="Project to test")
|
||||
test_parser.add_argument("--project", help="Project to test")
|
||||
test_parser.add_argument("--all", action="store_true", help="Run all project tests")
|
||||
|
||||
# Submit command
|
||||
submit_parser = subparsers.add_parser("submit", help="Submit project")
|
||||
@@ -153,6 +554,9 @@ def main():
|
||||
status_parser = subparsers.add_parser("status", help="Check project status")
|
||||
status_parser.add_argument("--project", required=True, help="Project to check")
|
||||
|
||||
# Doctor command
|
||||
doctor_parser = subparsers.add_parser("doctor", help="Run environment diagnosis")
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
# Handle version flag
|
||||
@@ -160,6 +564,19 @@ def main():
|
||||
cmd_version(args)
|
||||
return 0
|
||||
|
||||
# Environment validation (skip for doctor and info commands)
|
||||
if args.command not in ["doctor", "info"] and not validate_environment():
|
||||
return 1
|
||||
|
||||
# Validate test command arguments
|
||||
if args.command == "test":
|
||||
if not args.all and not args.project:
|
||||
error_text = Text()
|
||||
error_text.append("❌ Error: Must specify either --project or --all\n\n", style="bold red")
|
||||
error_text.append("Usage: python bin/tito.py test --project <name> | --all", style="cyan")
|
||||
console.print(Panel(error_text, title="Invalid Arguments", border_style="red"))
|
||||
return 1
|
||||
|
||||
# Handle commands
|
||||
if args.command == "info":
|
||||
cmd_info(args)
|
||||
@@ -169,6 +586,8 @@ def main():
|
||||
cmd_submit(args)
|
||||
elif args.command == "status":
|
||||
cmd_status(args)
|
||||
elif args.command == "doctor":
|
||||
cmd_doctor(args)
|
||||
else:
|
||||
parser.print_help()
|
||||
return 1
|
||||
|
||||
Reference in New Issue
Block a user