Add env_pro core modules
This commit is contained in:
151
app/env_pro/core/profile.py
Normal file
151
app/env_pro/core/profile.py
Normal file
@@ -0,0 +1,151 @@
|
|||||||
|
"""Profile management for env-pro."""
|
||||||
|
|
||||||
|
import os
|
||||||
|
from pathlib import Path
|
||||||
|
from typing import Optional, Dict, List
|
||||||
|
from dotenv import dotenv_values
|
||||||
|
|
||||||
|
|
||||||
|
class ProfileError(Exception):
|
||||||
|
"""Base exception for profile errors."""
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class ProfileNotFoundError(ProfileError):
|
||||||
|
"""Raised when a profile is not found."""
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def get_profiles_dir(project_root: Optional[Path] = None) -> Path:
|
||||||
|
"""Get the profiles directory path."""
|
||||||
|
if project_root is None:
|
||||||
|
project_root = Path.cwd()
|
||||||
|
return project_root / ".env-profiles"
|
||||||
|
|
||||||
|
|
||||||
|
def get_active_profile(project_root: Optional[Path] = None) -> Optional[str]:
|
||||||
|
"""Get the currently active profile name."""
|
||||||
|
profiles_dir = get_profiles_dir(project_root)
|
||||||
|
active_file = profiles_dir / ".active"
|
||||||
|
|
||||||
|
if active_file.exists():
|
||||||
|
return active_file.read_text().strip()
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def set_active_profile(profile_name: str, project_root: Optional[Path] = None):
|
||||||
|
"""Set the active profile."""
|
||||||
|
profiles_dir = get_profiles_dir(project_root)
|
||||||
|
profiles_dir.mkdir(parents=True, exist_ok=True)
|
||||||
|
|
||||||
|
active_file = profiles_dir / ".active"
|
||||||
|
active_file.write_text(profile_name)
|
||||||
|
|
||||||
|
|
||||||
|
def list_profiles(project_root: Optional[Path] = None) -> List[str]:
|
||||||
|
"""List all available profiles."""
|
||||||
|
profiles_dir = get_profiles_dir(project_root)
|
||||||
|
|
||||||
|
if not profiles_dir.exists():
|
||||||
|
return []
|
||||||
|
|
||||||
|
profiles = []
|
||||||
|
for item in profiles_dir.iterdir():
|
||||||
|
if item.is_dir() and not item.name.startswith('.'):
|
||||||
|
profiles.append(item.name)
|
||||||
|
return sorted(profiles)
|
||||||
|
|
||||||
|
|
||||||
|
def create_profile(profile_name: str, project_root: Optional[Path] = None):
|
||||||
|
"""Create a new profile."""
|
||||||
|
profiles_dir = get_profiles_dir(project_root)
|
||||||
|
profile_dir = profiles_dir / profile_name
|
||||||
|
|
||||||
|
if profile_dir.exists():
|
||||||
|
raise ProfileError(f"Profile '{profile_name}' already exists")
|
||||||
|
|
||||||
|
profile_dir.mkdir(parents=True, exist_ok=True)
|
||||||
|
env_file = profile_dir / ".env"
|
||||||
|
env_file.write_text("")
|
||||||
|
|
||||||
|
return profile_dir
|
||||||
|
|
||||||
|
|
||||||
|
def delete_profile(profile_name: str, project_root: Optional[Path] = None):
|
||||||
|
"""Delete a profile."""
|
||||||
|
profiles_dir = get_profiles_dir(project_root)
|
||||||
|
profile_dir = profiles_dir / profile_name
|
||||||
|
|
||||||
|
if not profile_dir.exists():
|
||||||
|
raise ProfileNotFoundError(f"Profile '{profile_name}' not found")
|
||||||
|
|
||||||
|
import shutil
|
||||||
|
shutil.rmtree(profile_dir)
|
||||||
|
|
||||||
|
|
||||||
|
def get_profile_vars(profile_name: str, project_root: Optional[Path] = None) -> Dict[str, str]:
|
||||||
|
"""Get all variables for a profile."""
|
||||||
|
profiles_dir = get_profiles_dir(project_root)
|
||||||
|
env_file = profiles_dir / profile_name / ".env"
|
||||||
|
|
||||||
|
if not env_file.exists():
|
||||||
|
raise ProfileNotFoundError(f"Profile '{profile_name}' not found")
|
||||||
|
|
||||||
|
vars = dotenv_values(env_file)
|
||||||
|
return {k: v for k, v in vars.items() if v is not None}
|
||||||
|
|
||||||
|
|
||||||
|
def set_profile_var(profile_name: str, key: str, value: str, project_root: Optional[Path] = None):
|
||||||
|
"""Set a variable in a profile."""
|
||||||
|
profiles_dir = get_profiles_dir(project_root)
|
||||||
|
env_file = profiles_dir / profile_name / ".env"
|
||||||
|
|
||||||
|
if not env_file.exists():
|
||||||
|
raise ProfileNotFoundError(f"Profile '{profile_name}' not found")
|
||||||
|
|
||||||
|
vars = dotenv_values(env_file)
|
||||||
|
vars[key] = value
|
||||||
|
|
||||||
|
with open(env_file, 'w') as f:
|
||||||
|
for k, v in vars.items():
|
||||||
|
if v is not None:
|
||||||
|
f.write(f"{k}={v}\n")
|
||||||
|
|
||||||
|
|
||||||
|
def delete_profile_var(profile_name: str, key: str, project_root: Optional[Path] = None):
|
||||||
|
"""Delete a variable from a profile."""
|
||||||
|
profiles_dir = get_profiles_dir(project_root)
|
||||||
|
env_file = profiles_dir / profile_name / ".env"
|
||||||
|
|
||||||
|
if not env_file.exists():
|
||||||
|
raise ProfileNotFoundError(f"Profile '{profile_name}' not found")
|
||||||
|
|
||||||
|
vars = dotenv_values(env_file)
|
||||||
|
if key in vars:
|
||||||
|
del vars[key]
|
||||||
|
|
||||||
|
with open(env_file, 'w') as f:
|
||||||
|
for k, v in vars.items():
|
||||||
|
if v is not None:
|
||||||
|
f.write(f"{k}={v}\n")
|
||||||
|
|
||||||
|
|
||||||
|
def init_project(project_root: Optional[Path] = None):
|
||||||
|
"""Initialize env-pro in a project directory."""
|
||||||
|
profiles_dir = get_profiles_dir(project_root)
|
||||||
|
|
||||||
|
if profiles_dir.exists():
|
||||||
|
return profiles_dir
|
||||||
|
|
||||||
|
profiles_dir.mkdir(parents=True, exist_ok=True)
|
||||||
|
|
||||||
|
default_profile = profiles_dir / "default"
|
||||||
|
default_profile.mkdir()
|
||||||
|
|
||||||
|
default_env = default_profile / ".env"
|
||||||
|
default_env.write_text("")
|
||||||
|
|
||||||
|
active_file = profiles_dir / ".active"
|
||||||
|
active_file.write_text("default")
|
||||||
|
|
||||||
|
return profiles_dir
|
||||||
Reference in New Issue
Block a user