Skip to content

Commit 4c28826

Browse files
committed
fix(sonar): pin maturin-action SHA, use logger.exception, exclude benchmarks/
Address SonarCloud Quality Gate failures on v1.6.1-prep commits: - 2x githubactions:S7637 (TO_REVIEW hotspots) - pin PyO3/maturin-action in cd.yml to commit SHA e83996d (v1.51.0) instead of the floating @v1. - 7x python:S8572 'Use logging.exception() instead' across tree.py, writer.py, treemapper.py - drops the explicit exception arg from logger.error(...) calls in except blocks; logging.exception captures the traceback automatically and is the documented idiom. - 1x python:S8513 in tests/test_basic.py - collapse chained .startswith(a) or .startswith(b) into the tuple form .startswith((a, b)). - Restore sonar-project.properties with sonar.exclusions=benchmarks/**, diffctx/**, etc - paper-track scaffolding is not shipped in the CLI release and should not gate it. This also lifts the C Reliability rating (the 3 outstanding BUG findings live in benchmarks/) and resolves text:S8565 (lock file missing - irrelevant for the CLI wheel distribution path).
1 parent 7c6c9d4 commit 4c28826

6 files changed

Lines changed: 34 additions & 20 deletions

File tree

.github/workflows/cd.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,7 @@ jobs:
213213
python-version: '3.12'
214214

215215
- name: Build wheel via maturin
216-
uses: PyO3/maturin-action@v1
216+
uses: PyO3/maturin-action@e83996d129638aa358a18fbd1dfb82f0b0fb5d3b # v1.51.0
217217
with:
218218
working-directory: ./repo
219219
target: ${{ matrix.maturin_target }}
@@ -256,7 +256,7 @@ jobs:
256256
python-version: '3.12'
257257

258258
- name: Build sdist via maturin
259-
uses: PyO3/maturin-action@v1
259+
uses: PyO3/maturin-action@e83996d129638aa358a18fbd1dfb82f0b0fb5d3b # v1.51.0
260260
with:
261261
working-directory: ./repo
262262
command: sdist

sonar-project.properties

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
sonar.projectKey=nikolay-e_TreeMapper
2+
sonar.organization=nikolay-e
3+
4+
sonar.sources=src
5+
sonar.tests=tests
6+
7+
# Paper-track scaffolding — not shipped in the CLI release, excluded from
8+
# code-quality analysis to keep the gate focused on `src/` (treemapper itself).
9+
sonar.exclusions=benchmarks/**,diffctx/**,scripts/**,docs/**,**/test-repos/**,**/results/**
10+
sonar.test.exclusions=tests/test_benchmark_*.py,tests/framework/**
11+
12+
sonar.python.coverage.reportPaths=coverage.xml
13+
sonar.python.xunit.reportPath=test-results.xml
14+
sonar.python.version=3.10,3.11,3.12,3.13

src/treemapper/tree.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -190,8 +190,8 @@ def _create_node(entry: Path, ctx: TreeBuildContext, current_depth: int, is_dir:
190190
node["content"] = _read_file_content(entry, ctx.max_file_bytes)
191191

192192
return node
193-
except OSError as e:
194-
logger.error("Failed to create node for %s: %s", entry.name, e)
193+
except OSError:
194+
logger.exception("Failed to create node for %s", entry.name)
195195
return None
196196

197197

@@ -274,6 +274,6 @@ def _read_file_content(file_path: Path, max_file_bytes: int | None) -> str:
274274
except UnicodeDecodeError:
275275
logger.error("Cannot decode %s as UTF-8. Marking as unreadable.", file_path.name)
276276
return "<unreadable content: not utf-8>\n"
277-
except OSError as e:
278-
logger.error("Could not read %s: %s", file_path.name, e)
277+
except OSError:
278+
logger.exception("Could not read %s", file_path.name)
279279
return "<unreadable content>\n"

src/treemapper/treemapper.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,8 @@ def _build_diff_tree(args: ParsedArgs) -> dict[str, Any]:
4040
whitelist_file=args.whitelist_file,
4141
scoring_mode=getattr(args, "scoring", "ego"),
4242
)
43-
except RuntimeError as e:
44-
logger.error("%s", e)
43+
except RuntimeError:
44+
logger.exception("diff context build failed")
4545
sys.exit(1)
4646

4747

@@ -130,8 +130,8 @@ def _handle_clipboard(output_content: str, args: ParsedArgs) -> bool:
130130
if not args.quiet:
131131
print("Copied to clipboard", file=sys.stderr)
132132
return True
133-
except ClipboardError as e:
134-
logger.error("Clipboard unavailable: %s", e)
133+
except ClipboardError:
134+
logger.exception("Clipboard unavailable")
135135
return False
136136

137137

@@ -147,8 +147,8 @@ def _handle_output_file(output_content: str, args: ParsedArgs) -> None:
147147
except IsADirectoryError:
148148
logger.error("'%s' is a directory", args.output_file)
149149
sys.exit(1)
150-
except OSError as e:
151-
logger.error("Cannot write '%s': %s", args.output_file, e)
150+
except OSError:
151+
logger.exception("Cannot write '%s'", args.output_file)
152152
sys.exit(1)
153153

154154

src/treemapper/writer.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -361,10 +361,10 @@ def _write_to_file_path(output_file: Path, writer: Callable[[TextIO], None]) ->
361361
try:
362362
fd_int, tmp_path = tempfile.mkstemp(dir=output_file.parent, suffix=".tmp")
363363
except PermissionError:
364-
logger.error("Unable to write to file '%s': permission denied", output_file)
364+
logger.exception("Unable to write to file '%s': permission denied", output_file)
365365
raise
366-
except OSError as e:
367-
logger.error("Unable to write to file '%s': %s", output_file, e)
366+
except OSError:
367+
logger.exception("Unable to write to file '%s'", output_file)
368368
raise
369369
try:
370370
with open(fd_int, "w", encoding="utf-8") as f:
@@ -374,11 +374,11 @@ def _write_to_file_path(output_file: Path, writer: Callable[[TextIO], None]) ->
374374
os.replace(tmp_path, output_file)
375375
except PermissionError:
376376
Path(tmp_path).unlink(missing_ok=True)
377-
logger.error("Unable to write to file '%s': permission denied", output_file)
377+
logger.exception("Unable to write to file '%s': permission denied", output_file)
378378
raise
379-
except OSError as e:
379+
except OSError:
380380
Path(tmp_path).unlink(missing_ok=True)
381-
logger.error("Unable to write to file '%s': %s", output_file, e)
381+
logger.exception("Unable to write to file '%s'", output_file)
382382
raise
383383
except BaseException:
384384
Path(tmp_path).unlink(missing_ok=True)

tests/test_basic.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -278,8 +278,8 @@ def test_unicode_content_and_encoding_errors(temp_project, run_mapper, caplog):
278278
assert binary_node is not None, "'binary.bin' not found"
279279
binary_content = binary_node.get("content", "")
280280
assert isinstance(binary_content, str)
281-
assert binary_content.startswith("<unreadable content") or binary_content.startswith(
282-
"<binary file:"
281+
assert binary_content.startswith(
282+
("<unreadable content", "<binary file:")
283283
), f"Binary file should be marked unreadable or binary, got: {binary_content!r}"
284284

285285

0 commit comments

Comments
 (0)