refactor: extract CSS modules for session/settings and delete styles.css (Task 2.3)
- Create InstanceList.module.css, AppShell.module.css, SettingsTabLayout.module.css - Create CommitPanel.module.css, FileViewer.module.css - Create page CSS files: sessions, repo-workspace, dashboard, projects, git-history, ssh-keys, settings - Update components to import and use CSS modules - Delete monolithic styles.css (2,255 lines) - Update main.tsx to import page CSS and new modules Quality gates: tsc (pass), eslint (pass), build (pass) Refs: repo-restructure Task 2.3
This commit is contained in:
@@ -0,0 +1,196 @@
|
||||
"""Git control operations with repo validation."""
|
||||
|
||||
import logging
|
||||
import os
|
||||
import uuid
|
||||
|
||||
from fastapi import HTTPException, status
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
from src.models.git_repository import GitRepository
|
||||
from src.models.user import User
|
||||
from src.schemas.git_repository import (
|
||||
BranchCreateRequest,
|
||||
CheckoutRequest,
|
||||
CommitRequest,
|
||||
FetchResponse,
|
||||
MergeRequest,
|
||||
MergeResponse,
|
||||
PullResponse,
|
||||
PushResponse,
|
||||
StatusResponse,
|
||||
)
|
||||
from src.services.git.repository import ensure_repo_on_disk, get_repo_and_validate
|
||||
from src.utils.git_control import (
|
||||
checkout_branch,
|
||||
commit_changes,
|
||||
create_branch,
|
||||
delete_branch,
|
||||
fetch,
|
||||
get_status,
|
||||
merge,
|
||||
pull,
|
||||
push,
|
||||
)
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
async def get_status_with_validation(
|
||||
session: AsyncSession,
|
||||
project_id: uuid.UUID,
|
||||
repo_id: uuid.UUID,
|
||||
) -> StatusResponse:
|
||||
repo = await get_repo_and_validate(session, repo_id, project_id)
|
||||
ensure_repo_on_disk(repo)
|
||||
try:
|
||||
result = get_status(repo.path)
|
||||
return StatusResponse(
|
||||
branch=result.branch,
|
||||
modified=result.modified,
|
||||
added=result.added,
|
||||
deleted=result.deleted,
|
||||
untracked=result.untracked,
|
||||
renamed=result.renamed,
|
||||
ahead=result.ahead,
|
||||
behind=result.behind,
|
||||
)
|
||||
except RuntimeError as e:
|
||||
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))
|
||||
|
||||
|
||||
async def create_branch_with_validation(
|
||||
session: AsyncSession,
|
||||
project_id: uuid.UUID,
|
||||
repo_id: uuid.UUID,
|
||||
data: BranchCreateRequest,
|
||||
) -> dict:
|
||||
repo = await get_repo_and_validate(session, repo_id, project_id)
|
||||
ensure_repo_on_disk(repo)
|
||||
try:
|
||||
create_branch(repo.path, data.name, data.base_branch)
|
||||
return {"message": f"Branch '{data.name}' created", "branch": data.name}
|
||||
except RuntimeError as e:
|
||||
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))
|
||||
|
||||
|
||||
async def delete_branch_with_validation(
|
||||
session: AsyncSession,
|
||||
project_id: uuid.UUID,
|
||||
repo_id: uuid.UUID,
|
||||
branch_name: str,
|
||||
force: bool = False,
|
||||
) -> dict:
|
||||
repo = await get_repo_and_validate(session, repo_id, project_id)
|
||||
ensure_repo_on_disk(repo)
|
||||
try:
|
||||
delete_branch(repo.path, branch_name, force)
|
||||
return {"message": f"Branch '{branch_name}' deleted"}
|
||||
except RuntimeError as e:
|
||||
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))
|
||||
|
||||
|
||||
async def checkout_branch_with_validation(
|
||||
session: AsyncSession,
|
||||
project_id: uuid.UUID,
|
||||
repo_id: uuid.UUID,
|
||||
data: CheckoutRequest,
|
||||
) -> dict:
|
||||
repo = await get_repo_and_validate(session, repo_id, project_id)
|
||||
ensure_repo_on_disk(repo)
|
||||
try:
|
||||
checkout_branch(repo.path, data.branch)
|
||||
return {"message": f"Checked out branch '{data.branch}'", "branch": data.branch}
|
||||
except RuntimeError as e:
|
||||
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))
|
||||
|
||||
|
||||
async def commit_changes_with_validation(
|
||||
session: AsyncSession,
|
||||
project_id: uuid.UUID,
|
||||
repo_id: uuid.UUID,
|
||||
data: CommitRequest,
|
||||
user: User,
|
||||
) -> dict:
|
||||
repo = await get_repo_and_validate(session, repo_id, project_id)
|
||||
ensure_repo_on_disk(repo)
|
||||
author_name = user.name or "Unknown"
|
||||
author_email = user.email or "unknown@example.com"
|
||||
try:
|
||||
commit_hash = commit_changes(
|
||||
repo_path=repo.path,
|
||||
message=data.message,
|
||||
author_name=author_name,
|
||||
author_email=author_email,
|
||||
files=data.files,
|
||||
)
|
||||
return {"commit_hash": commit_hash, "message": data.message}
|
||||
except RuntimeError as e:
|
||||
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))
|
||||
|
||||
|
||||
async def fetch_with_validation(
|
||||
session: AsyncSession,
|
||||
project_id: uuid.UUID,
|
||||
repo_id: uuid.UUID,
|
||||
) -> FetchResponse:
|
||||
repo = await get_repo_and_validate(session, repo_id, project_id)
|
||||
ensure_repo_on_disk(repo)
|
||||
try:
|
||||
fetch(repo.path)
|
||||
return FetchResponse(message="Fetched from remote")
|
||||
except RuntimeError as e:
|
||||
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))
|
||||
|
||||
|
||||
async def pull_with_validation(
|
||||
session: AsyncSession,
|
||||
project_id: uuid.UUID,
|
||||
repo_id: uuid.UUID,
|
||||
branch: str | None = None,
|
||||
) -> PullResponse:
|
||||
repo = await get_repo_and_validate(session, repo_id, project_id)
|
||||
ensure_repo_on_disk(repo)
|
||||
try:
|
||||
pull(repo.path, branch)
|
||||
return PullResponse(message="Pulled from remote")
|
||||
except RuntimeError as e:
|
||||
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))
|
||||
|
||||
|
||||
async def push_with_validation(
|
||||
session: AsyncSession,
|
||||
project_id: uuid.UUID,
|
||||
repo_id: uuid.UUID,
|
||||
branch: str | None = None,
|
||||
) -> PushResponse:
|
||||
repo = await get_repo_and_validate(session, repo_id, project_id)
|
||||
ensure_repo_on_disk(repo)
|
||||
try:
|
||||
push(repo.path, branch)
|
||||
return PushResponse(message="Pushed to remote")
|
||||
except RuntimeError as e:
|
||||
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))
|
||||
|
||||
|
||||
async def merge_with_validation(
|
||||
session: AsyncSession,
|
||||
project_id: uuid.UUID,
|
||||
repo_id: uuid.UUID,
|
||||
data: MergeRequest,
|
||||
) -> MergeResponse:
|
||||
repo = await get_repo_and_validate(session, repo_id, project_id)
|
||||
ensure_repo_on_disk(repo)
|
||||
try:
|
||||
commit_hash = merge(
|
||||
repo_path=repo.path,
|
||||
source_branch=data.source_branch,
|
||||
target_branch=data.target_branch,
|
||||
message=data.message,
|
||||
)
|
||||
return MergeResponse(
|
||||
commit_hash=commit_hash,
|
||||
message=data.message or f"Merge {data.source_branch}",
|
||||
)
|
||||
except RuntimeError as e:
|
||||
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e))
|
||||
Reference in New Issue
Block a user