# Code Examples: Security-Focused CWD Operations
## Basic Usage Examples
### 1. Simple Tool Without Repository Parameter
```python
# Before: Tool with optional repo_path
@mcp.tool()
def get_git_status(repo_path: Optional[str] = None) -> Dict[str, Any]:
"""Get git status - accepts repo_path."""
if repo_path is None:
repo_path = get_repository_path()
service = CommitzenService(repo_path=repo_path)
return service.get_repository_status()
# After: Tool without repo_path - CWD only
@mcp.tool()
def get_git_status() -> Dict[str, Any]:
"""Get git status for current working directory."""
# Validate CWD is a git repository
manager = SecureRepositoryManager()
if not manager.validate_git_repository():
return create_error_response(
RepositoryError("Current directory is not a git repository")
)
# Always use CWD
service = CommitzenService()
return service.get_repository_status()
```
### 2. Handling Different Directory Types
```python
@mcp.tool()
def analyze_directory() -> Dict[str, Any]:
"""Analyze current directory with appropriate operations."""
manager = SecureRepositoryManager()
# Basic validation
if not manager.validate_cwd():
return create_error_response(
RepositoryError("Invalid current working directory")
)
result = {
"directory": os.getcwd(),
"is_git_repository": manager.is_git_repository(),
"analysis": {}
}
# Provide different analysis based on directory type
if manager.is_git_repository():
# Full git analysis
result["analysis"]["type"] = "git"
result["analysis"]["branch"] = get_current_branch()
result["analysis"]["status"] = get_git_status()
else:
# Basic directory analysis
result["analysis"]["type"] = "directory"
result["analysis"]["file_count"] = len(os.listdir(os.getcwd()))
return create_success_response(result)
```
## Service Layer Examples
### 3. Service Without Path Parameters
```python
# Before: Service with repo_path parameter
class CommitzenService:
def __init__(self, repo_path: str):
self.repo_path = repo_path
self._validate_path()
self._initialize_commitizen()
def _validate_path(self):
if not os.path.exists(self.repo_path):
raise ValueError(f"Path does not exist: {self.repo_path}")
# After: Service using CWD only
class CommitzenService:
def __init__(self):
self.repo_path = os.getcwd()
# No path validation needed - always CWD
self._initialize_commitizen()
```
### 4. Repository Manager Simplification
```python
# Before: Complex repository manager
class RepositoryManager:
def resolve_repository_path(self, repo_path: Optional[str] = None) -> str:
# Priority order:
# 1. Explicit repo_path
# 2. Environment variable
# 3. Client context
# 4. Current directory
if repo_path:
return self._validate_path(repo_path)
if os.environ.get("COMMITIZEN_REPO_PATH"):
return self._validate_path(os.environ["COMMITIZEN_REPO_PATH"])
# ... more complex logic
return os.getcwd()
# After: Simple repository manager
class SecureRepositoryManager:
def get_repository_path(self) -> str:
"""Always returns current working directory."""
return os.getcwd()
def validate_cwd(self) -> bool:
"""Validate current working directory."""
cwd = os.getcwd()
return os.path.isdir(cwd) and os.access(cwd, os.R_OK)
```
## Testing Examples
### 5. Unit Test Without Path Mocking
```python
# Before: Complex test with path mocking
def test_tool_with_custom_path(mock_path):
"""Test tool with mocked repository path."""
mock_path.return_value = "/mocked/path"
with patch.dict(os.environ, {"COMMITIZEN_REPO_PATH": "/env/path"}):
result = get_git_status(repo_path="/explicit/path")
assert result["repository_path"] == "/explicit/path"
# After: Simple test with actual directory
def test_tool_with_cwd():
"""Test tool operates on current directory."""
with temporary_git_repo() as repo:
os.chdir(repo.working_dir)
result = get_git_status()
assert result["success"] is True
assert result["repository_path"] == repo.working_dir
```
### 6. Security Test Examples
```python
def test_cannot_access_other_directories():
"""Test that operations cannot access other directories."""
with temporary_directory() as temp_dir:
target_dir = os.path.join(temp_dir, "target")
other_dir = os.path.join(temp_dir, "other")
os.makedirs(target_dir)
os.makedirs(other_dir)
# Change to target directory
os.chdir(target_dir)
# Tool should only see current directory
result = analyze_directory()
assert result["directory"] == target_dir
assert other_dir not in str(result)
def test_environment_variable_ignored():
"""Test that COMMITIZEN_REPO_PATH is completely ignored."""
with temporary_directory() as temp_dir:
os.chdir(temp_dir)
# Set environment variable (should be ignored)
os.environ["COMMITIZEN_REPO_PATH"] = "/should/be/ignored"
manager = SecureRepositoryManager()
assert manager.get_repository_path() == temp_dir
assert manager.get_repository_path() != "/should/be/ignored"
```
## Migration Examples
### 7. Migrating Existing Code
```python
# Old code (v1.x)
def process_repository(repo_path: str):
"""Process a specific repository."""
result = commit_helper.get_git_status(repo_path=repo_path)
if result["success"]:
commit_result = commit_helper.generate_commit_message(
type="feat",
subject="Add new feature",
repo_path=repo_path
)
return commit_result
# New code (v2.0)
def process_repository(repo_path: str):
"""Process a specific repository."""
# Must change directory first
original_dir = os.getcwd()
try:
os.chdir(repo_path)
result = commit_helper.get_git_status()
if result["success"]:
commit_result = commit_helper.generate_commit_message(
type="feat",
subject="Add new feature"
)
return commit_result
finally:
os.chdir(original_dir)
```
### 8. Multi-Repository Workflow
```python
# Old approach with repo_path
def check_multiple_repos(repo_paths: List[str]):
"""Check status of multiple repositories."""
results = {}
for repo_path in repo_paths:
results[repo_path] = get_git_status(repo_path=repo_path)
return results
# New approach with directory changes
def check_multiple_repos(repo_paths: List[str]):
"""Check status of multiple repositories."""
original_dir = os.getcwd()
results = {}
try:
for repo_path in repo_paths:
os.chdir(repo_path)
results[repo_path] = get_git_status()
finally:
os.chdir(original_dir)
return results
```
## Error Handling Examples
### 9. Clear Error Messages
```python
@mcp.tool()
def safe_git_operation() -> Dict[str, Any]:
"""Git operation with clear error handling."""
manager = SecureRepositoryManager()
# Check basic directory access
if not manager.validate_cwd():
return create_error_response(
RepositoryError(
message="Cannot access current working directory",
suggestions=[
"Check directory permissions",
"Ensure the directory exists"
]
)
)
# Check if git repository
if not manager.is_git_repository():
return create_error_response(
RepositoryError(
message="Current directory is not a git repository",
suggestions=[
"Run 'git init' to initialize a repository",
"Change to a directory containing a git repository"
]
)
)
# Perform operation
try:
result = perform_git_operation()
return create_success_response(result)
except Exception as e:
return create_error_response(
ServiceError(
message=f"Git operation failed: {str(e)}",
service_name="git_operation"
)
)
```
### 10. Validation Helper Functions
```python
def validate_cwd_for_operation() -> Tuple[bool, Optional[Dict[str, Any]]]:
"""Validate current working directory for basic operations."""
manager = SecureRepositoryManager()
if not manager.validate_cwd():
return False, create_error_response(
RepositoryError(
message="Invalid current working directory",
repo_path=os.getcwd()
)
)
return True, None
def validate_cwd_for_git_operation() -> Tuple[bool, Optional[Dict[str, Any]]]:
"""Validate current working directory is a git repository."""
# First check basic validity
is_valid, error = validate_cwd_for_operation()
if not is_valid:
return False, error
manager = SecureRepositoryManager()
if not manager.is_git_repository():
return False, create_error_response(
RepositoryError(
message="Current directory is not a git repository",
repo_path=os.getcwd(),
suggestions=[
"Run 'git init' to initialize a repository",
"Change to a directory containing a git repository"
]
)
)
return True, None
```
## Shell Script Examples
### 11. Single Repository Script
```bash
#!/bin/bash
# Old way (v1.x)
commit_helper get_git_status --repo-path /path/to/repo
commit_helper generate_commit_message --repo-path /path/to/repo \
--type feat --subject "Add feature"
# New way (v2.0)
cd /path/to/repo
commit_helper get_git_status
commit_helper generate_commit_message --type feat --subject "Add feature"
```
### 12. Multi-Repository Script
```bash
#!/bin/bash
# Script to check multiple repositories
# Old way (v1.x)
for repo in repo1 repo2 repo3; do
echo "Checking $repo..."
commit_helper analyze_repository_health --repo-path "/repos/$repo"
done
# New way (v2.0)
ORIGINAL_DIR=$(pwd)
for repo in repo1 repo2 repo3; do
echo "Checking $repo..."
cd "/repos/$repo"
commit_helper analyze_repository_health
done
cd "$ORIGINAL_DIR"
```
## Performance Comparison
### 13. Simplified Operation Flow
```python
# Before: Multiple checks and resolution
def complex_operation(repo_path: Optional[str] = None):
# Resolve path (multiple checks)
if repo_path is None:
if os.environ.get("COMMITIZEN_REPO_PATH"):
repo_path = os.environ["COMMITIZEN_REPO_PATH"]
elif hasattr(context, "repo_path"):
repo_path = context.repo_path
else:
repo_path = os.getcwd()
# Validate path
if not os.path.exists(repo_path):
raise ValueError(f"Invalid path: {repo_path}")
# Execute
return do_work(repo_path)
# After: Direct execution
def simple_operation():
# No resolution needed
# Validation is simple
if not os.access(os.getcwd(), os.R_OK):
raise PermissionError("Cannot read current directory")
# Execute
return do_work(os.getcwd())
```
## Summary
The security-focused approach eliminates complexity while enhancing security:
1. **No Path Parameters**: All tools operate on CWD only
2. **No Environment Variables**: No external configuration
3. **Simple Validation**: Only validate CWD access
4. **Clear Errors**: Always about current directory
5. **Natural Testing**: No complex mocking needed
6. **Explicit Navigation**: Users must `cd` to target directory
This approach trades flexibility for security and simplicity, resulting in a more maintainable and secure codebase.