Skip to content

Commit 28d49db

Browse files
aksOpsclaude
andcommitted
Fix SonarCloud issues: vulnerabilities, bugs, and code smells
- Fix BLOCKER BUG: wrong keyword arg in generate_flow route (format→fmt) - Fix BLOCKER: Use Annotated type hints for all FastAPI query params - Fix CRITICAL VULN: Cap loop bounds in ego() and trace_impact() (max 10) - Fix MAJOR BUG: Remove duplicate if/else branches in GraphQuery - Fix MAJOR BUG: Remove redundant regex alternatives in django_models, session_header_auth - Fix duplicate string literals (micronaut, quarkus, flow/views) - Fix unused variables (5 detectors + cli) - Fix regex issues (fastapi_auth, session_header_auth, scala, renderer) - Remove commented-out code in python_structures - Document HTTPException responses in routes - Fix remaining code-intelligence references to osscodeiq Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 729fd62 commit 28d49db

20 files changed

Lines changed: 88 additions & 77 deletions

src/osscodeiq/cli.py

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
"""CLI entry point for code-intelligence."""
1+
"""CLI entry point for OSSCodeIQ."""
22

33
from __future__ import annotations
44

@@ -17,12 +17,16 @@
1717
)
1818
console = Console()
1919

20+
_GRAPH_DIR_NAME = ".code-intelligence"
21+
_KUZU_DB_NAME = "graph.kuzu"
22+
_SQLITE_DB_NAME = "graph.db"
23+
2024

2125
def _get_version() -> str:
2226
"""Get package version from metadata."""
2327
try:
2428
from importlib.metadata import version
25-
return version("code-intelligence")
29+
return version("osscodeiq")
2630
except Exception:
2731
return "0.1.0"
2832

@@ -63,11 +67,11 @@ def analyze(
6367
cfg.analysis.incremental = incremental
6468
cfg.graph.backend = backend
6569
if backend in ("kuzu", "sqlite"):
66-
graph_dir = path.resolve() / ".code-intelligence"
70+
graph_dir = path.resolve() / _GRAPH_DIR_NAME
6771
if backend == "kuzu":
68-
cfg.graph.path = str(graph_dir / "graph.kuzu")
72+
cfg.graph.path = str(graph_dir / _KUZU_DB_NAME)
6973
elif backend == "sqlite":
70-
cfg.graph.path = str(graph_dir / "graph.db")
74+
cfg.graph.path = str(graph_dir / _SQLITE_DB_NAME)
7175

7276
console.print("🚀 Starting analysis…")
7377
analyzer = Analyzer(cfg)
@@ -145,7 +149,7 @@ def graph(
145149
cache_path = path.resolve() / cfg.cache.directory / cfg.cache.db_name
146150

147151
if not cache_path.exists():
148-
console.print("❌ No analysis cache found. Run 'code-intelligence analyze' first.")
152+
console.print("❌ No analysis cache found. Run 'osscodeiq analyze' first.")
149153
raise typer.Exit(1)
150154

151155
console.print("💾 Loading analysis cache…")
@@ -229,7 +233,7 @@ def query(
229233
cache_path = path.resolve() / cfg.cache.directory / cfg.cache.db_name
230234

231235
if not cache_path.exists():
232-
console.print("❌ No analysis cache found. Run 'code-intelligence analyze' first.")
236+
console.print("❌ No analysis cache found. Run 'osscodeiq analyze' first.")
233237
raise typer.Exit(1)
234238

235239
console.print("💾 Loading analysis cache…")
@@ -302,7 +306,7 @@ def cache(
302306
console.print("⚠️ No cache found.")
303307
elif action == "stats":
304308
if not cache_path.exists():
305-
console.print("⚠️ No cache found. Run 'code-intelligence analyze' first.")
309+
console.print("⚠️ No cache found. Run 'osscodeiq analyze' first.")
306310
return
307311
console.print("📊 Loading cache statistics…")
308312
from osscodeiq.cache.store import CacheStore
@@ -362,11 +366,11 @@ def bundle(
362366
cfg.graph.backend = backend
363367

364368
# Set default path for file-based backends
365-
graph_dir = path.resolve() / ".code-intelligence"
369+
graph_dir = path.resolve() / _GRAPH_DIR_NAME
366370
if backend == "kuzu":
367-
cfg.graph.path = str(graph_dir / "graph.kuzu")
371+
cfg.graph.path = str(graph_dir / _KUZU_DB_NAME)
368372
elif backend == "sqlite":
369-
cfg.graph.path = str(graph_dir / "graph.db")
373+
cfg.graph.path = str(graph_dir / _SQLITE_DB_NAME)
370374

371375
# Run analysis
372376
from osscodeiq.analyzer import Analyzer
@@ -432,17 +436,17 @@ def _load_graph_backend(path: Path, backend: str, config: Path | None = None):
432436
"""Load a graph backend from a previously analyzed project."""
433437
from osscodeiq.graph.backends import create_backend
434438

435-
graph_dir = path.resolve() / ".code-intelligence"
439+
graph_dir = path.resolve() / _GRAPH_DIR_NAME
436440
if backend == "kuzu":
437-
db_path = str(graph_dir / "graph.kuzu")
441+
db_path = str(graph_dir / _KUZU_DB_NAME)
438442
elif backend == "sqlite":
439-
db_path = str(graph_dir / "graph.db")
443+
db_path = str(graph_dir / _SQLITE_DB_NAME)
440444
else:
441445
# NetworkX ��� load from cache
442446
cfg = _load_config(config)
443447
cache_path = path.resolve() / cfg.cache.directory / cfg.cache.db_name
444448
if not cache_path.exists():
445-
console.print("No analysis cache found. Run 'code-intelligence analyze' first.")
449+
console.print("No analysis cache found. Run 'osscodeiq analyze' first.")
446450
raise typer.Exit(1)
447451
from osscodeiq.cache.store import CacheStore
448452
cache = CacheStore(cache_path)
@@ -451,7 +455,7 @@ def _load_graph_backend(path: Path, backend: str, config: Path | None = None):
451455

452456
from pathlib import Path as P
453457
if not P(db_path).exists():
454-
console.print(f"No graph database found at {db_path}. Run 'code-intelligence analyze --backend {backend}' first.")
458+
console.print(f"No graph database found at {db_path}. Run 'osscodeiq analyze --backend {backend}' first.")
455459
raise typer.Exit(1)
456460

457461
from osscodeiq.graph.store import GraphStore
@@ -624,7 +628,7 @@ def _flow_fallback(store, node_id: str | None, hops: int) -> list[dict]:
624628
visited: set[str] = set()
625629
frontier = {node_id}
626630
results = []
627-
for depth in range(1, hops + 1):
631+
for _ in range(1, hops + 1):
628632
next_frontier: set[str] = set()
629633
for nid in frontier:
630634
for neighbor in store.neighbors(nid, direction="out"):
@@ -700,7 +704,7 @@ def serve(
700704
import uvicorn
701705
from osscodeiq.server.app import create_app
702706

703-
console.print(f"[bold]OSSCodeIQ Server[/bold]")
707+
console.print("[bold]OSSCodeIQ Server[/bold]")
704708
console.print(f" Codebase: {path.resolve()}")
705709
console.print(f" Backend: {backend}")
706710
console.print(f" API docs: http://{host}:{port}/docs")

src/osscodeiq/detectors/auth/session_header_auth.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ class _PatternDef:
2929

3030
# -- Header patterns --
3131
_HEADER_PATTERNS: list[_PatternDef] = [
32-
_PatternDef(re.compile(r"""['"](X-API-Key|x-api-key)['"]""", re.IGNORECASE), "header", NodeKind.GUARD),
32+
_PatternDef(re.compile(r"""['"]X-API-Key['"]""", re.IGNORECASE), "header", NodeKind.GUARD),
3333
_PatternDef(
3434
re.compile(r"""(?:req|request|ctx)\.headers?\s*\[\s*['"]authorization['"]\s*\]""", re.IGNORECASE),
3535
"header",
@@ -49,8 +49,8 @@ class _PatternDef:
4949
"api_key",
5050
NodeKind.GUARD,
5151
),
52-
_PatternDef(re.compile(r"\bapi[_-]?key\s*(?:=|:)\s*", re.IGNORECASE), "api_key", NodeKind.GUARD),
53-
_PatternDef(re.compile(r"\bvalidate[_]?api[_]?key\b", re.IGNORECASE), "api_key", NodeKind.GUARD),
52+
_PatternDef(re.compile(r"\bapi[_-]?key\s*[=:]\s*", re.IGNORECASE), "api_key", NodeKind.GUARD),
53+
_PatternDef(re.compile(r"\bvalidate_?api_?key\b", re.IGNORECASE), "api_key", NodeKind.GUARD),
5454
]
5555

5656
# -- CSRF patterns --

src/osscodeiq/detectors/csharp/csharp_minimal_apis.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -129,8 +129,6 @@ def detect(self, ctx: DetectorContext) -> DetectorResult:
129129
lifetime = m.group(1)
130130
interface_name = m.group(2)
131131
impl_name = m.group(3) # May be None for single-type registrations
132-
line_num = find_line_number(text, m.start())
133-
134132
if impl_name:
135133
result.edges.append(GraphEdge(
136134
source=f"dotnet:*:{impl_name}",

src/osscodeiq/detectors/java/micronaut.py

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@
2222
_INJECT_RE = re.compile(r"@Inject\b")
2323
_SCHEDULED_RE = re.compile(r'@Scheduled\s*\(\s*fixedRate\s*=\s*"([^"]+)"')
2424
_EVENT_LISTENER_RE = re.compile(r"@EventListener\b")
25+
_INJECT = "@Inject"
26+
_EVENT_LISTENER = "@EventListener"
27+
2528
_CLASS_RE = re.compile(r"(?:public\s+)?class\s+(\w+)")
2629
_JAVA_METHOD_RE = re.compile(
2730
r"(?:public|protected|private)?\s*(?:static\s+)?(?:[\w<>\[\],\s]+)\s+(\w+)\s*\("
@@ -51,9 +54,9 @@ def detect(self, ctx: DetectorContext) -> DetectorResult:
5154
"@Prototype",
5255
"@Infrastructure",
5356
"@Client",
54-
"@Inject",
57+
_INJECT,
5558
"@Scheduled",
56-
"@EventListener",
59+
_EVENT_LISTENER,
5760
"io.micronaut",
5861
)
5962
):
@@ -198,11 +201,11 @@ def detect(self, ctx: DetectorContext) -> DetectorResult:
198201
GraphNode(
199202
id=node_id,
200203
kind=NodeKind.MIDDLEWARE,
201-
label="@Inject",
204+
label=_INJECT,
202205
fqn=f"{class_name}.inject" if class_name else "inject",
203206
module=ctx.module_name,
204207
location=SourceLocation(file_path=ctx.file_path, line_start=lineno),
205-
annotations=["@Inject"],
208+
annotations=[_INJECT],
206209
properties={"framework": "micronaut"},
207210
)
208211
)
@@ -233,11 +236,11 @@ def detect(self, ctx: DetectorContext) -> DetectorResult:
233236
GraphNode(
234237
id=node_id,
235238
kind=NodeKind.EVENT,
236-
label="@EventListener",
239+
label=_EVENT_LISTENER,
237240
fqn=f"{class_name}.eventListener" if class_name else "eventListener",
238241
module=ctx.module_name,
239242
location=SourceLocation(file_path=ctx.file_path, line_start=lineno),
240-
annotations=["@EventListener"],
243+
annotations=[_EVENT_LISTENER],
241244
properties={"framework": "micronaut"},
242245
)
243246
)

src/osscodeiq/detectors/java/quarkus.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
_SCHEDULED_RE = re.compile(r'@Scheduled\s*\(\s*(?:every|cron)\s*=\s*"([^"]+)"')
2424
_TRANSACTIONAL_RE = re.compile(r"@Transactional\b")
2525
_STARTUP_RE = re.compile(r"@Startup\b")
26+
_TRANSACTIONAL = "@Transactional"
27+
2628
_CLASS_RE = re.compile(r"(?:public\s+)?class\s+(\w+)")
2729

2830

@@ -46,7 +48,7 @@ def detect(self, ctx: DetectorContext) -> DetectorResult:
4648
"@ApplicationScoped",
4749
"@RequestScoped",
4850
"@Scheduled",
49-
"@Transactional",
51+
_TRANSACTIONAL,
5052
"@Startup",
5153
"io.quarkus",
5254
)
@@ -145,11 +147,11 @@ def detect(self, ctx: DetectorContext) -> DetectorResult:
145147
GraphNode(
146148
id=node_id,
147149
kind=NodeKind.MIDDLEWARE,
148-
label="@Transactional",
150+
label=_TRANSACTIONAL,
149151
fqn=f"{class_name}.transactional" if class_name else "transactional",
150152
module=ctx.module_name,
151153
location=SourceLocation(file_path=ctx.file_path, line_start=lineno),
152-
annotations=["@Transactional"],
154+
annotations=[_TRANSACTIONAL],
153155
properties={"framework": "quarkus"},
154156
)
155157
)

src/osscodeiq/detectors/python/django_auth.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,6 @@ def detect(self, ctx: DetectorContext) -> DetectorResult:
113113
for base in bases:
114114
if base in _AUTH_MIXINS:
115115
line = _line_number(text, m.start())
116-
pattern_name = _AUTH_MIXINS[base]
117116
result.nodes.append(GraphNode(
118117
id=f"auth:{ctx.file_path}:{base}:{line}",
119118
kind=NodeKind.GUARD,

src/osscodeiq/detectors/python/django_models.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ class DjangoModelDetector:
1616
supported_languages: tuple[str, ...] = ("python",)
1717

1818
_DJANGO_MODEL_RE = re.compile(
19-
r"^class\s+(\w+)\s*\(\s*(?:models\.Model|[\w.]*Model)\s*\)", re.MULTILINE
19+
r"^class\s+(\w+)\s*\(\s*[\w.]*Model\s*\)", re.MULTILINE
2020
)
2121
_FK_RE = re.compile(
2222
r"(\w+)\s*=\s*models\.(?:ForeignKey|OneToOneField)\s*\(\s*[\"']?(\w+)",
@@ -29,7 +29,7 @@ class DjangoModelDetector:
2929
_META_TABLE_RE = re.compile(r"db_table\s*=\s*[\"'](\w+)[\"']")
3030
_META_ORDERING_RE = re.compile(r"ordering\s*=\s*(\[.*?\])")
3131
_MANAGER_RE = re.compile(
32-
r"^class\s+(\w+)\s*\(\s*(?:models\.Manager|[\w.]*Manager)\s*\)", re.MULTILINE
32+
r"^class\s+(\w+)\s*\(\s*[\w.]*Manager\s*\)", re.MULTILINE
3333
)
3434
_MANAGER_ASSIGNMENT_RE = re.compile(r"(\w+)\s*=\s*(\w+)\s*\(\s*\)", re.MULTILINE)
3535

src/osscodeiq/detectors/python/fastapi_auth.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
# Depends(get_current_user) or Depends(get_current_active_user) etc.
1212
_DEPENDS_AUTH_RE = re.compile(
13-
r'Depends\(\s*(get_current[_\w]*|require_auth[_\w]*|auth[_\w]*)\s*\)'
13+
r'Depends\(\s*(get_current[\w]*|require_auth[\w]*|auth[\w]*)\s*\)'
1414
)
1515

1616
# Security(oauth2_scheme) or Security(some_auth_scheme, scopes=[...])

src/osscodeiq/detectors/python/kafka_python.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,6 @@ def _ensure_topic(topic: str, role: str, line: int) -> str:
161161

162162
# Detect imports -> IMPORTS edges
163163
for i, line in enumerate(lines):
164-
lineno = i + 1
165164
m = _IMPORT_RE.search(line)
166165
if m:
167166
lib = m.group(1)

src/osscodeiq/detectors/python/python_structures.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -199,15 +199,13 @@ def detect(self, ctx: DetectorContext) -> DetectorResult:
199199
from_module = m.group(1)
200200
import_names = m.group(2)
201201
if from_module:
202-
# from X import Y, Z
203202
result.edges.append(GraphEdge(
204203
source=file_node_id,
205204
target=from_module,
206205
kind=EdgeKind.IMPORTS,
207206
label=f"{fp} imports {from_module}",
208207
))
209208
else:
210-
# import X, Y
211209
for name in import_names.split(","):
212210
name = name.strip()
213211
if name:

0 commit comments

Comments
 (0)