Skip to content

SCANPY-80 Read ".coveragerc" configuration to exclude files from coverage#234

Merged
maksim-grebeniuk-sonarsource merged 6 commits intomasterfrom
SCANPY-80
Jun 17, 2025
Merged

SCANPY-80 Read ".coveragerc" configuration to exclude files from coverage#234
maksim-grebeniuk-sonarsource merged 6 commits intomasterfrom
SCANPY-80

Conversation

@maksim-grebeniuk-sonarsource
Copy link
Copy Markdown
Contributor

@maksim-grebeniuk-sonarsource maksim-grebeniuk-sonarsource commented Jun 17, 2025

SCANPY-80

Part of

Copy link
Copy Markdown
Contributor

@thomas-serre-sonarsource thomas-serre-sonarsource left a comment

Choose a reason for hiding this comment

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

The logic looks good to me.
I suggested a few changes with some of them which are a matter of taste.

class CoverageRCConfigurationLoader:

@staticmethod
def load(base_dir: pathlib.Path) -> dict[str, str]:
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.

minor let's rename this function as it's not loading the all coverage file but only the exclusions properties

Suggested change
def load(base_dir: pathlib.Path) -> dict[str, str]:
def load_exclusion_properties(base_dir: pathlib.Path) -> dict[str, str]:

Comment on lines +36 to +40
exclusion_properties = CoverageRCConfigurationLoader.__read_coverage_exclusions_properties(
config_file_path, coverage_properties
)
result_dict.update(exclusion_properties)
return result_dict
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.

minor I would simplify

Suggested change
exclusion_properties = CoverageRCConfigurationLoader.__read_coverage_exclusions_properties(
config_file_path, coverage_properties
)
result_dict.update(exclusion_properties)
return result_dict
exclusion_properties = CoverageRCConfigurationLoader.__read_coverage_exclusions_properties(
config_file_path, coverage_properties
)
return exclusion_properties

def __read_config(config_file_path: pathlib.Path) -> dict[str, Any]:
config_dict: dict[str, Any] = {}
if not config_file_path.exists():
logging.debug(f"Configuration file not found: {config_file_path}")
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.

minor for coherence with other logs

Suggested change
logging.debug(f"Configuration file not found: {config_file_path}")
logging.debug(f"Coverage file not found: {config_file_path}")

Comment on lines +52 to +53

# Iterate over sections and options
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.

nit

Suggested change
# Iterate over sections and options

return config_dict

@staticmethod
def __read_coverage_exclusions_properties(
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.

minor as this function is not reading from the file but only extracting patterns

Suggested change
def __read_coverage_exclusions_properties(
def __extract_coverage_exclusion_patterns(

Comment on lines +64 to +75
@staticmethod
def __read_coverage_exclusions_properties(
config_file_path: pathlib.Path, coverage_properties: dict[str, Any]
) -> dict[str, Any]:
result_dict: dict[str, Any] = {}
if "run" not in coverage_properties:
logging.debug(f"The run key was not found in {config_file_path}")
return result_dict

if "omit" not in coverage_properties["run"]:
logging.debug(f"The run.omit key was not found in {config_file_path}")
return result_dict
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.

Suggested change
@staticmethod
def __read_coverage_exclusions_properties(
config_file_path: pathlib.Path, coverage_properties: dict[str, Any]
) -> dict[str, Any]:
result_dict: dict[str, Any] = {}
if "run" not in coverage_properties:
logging.debug(f"The run key was not found in {config_file_path}")
return result_dict
if "omit" not in coverage_properties["run"]:
logging.debug(f"The run.omit key was not found in {config_file_path}")
return result_dict
@staticmethod
def __extract_coverage_exclusion_patterns(coverage_properties: dict[str, Any]) -> dict[str, Any]:
result_dict: dict[str, Any] = {}
if "run" not in coverage_properties or "omit" not in coverage_properties["run"]:
logging.debug(f"Coverage file has no exclusion properties")
return result_dict

Comment on lines +81 to +82
result_dict["sonar.coverage.exclusions"] = translated_exclusions
return result_dict
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.

I don't find it relevant in a loader file to build the options that should be passed to the scanner. I think this function should only return the exclusion patterns, so only a string, and the dict should be built outside. Moreover, the dict will always have only one key which seems overkill :) I'd suggest to build the dictionnary in the load function

Suggested change
result_dict["sonar.coverage.exclusions"] = translated_exclusions
return result_dict
return translated_exclusions

@sonarqube-next
Copy link
Copy Markdown

Copy link
Copy Markdown
Contributor

@thomas-serre-sonarsource thomas-serre-sonarsource left a comment

Choose a reason for hiding this comment

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

LGTM, thanks for the modifications !

@maksim-grebeniuk-sonarsource maksim-grebeniuk-sonarsource marked this pull request as ready for review June 17, 2025 14:02
@maksim-grebeniuk-sonarsource maksim-grebeniuk-sonarsource merged commit 8f21b82 into master Jun 17, 2025
17 checks passed
@maksim-grebeniuk-sonarsource maksim-grebeniuk-sonarsource deleted the SCANPY-80 branch June 17, 2025 14:02
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