From 67b61d6d132e4122aa13df514053bf05f9fbfe20 Mon Sep 17 00:00:00 2001 From: Juan Antonio Osorio Date: Mon, 20 Jan 2025 13:37:35 +0200 Subject: [PATCH] `make lint` now checks for format This enables `make lint` to also run black but without persisting the changes. This will hopefully allow developers to more easily detect if their changes are not compliant with the linter settings. This also removes the `make format` call from CI, which didn't actually fail if linter issues were found. Signed-off-by: Juan Antonio Osorio --- .github/workflows/ci.yml | 3 --- Makefile | 1 + src/codegate/api/v1.py | 9 ++++++--- src/codegate/db/connection.py | 15 +++++++++++---- src/codegate/server.py | 2 +- src/codegate/workspaces/crud.py | 8 +++++--- tests/pipeline/workspace/test_workspace.py | 8 ++------ tests/test_server.py | 4 +++- 8 files changed, 29 insertions(+), 21 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 99d56dff..1478844f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -47,9 +47,6 @@ jobs: - name: Run linting run: make lint - - name: Run formatting - run: make format - - name: Run tests run: make test diff --git a/Makefile b/Makefile index 3c3074d6..a567f736 100644 --- a/Makefile +++ b/Makefile @@ -19,6 +19,7 @@ format: poetry run ruff check --fix . lint: + poetry run black --check . poetry run ruff check . test: diff --git a/src/codegate/api/v1.py b/src/codegate/api/v1.py index 358e4859..73a8d195 100644 --- a/src/codegate/api/v1.py +++ b/src/codegate/api/v1.py @@ -63,9 +63,12 @@ async def create_workspace(request: v1_models.CreateWorkspaceRequest) -> v1_mode except AlreadyExistsError: raise HTTPException(status_code=409, detail="Workspace already exists") except ValidationError: - raise HTTPException(status_code=400, - detail=("Invalid workspace name. " - "Please use only alphanumeric characters and dashes")) + raise HTTPException( + status_code=400, + detail=( + "Invalid workspace name. " "Please use only alphanumeric characters and dashes" + ), + ) except Exception: raise HTTPException(status_code=500, detail="Internal server error") diff --git a/src/codegate/db/connection.py b/src/codegate/db/connection.py index 6efe4586..c2a32436 100644 --- a/src/codegate/db/connection.py +++ b/src/codegate/db/connection.py @@ -30,9 +30,11 @@ alert_queue = asyncio.Queue() fim_cache = FimCache() + class AlreadyExistsError(Exception): pass + class DbCodeGate: _instance = None @@ -266,7 +268,8 @@ async def add_workspace(self, workspace_name: str) -> Optional[Workspace]: try: added_workspace = await self._execute_update_pydantic_model( - workspace, sql, should_raise=True) + workspace, sql, should_raise=True + ) except IntegrityError as e: logger.debug(f"Exception type: {type(e)}") raise AlreadyExistsError(f"Workspace {workspace_name} already exists.") @@ -317,8 +320,11 @@ async def _execute_select_pydantic_model( return None async def _exec_select_conditions_to_pydantic( - self, model_type: Type[BaseModel], sql_command: TextClause, conditions: dict, - should_raise: bool = False + self, + model_type: Type[BaseModel], + sql_command: TextClause, + conditions: dict, + should_raise: bool = False, ) -> Optional[List[BaseModel]]: async with self._async_db_engine.begin() as conn: try: @@ -397,7 +403,8 @@ async def get_workspace_by_name(self, name: str) -> List[Workspace]: ) conditions = {"name": name} workspaces = await self._exec_select_conditions_to_pydantic( - Workspace, sql, conditions, should_raise=True) + Workspace, sql, conditions, should_raise=True + ) return workspaces[0] if workspaces else None async def get_sessions(self) -> List[Session]: diff --git a/src/codegate/server.py b/src/codegate/server.py index dc9a8b0f..857fb064 100644 --- a/src/codegate/server.py +++ b/src/codegate/server.py @@ -112,4 +112,4 @@ def generate_openapi(): # Convert the schema to JSON string for easier handling or storage openapi_json = json.dumps(openapi_schema, indent=2) - print(openapi_json) \ No newline at end of file + print(openapi_json) diff --git a/src/codegate/workspaces/crud.py b/src/codegate/workspaces/crud.py index 0e215cbb..d14f24ab 100644 --- a/src/codegate/workspaces/crud.py +++ b/src/codegate/workspaces/crud.py @@ -8,12 +8,15 @@ class WorkspaceCrudError(Exception): pass + class WorkspaceDoesNotExistError(WorkspaceCrudError): pass + class WorkspaceAlreadyActiveError(WorkspaceCrudError): pass + class WorkspaceCrud: def __init__(self): @@ -30,7 +33,7 @@ async def add_workspace(self, new_workspace_name: str) -> Workspace: workspace_created = await db_recorder.add_workspace(new_workspace_name) return workspace_created - async def get_workspaces(self)-> List[WorkspaceActive]: + async def get_workspaces(self) -> List[WorkspaceActive]: """ Get all workspaces """ @@ -60,8 +63,7 @@ async def _is_workspace_active( raise RuntimeError("Something went wrong. No active session found.") session = sessions[0] - return (session.active_workspace_id == selected_workspace.id, - session, selected_workspace) + return (session.active_workspace_id == selected_workspace.id, session, selected_workspace) async def activate_workspace(self, workspace_name: str): """ diff --git a/tests/pipeline/workspace/test_workspace.py b/tests/pipeline/workspace/test_workspace.py index 1caf2be2..e45376fa 100644 --- a/tests/pipeline/workspace/test_workspace.py +++ b/tests/pipeline/workspace/test_workspace.py @@ -77,9 +77,7 @@ async def test_add_workspaces(args, existing_workspaces, expected_message): workspace_commands._db_reader = mock_db_reader # We'll also patch DbRecorder to ensure no real DB operations happen - with patch( - "codegate.workspaces.crud.WorkspaceCrud", autospec=True - ) as mock_recorder_cls: + with patch("codegate.workspaces.crud.WorkspaceCrud", autospec=True) as mock_recorder_cls: mock_recorder = mock_recorder_cls.return_value workspace_commands.workspace_crud = mock_recorder mock_recorder.add_workspace = AsyncMock() @@ -115,9 +113,7 @@ async def test_parse_execute_cmd( """ workspace_commands = Workspace() - with patch.object( - workspace_commands, "run", return_value=mocked_execute_response - ) as mock_run: + with patch.object(workspace_commands, "run", return_value=mocked_execute_response) as mock_run: result = await workspace_commands.exec(user_message) assert result == mocked_execute_response diff --git a/tests/test_server.py b/tests/test_server.py index 0eecd92c..8e07c0ee 100644 --- a/tests/test_server.py +++ b/tests/test_server.py @@ -81,6 +81,7 @@ def test_health_check(test_client: TestClient) -> None: assert response.status_code == 200 assert response.json() == {"status": "healthy"} + @patch("codegate.api.dashboard.dashboard.fetch_latest_version", return_value="foo") def test_version_endpoint(mock_fetch_latest_version, test_client: TestClient) -> None: """Test the version endpoint.""" @@ -89,11 +90,12 @@ def test_version_endpoint(mock_fetch_latest_version, test_client: TestClient) -> response_data = response.json() - assert response_data["current_version"] == __version__.lstrip('v') + assert response_data["current_version"] == __version__.lstrip("v") assert response_data["latest_version"] == "foo" assert isinstance(response_data["is_latest"], bool) assert response_data["is_latest"] is False + @patch("codegate.pipeline.secrets.manager.SecretsManager") @patch("codegate.server.ProviderRegistry") def test_provider_registration(mock_registry, mock_secrets_mgr, mock_pipeline_factory) -> None: