Skip to content

SCANPY-249 Default sonar.sources to current directory when not provided#319

Merged
guillaume-dequenne merged 3 commits into
masterfrom
current-dir-sources
May 22, 2026
Merged

SCANPY-249 Default sonar.sources to current directory when not provided#319
guillaume-dequenne merged 3 commits into
masterfrom
current-dir-sources

Conversation

@guillaume-dequenne
Copy link
Copy Markdown
Contributor

@guillaume-dequenne guillaume-dequenne commented May 22, 2026


Summary by Gitar

  • Default sonar.sources:
    • When sonar.sources is not provided, defaults to current directory '.'
  • Test directory exclusions:
    • Auto-detected or explicitly set test directories are added to sonar.exclusions to prevent overlap with sonar.sources
    • Existing exclusions are preserved and appended to

This will update automatically on new commits.

@hashicorp-vault-sonar-prod hashicorp-vault-sonar-prod Bot changed the title Default sonar.sources to current directory when not provided SCANPY-249 Default sonar.sources to current directory when not provided May 22, 2026
@hashicorp-vault-sonar-prod
Copy link
Copy Markdown

hashicorp-vault-sonar-prod Bot commented May 22, 2026

SCANPY-249

@sonar-review-alpha
Copy link
Copy Markdown

sonar-review-alpha Bot commented May 22, 2026

Summary

This PR adds a sensible default for sonar.sources when it's not explicitly configured. If sonar.sources is missing, it now defaults to the current directory ("."). Additionally, when this default is applied and sonar.tests is also configured, the PR automatically adds test directories to sonar.exclusions to prevent test code from being analyzed as source code.

The changes are backward-compatible: projects that already set sonar.sources explicitly are unaffected. New behavior only applies when the property is completely absent.

What reviewers should know

Where to start: Look at the main logic in configuration_loader.py lines 91-103 — this is where the default gets applied and the exclusion logic runs.

Key reviewer points:

  • The default only applies when sonar.sources is not in resolved_properties (doesn't override explicit configuration)
  • The exclusion-building logic is only triggered if both conditions are true: (1) sources was just defaulted, and (2) sonar.tests is already set
  • Test directory patterns are formatted as dir/** to exclude everything under that directory
  • Existing sonar.exclusions values are preserved and test patterns are appended with a comma delimiter

Test coverage: Existing assertions were updated to expect the new default (e.g., expecting SONAR_SOURCES: "." in configs). New test cases cover: default behavior, explicit override, and the exclusion-building logic with both fresh and existing exclusions. These are good—no gaps in the happy path or edge cases.


  • Generate Walkthrough
  • Generate Diagram

🗣️ Give feedback

Copy link
Copy Markdown

@sonar-review-alpha sonar-review-alpha Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Solid PR overall — the ordering is correct (test auto-detection runs before the sources defaulting, so auto-detected test paths are visible to the exclusion logic), the appending logic handles existing exclusions cleanly, and the test suite covers the key scenarios well. One edge case in the exclusion-building block needs a guard before merge.

🗣️ Give feedback

Comment on lines +94 to +102
if SONAR_TESTS in resolved_properties:
test_dirs = [d.strip() for d in resolved_properties[SONAR_TESTS].split(",") if d.strip()]
test_exclusion_patterns = ",".join(f"{d}/**" for d in test_dirs)
existing = resolved_properties.get(SONAR_EXCLUSIONS, "")
resolved_properties[SONAR_EXCLUSIONS] = f"{existing},{test_exclusion_patterns}" if existing else test_exclusion_patterns
logging.info(
"sonar.sources defaults to '.'; adding test directories to sonar.exclusions to avoid overlap: '%s'",
test_exclusion_patterns,
)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If sonar.tests is present but blank (e.g. sonar.tests= in sonar-project.properties, or SONAR_TESTS="" as an env var), test_dirs ends up empty after filtering. The code then:

  • Computes test_exclusion_patterns = "" (empty join)
  • If SONAR_EXCLUSIONS already has a value: writes "existing," — a trailing comma into the scanner's exclusion glob list
  • If SONAR_EXCLUSIONS is absent: silently sets it to "", creating a property that wasn't there before

Both are wrong. Guard the inner block with if test_dirs: so the exclusion mutation only fires when there are actual patterns to add.

Suggested change
if SONAR_TESTS in resolved_properties:
test_dirs = [d.strip() for d in resolved_properties[SONAR_TESTS].split(",") if d.strip()]
test_exclusion_patterns = ",".join(f"{d}/**" for d in test_dirs)
existing = resolved_properties.get(SONAR_EXCLUSIONS, "")
resolved_properties[SONAR_EXCLUSIONS] = f"{existing},{test_exclusion_patterns}" if existing else test_exclusion_patterns
logging.info(
"sonar.sources defaults to '.'; adding test directories to sonar.exclusions to avoid overlap: '%s'",
test_exclusion_patterns,
)
if SONAR_TESTS in resolved_properties:
test_dirs = [d.strip() for d in resolved_properties[SONAR_TESTS].split(",") if d.strip()]
if test_dirs:
test_exclusion_patterns = ",".join(f"{d}/**" for d in test_dirs)
existing = resolved_properties.get(SONAR_EXCLUSIONS, "")
resolved_properties[SONAR_EXCLUSIONS] = f"{existing},{test_exclusion_patterns}" if existing else test_exclusion_patterns
logging.info(
"sonar.sources defaults to '.'; adding test directories to sonar.exclusions to avoid overlap: '%s'",
test_exclusion_patterns,
)

Comment on lines +98 to +108
if (sources_defaulted or tests_auto_detected) and SONAR_TESTS in resolved_properties:
test_dirs = [d.strip() for d in resolved_properties[SONAR_TESTS].split(",") if d.strip()]
test_exclusion_patterns = ",".join(f"{d}/**" for d in test_dirs)
existing = resolved_properties.get(SONAR_EXCLUSIONS, "")
resolved_properties[SONAR_EXCLUSIONS] = (
f"{existing},{test_exclusion_patterns}" if existing else test_exclusion_patterns
)
logging.info(
"Adding test directories to sonar.exclusions to avoid overlap with sonar.sources: '%s'",
test_exclusion_patterns,
)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Edge Case: Exclusions added for auto-detected tests even when sources is narrow

When tests_auto_detected is True but the user explicitly set sonar.sources to a narrow path like "src", the condition on line 98 still evaluates to True (via the tests_auto_detected branch), and test directory exclusion patterns are appended to sonar.exclusions. These exclusions are harmless but unnecessary when the source path doesn't overlap with the test directories.

For example: --sonar-sources src with auto-detected tests directory → sonar.exclusions gets tests/** even though src never included tests.

This is a minor concern since extra exclusions don't cause incorrect behavior, but the log message "Adding test directories to sonar.exclusions to avoid overlap with sonar.sources" would be misleading when there's no actual overlap.

Only add test exclusions when sources actually includes '.' (the root), which is the only case where overlap is likely:

if SONAR_TESTS in resolved_properties and (
    sources_defaulted or resolved_properties.get(SONAR_SOURCES) == "."
):
  • Apply fix

Check the box to apply the fix or reply for a change | Was this helpful? React with 👍 / 👎

@gitar-bot
Copy link
Copy Markdown

gitar-bot Bot commented May 22, 2026

Code Review 👍 Approved with suggestions 0 resolved / 1 findings

Defaults sonar.sources to the current directory when not provided, with auto-detected test directories added to sonar.exclusions to prevent overlap. Consider refining the exclusion logic to account for cases where users explicitly set a narrow sonar.sources configuration.

💡 Edge Case: Exclusions added for auto-detected tests even when sources is narrow

📄 src/pysonar_scanner/configuration/configuration_loader.py:98-108

When tests_auto_detected is True but the user explicitly set sonar.sources to a narrow path like "src", the condition on line 98 still evaluates to True (via the tests_auto_detected branch), and test directory exclusion patterns are appended to sonar.exclusions. These exclusions are harmless but unnecessary when the source path doesn't overlap with the test directories.

For example: --sonar-sources src with auto-detected tests directory → sonar.exclusions gets tests/** even though src never included tests.

This is a minor concern since extra exclusions don't cause incorrect behavior, but the log message "Adding test directories to sonar.exclusions to avoid overlap with sonar.sources" would be misleading when there's no actual overlap.

Only add test exclusions when sources actually includes '.' (the root), which is the only case where overlap is likely
if SONAR_TESTS in resolved_properties and (
    sources_defaulted or resolved_properties.get(SONAR_SOURCES) == "."
):
🤖 Prompt for agents
Code Review: Defaults sonar.sources to the current directory when not provided, with auto-detected test directories added to sonar.exclusions to prevent overlap. Consider refining the exclusion logic to account for cases where users explicitly set a narrow sonar.sources configuration.

1. 💡 Edge Case: Exclusions added for auto-detected tests even when sources is narrow
   Files: src/pysonar_scanner/configuration/configuration_loader.py:98-108

   When `tests_auto_detected` is `True` but the user explicitly set `sonar.sources` to a narrow path like `"src"`, the condition on line 98 still evaluates to `True` (via the `tests_auto_detected` branch), and test directory exclusion patterns are appended to `sonar.exclusions`. These exclusions are harmless but unnecessary when the source path doesn't overlap with the test directories.
   
   For example: `--sonar-sources src` with auto-detected `tests` directory → `sonar.exclusions` gets `tests/**` even though `src` never included `tests`.
   
   This is a minor concern since extra exclusions don't cause incorrect behavior, but the log message "Adding test directories to sonar.exclusions to avoid overlap with sonar.sources" would be misleading when there's no actual overlap.

   Fix (Only add test exclusions when sources actually includes '.' (the root), which is the only case where overlap is likely):
   if SONAR_TESTS in resolved_properties and (
       sources_defaulted or resolved_properties.get(SONAR_SOURCES) == "."
   ):

Options

Auto-apply is off → Gitar will not commit updates to this branch.
Display: compact → Showing less information.

Comment with these commands to change:

Auto-apply Compact
gitar auto-apply:on         
gitar display:verbose         

Was this helpful? React with 👍 / 👎 | Gitar

Copy link
Copy Markdown
Contributor

@Seppli11 Seppli11 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the change looks good.
I was trying to think if the situation where the user didn't set the sources or tests, but did set the test exclusion would cause problems. But an easy workaround is to just set the two properties

f"{existing},{test_exclusion_patterns}" if existing else test_exclusion_patterns
)
logging.info(
"Adding test directories to sonar.exclusions to avoid overlap with sonar.sources: '%s'",
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nitpick: It would probably make sense to tell the user what they should do if they want to disable this behavior

@sonarqube-next
Copy link
Copy Markdown

@guillaume-dequenne guillaume-dequenne merged commit c83cebf into master May 22, 2026
18 checks passed
@guillaume-dequenne guillaume-dequenne deleted the current-dir-sources branch May 22, 2026 14:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants