From fa81793bea923c12672ec17274acd3d8195d82c4 Mon Sep 17 00:00:00 2001 From: catlog22 Date: Sun, 21 Dec 2025 17:01:49 +0800 Subject: [PATCH] =?UTF-8?q?refactor:=20=E4=BC=98=E5=8C=96=E5=BC=82?= =?UTF-8?q?=E5=B8=B8=E5=A4=84=E7=90=86=EF=BC=8C=E4=BD=BF=E7=94=A8=20cached?= =?UTF-8?q?=5Fproperty=20=E6=9B=BF=E4=BB=A3=20property=EF=BC=8C=E5=A2=9E?= =?UTF-8?q?=E5=BC=BA=E4=BB=A3=E7=A0=81=E5=8F=AF=E8=AF=BB=E6=80=A7=EF=BC=9B?= =?UTF-8?q?=E6=B7=BB=E5=8A=A0=20RelationshipType=20=E6=9E=9A=E4=B8=BE?= =?UTF-8?q?=E4=BB=A5=E8=A7=84=E8=8C=83=E5=8C=96=E5=85=B3=E7=B3=BB=E7=B1=BB?= =?UTF-8?q?=E5=9E=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- codex-lens/src/codexlens/cli/commands.py | 100 ----------------------- codex-lens/src/codexlens/config.py | 7 +- codex-lens/src/codexlens/entities.py | 18 ++-- 3 files changed, 13 insertions(+), 112 deletions(-) diff --git a/codex-lens/src/codexlens/cli/commands.py b/codex-lens/src/codexlens/cli/commands.py index 166237d2..4fe396b1 100644 --- a/codex-lens/src/codexlens/cli/commands.py +++ b/codex-lens/src/codexlens/cli/commands.py @@ -248,12 +248,6 @@ def init( else: console.print(f"[red]Init failed:[/red] {exc}") raise typer.Exit(code=1) - except Exception as exc: - if json_mode: - print_json(success=False, error=f"Unexpected error: {exc}") - else: - console.print(f"[red]Init failed (unexpected):[/red] {exc}") - raise typer.Exit(code=1) finally: if registry is not None: registry.close() @@ -457,12 +451,6 @@ def search( else: console.print(f"[red]Search failed:[/red] {exc}") raise typer.Exit(code=1) - except Exception as exc: - if json_mode: - print_json(success=False, error=f"Unexpected error: {exc}") - else: - console.print(f"[red]Search failed (unexpected):[/red] {exc}") - raise typer.Exit(code=1) finally: if registry is not None: registry.close() @@ -522,12 +510,6 @@ def symbol( else: console.print(f"[red]Symbol lookup failed:[/red] {exc}") raise typer.Exit(code=1) - except Exception as exc: - if json_mode: - print_json(success=False, error=f"Unexpected error: {exc}") - else: - console.print(f"[red]Symbol lookup failed (unexpected):[/red] {exc}") - raise typer.Exit(code=1) finally: if registry is not None: registry.close() @@ -583,12 +565,6 @@ def inspect( else: console.print(f"[red]Inspect failed:[/red] {exc}") raise typer.Exit(code=1) - except Exception as exc: - if json_mode: - print_json(success=False, error=f"Unexpected error: {exc}") - else: - console.print(f"[red]Inspect failed (unexpected):[/red] {exc}") - raise typer.Exit(code=1) @app.command() @@ -727,12 +703,6 @@ def status( else: console.print(f"[red]Status failed:[/red] {exc}") raise typer.Exit(code=1) - except Exception as exc: - if json_mode: - print_json(success=False, error=f"Unexpected error: {exc}") - else: - console.print(f"[red]Status failed (unexpected):[/red] {exc}") - raise typer.Exit(code=1) finally: if registry is not None: registry.close() @@ -884,12 +854,6 @@ def projects( else: console.print(f"[red]Projects command failed:[/red] {exc}") raise typer.Exit(code=1) - except Exception as exc: - if json_mode: - print_json(success=False, error=f"Unexpected error: {exc}") - else: - console.print(f"[red]Projects command failed (unexpected):[/red] {exc}") - raise typer.Exit(code=1) finally: if registry is not None: registry.close() @@ -1060,12 +1024,6 @@ def config( else: console.print(f"[red]Config command failed:[/red] {exc}") raise typer.Exit(code=1) - except Exception as exc: - if json_mode: - print_json(success=False, error=f"Unexpected error: {exc}") - else: - console.print(f"[red]Config command failed (unexpected):[/red] {exc}") - raise typer.Exit(code=1) @app.command() @@ -1192,12 +1150,6 @@ def migrate( else: console.print(f"[red]Migration failed:[/red] {exc}") raise typer.Exit(code=1) - except Exception as exc: - if json_mode: - print_json(success=False, error=f"Unexpected error: {exc}") - else: - console.print(f"[red]Migration failed (unexpected):[/red] {exc}") - raise typer.Exit(code=1) finally: if registry is not None: registry.close() @@ -1346,12 +1298,6 @@ def clean( else: console.print(f"[red]Clean failed:[/red] {exc}") raise typer.Exit(code=1) - except Exception as exc: - if json_mode: - print_json(success=False, error=f"Unexpected error: {exc}") - else: - console.print(f"[red]Clean failed (unexpected):[/red] {exc}") - raise typer.Exit(code=1) @app.command("semantic-list") @@ -1472,12 +1418,6 @@ def semantic_list( else: console.print(f"[red]Semantic-list failed:[/red] {exc}") raise typer.Exit(code=1) - except Exception as exc: - if json_mode: - print_json(success=False, error=f"Unexpected error: {exc}") - else: - console.print(f"[red]Semantic-list failed (unexpected):[/red] {exc}") - raise typer.Exit(code=1) finally: if registry is not None: registry.close() @@ -1549,12 +1489,6 @@ def model_list( console.print("[red]Error:[/red] fastembed not installed") console.print("[yellow]Install with:[/yellow] pip install codexlens[semantic]") raise typer.Exit(code=1) - except Exception as exc: - if json_mode: - print_json(success=False, error=str(exc)) - else: - console.print(f"[red]Model-list failed:[/red] {exc}") - raise typer.Exit(code=1) @app.command(name="model-download") @@ -1600,12 +1534,6 @@ def model_download( console.print("[red]Error:[/red] fastembed not installed") console.print("[yellow]Install with:[/yellow] pip install codexlens[semantic]") raise typer.Exit(code=1) - except Exception as exc: - if json_mode: - print_json(success=False, error=str(exc)) - else: - console.print(f"[red]Model-download failed:[/red] {exc}") - raise typer.Exit(code=1) @app.command(name="model-delete") @@ -1639,13 +1567,6 @@ def model_delete( console.print(f" Model: {data['model_name']}") console.print(f" Freed space: {data['deleted_size_mb']:.1f} MB") - except Exception as exc: - if json_mode: - print_json(success=False, error=str(exc)) - else: - console.print(f"[red]Model-delete failed:[/red] {exc}") - raise typer.Exit(code=1) - @app.command(name="model-info") def model_info( @@ -1682,13 +1603,6 @@ def model_info( console.print(f"\n Description: {data['description']}") console.print(f" Use case: {data['use_case']}") - except Exception as exc: - if json_mode: - print_json(success=False, error=str(exc)) - else: - console.print(f"[red]Model-info failed:[/red] {exc}") - raise typer.Exit(code=1) - # ==================== Embedding Management Commands ==================== @@ -1821,13 +1735,6 @@ def embeddings_status( console.print("\n[dim]Generate embeddings with:[/dim]") console.print(f" [cyan]codexlens embeddings-generate {index_path}[/cyan]") - except Exception as exc: - if json_mode: - print_json(success=False, error=str(exc)) - else: - console.print(f"[red]Embeddings-status failed:[/red] {exc}") - raise typer.Exit(code=1) - @app.command(name="embeddings-generate") def embeddings_generate( @@ -2011,10 +1918,3 @@ def embeddings_generate( console.print("\n[dim]Use vector search with:[/dim]") console.print(" [cyan]codexlens search 'your query' --mode pure-vector[/cyan]") - - except Exception as exc: - if json_mode: - print_json(success=False, error=str(exc)) - else: - console.print(f"[red]Embeddings-generate failed:[/red] {exc}") - raise typer.Exit(code=1) diff --git a/codex-lens/src/codexlens/config.py b/codex-lens/src/codexlens/config.py index fb96c74d..953b6ac7 100644 --- a/codex-lens/src/codexlens/config.py +++ b/codex-lens/src/codexlens/config.py @@ -4,6 +4,7 @@ from __future__ import annotations import os from dataclasses import dataclass, field +from functools import cached_property from pathlib import Path from typing import Any, Dict, List, Optional @@ -96,17 +97,17 @@ class Config: except Exception as exc: raise ConfigError(f"Failed to initialize data_dir at {self.data_dir}: {exc}") from exc - @property + @cached_property def cache_dir(self) -> Path: """Directory for transient caches.""" return self.data_dir / "cache" - @property + @cached_property def index_dir(self) -> Path: """Directory where index artifacts are stored.""" return self.data_dir / "index" - @property + @cached_property def db_path(self) -> Path: """Default SQLite index path.""" return self.index_dir / "codexlens.db" diff --git a/codex-lens/src/codexlens/entities.py b/codex-lens/src/codexlens/entities.py index a69edfa1..08e51f54 100644 --- a/codex-lens/src/codexlens/entities.py +++ b/codex-lens/src/codexlens/entities.py @@ -2,6 +2,7 @@ from __future__ import annotations +from enum import Enum from typing import Any, Dict, List, Optional, Tuple from pydantic import BaseModel, Field, field_validator @@ -62,24 +63,23 @@ class IndexedFile(BaseModel): return cleaned +class RelationshipType(str, Enum): + """Types of code relationships.""" + CALL = "call" + INHERITS = "inherits" + IMPORTS = "imports" + + class CodeRelationship(BaseModel): """A relationship between code symbols (e.g., function calls, inheritance).""" source_symbol: str = Field(..., min_length=1, description="Name of source symbol") target_symbol: str = Field(..., min_length=1, description="Name of target symbol") - relationship_type: str = Field(..., min_length=1, description="Type of relationship (call, inherits, etc.)") + relationship_type: RelationshipType = Field(..., description="Type of relationship (call, inherits, etc.)") source_file: str = Field(..., min_length=1, description="File path containing source symbol") target_file: Optional[str] = Field(default=None, description="File path containing target (None if same file)") source_line: int = Field(..., ge=1, description="Line number where relationship occurs (1-based)") - @field_validator("relationship_type") - @classmethod - def validate_relationship_type(cls, value: str) -> str: - allowed_types = {"call", "inherits", "imports"} - if value not in allowed_types: - raise ValueError(f"relationship_type must be one of {allowed_types}") - return value - class AdditionalLocation(BaseModel): """A pointer to another location where a similar result was found.