Repository: SonarSource/sonar-scanner-python
Pull request #163: SCANPY-137 Support documented analyzer properties
Author: login: thomas-serre-sonarsource
Created: 2025-03-24T15:50:29Z | Merged: 2025-03-27T13:51:20Z

[SCANPY-137](https://sonarsource.atlassian.net/browse/SCANPY-137)



[SCANPY-137]: https://sonarsource.atlassian.net/browse/SCANPY-137?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ


Diff:
diff --git a/src/pysonar_scanner/configuration/cli.py b/src/pysonar_scanner/configuration/cli.py
index 855396f9..231b0cf3 100644
--- a/src/pysonar_scanner/configuration/cli.py
+++ b/src/pysonar_scanner/configuration/cli.py
@@ -27,7 +27,6 @@ class CliConfigurationLoader:
     @classmethod
     def load(cls) -> dict[str, any]:
         args = cls.__parse_cli_args()
-
         config = {}
         for prop in properties.PROPERTIES:
             if prop.cli_getter is not None:
@@ -60,13 +59,24 @@ def __parse_cli_args(cls) -> argparse.Namespace:
             type=str,
             help="Name of the project in SonarQube",
         )
-
+        parser.add_argument(
+            "--sonar-sources",
+            "-Dsonar.sources",
+            type=str,
+            help="The analysis scope for main source code (non-test code) in the project",
+        )
+        parser.add_argument(
+            "--sonar-tests",
+            "-Dsonar.tests",
+            type=str,
+            help="The analysis scope for test source code in the project",
+        )
         parser.add_argument(
             "-v",
             "--verbose",
             "--sonar-verbose",
             "-Dsonar.verbose",
-            action="store_true",
+            action=argparse.BooleanOptionalAction,
             default=None,
             help="Increase output verbosity",
         )
@@ -114,6 +124,12 @@ def __parse_cli_args(cls) -> argparse.Namespace:
             choices=["x64", "aarch64"],
             help="Architecture on which the scanner will be running",
         )
+        parser.add_argument(
+            "--sonar-scanner-metadata-filepath",
+            "-Dsonar.scanner.metadataFilepath",
+            type=str,
+            help="Sets the location where the scanner writes the report-task.txt file containing among other things the ceTaskId",
+        )
 
         parser.add_argument(
             "--skip-jre-provisioning",
@@ -207,6 +223,152 @@ def __parse_cli_args(cls) -> argparse.Namespace:
             help="Directory containing the project to be analyzed. Default is the current directory",
         )
 
+        parser.add_argument(
+            "--sonar-scm-exclusions-disabled",
+            type=bool,
+            action=argparse.BooleanOptionalAction,
+            help="Defines whether files ignored by the SCM, e.g., files listed in .gitignore, will be excluded from the analysis or not",
+        )
+
+        parser.add_argument(
+            "-Dsonar.scm.exclusions.disabled",
+            type=bool,
+            help="Equivalent to --sonar-scm-exclusions-disabled",
+        )
+
+        parser.add_argument(
+            "--sonar-filesize-limit",
+            "-Dsonar.filesize.limit",
+            type=int,
+            help="Sets the limit in MB for files to be discarded from the analysis scope if the size is greater than specified",
+        )
+
+        parser.add_argument(
+            "--sonar-cpd-python-minimum-tokens",
+            "-Dsonar.cpd.python.minimumTokens",
+            type=int,
+            help="Minimum number of tokens to be considered as a duplicated block of code",
+        )
+        parser.add_argument(
+            "--sonar-cpd-python-minimum-lines",
+            "-Dsonar.cpd.python.minimumLines",
+            type=int,
+            help="Minimum number of tokens to be considered as a duplicated block of code",
+        )
+
+        parser.add_argument(
+            "--sonar-log-level",
+            "-Dsonar.log.level",
+            type=str,
+            choices=["TRACE", "DEBUG", "INFO", "WARN", "ERROR"],
+            help="Log level during the analysis",
+        )
+        parser.add_argument(
+            "--sonar-qualitygate-wait",
+            type=bool,
+            action=argparse.BooleanOptionalAction,
+            help="Forces the analysis step to poll the server instance and wait for the Quality Gate status",
+        )
+        parser.add_argument(
+            "-Dsonar.qualitygate.wait",
+            type=bool,
+            help="Equivalent to --sonar-qualitygate-wait",
+        )
+        parser.add_argument(
+            "--sonar-qualitygate-timeout",
+            "-Dsonar.qualitygate.timeout",
+            type=int,
+            help="The number of seconds that the scanner should wait for a report to be processed",
+        )
+        parser.add_argument(
+            "--sonar-external-issues-report-paths",
+            "-Dsonar.externalIssuesReportPaths",
+            type=str,
+            help="Comma-delimited list of paths to generic issue reports",
+        )
+        parser.add_argument(
+            "--sonar-sarif-report-paths",
+            "-Dsonar.sarifReportPaths",
+            type=str,
+            help="Comma-delimited list of paths to SARIF issue reports",
+        )
+        parser.add_argument(
+            "--sonar-links-ci", "-Dsonar.links.ci", type=str, help="The URL of the continuous integration system used"
+        )
+        parser.add_argument(
+            "--sonar-links-homepage", "-Dsonar.links.homepage", type=str, help="The URL of the build project home page"
+        )
+        parser.add_argument(
+            "--sonar-links-issue", "-Dsonar.links.issue", type=str, help="The URL to the issue tracker being used"
+        )
+        parser.add_argument(
+            "--sonar-links-scm",
+            "-Dsonar.links.scm",
+            type=str,
+            help="The URL of the build project source code repository",
+        )
+        parser.add_argument(
+            "--sonar-branch-name", "-Dsonar.branch.name", type=str, help="Name of the branch being analyzed"
+        )
+        parser.add_argument(
+            "--sonar-pullrequest-key",
+            "-Dsonar.pullrequest.key",
+            type=str,
+            help="Key of the pull request being analyzed",
+        )
+        parser.add_argument(
+            "--sonar-pullrequest-branch",
+            "-Dsonar.pullrequest.branch",
+            type=str,
+            help="Branch of the pull request being analyzed",
+        )
+        parser.add_argument(
+            "--sonar-pullrequest-base",
+            "-Dsonar.pullrequest.base",
+            type=str,
+            help="Base branch of the pull request being analyzed",
+        )
+        parser.add_argument(
+            "--sonar-newcode-reference-branch",
+            "-Dsonar.newCode.referenceBranch",
+            type=str,
+            help="Reference branch for new code definition",
+        )
+        parser.add_argument(
+            "--sonar-scm-revision",
+            "-Dsonar.scm.revision",
+            type=str,
+            help="Overrides the revision, for instance, the Git sha1, displayed in analysis results",
+        )
+        parser.add_argument(
+            "--sonar-build-string",
+            "-Dsonar.buildString",
+            type=str,
+            help="The string passed with this property will be stored with the analysis and available in the results of api/project_analyses/search, thus allowing you to later identify a specific analysis and obtain its key for use with api/new_code_periods/set on the SPECIFIC_ANALYSIS type",
+        )
+        parser.add_argument(
+            "--sonar-source-encoding",
+            "-Dsonar.sourceEncoding",
+            type=str,
+            help="Encoding of the source files. For example, UTF-8, MacRoman, Shift_JIS",
+        )
+        parser.add_argument(
+            "--sonar-working-directory",
+            "-Dsonar.working.directory",
+            type=str,
+            help="Path to the working directory used by the Sonar scanner during a project analysis to store temporary data",
+        )
+        parser.add_argument(
+            "--sonar-scm-force-reload-all",
+            type=bool,
+            action=argparse.BooleanOptionalAction,
+            help="Set this property to true to load blame information for all files, which may significantly increase analysis duration",
+        )
+        parser.add_argument(
+            "-Dsonar.scm.forceReloadAll",
+            type=bool,
+            help="Equivalent to --sonar-scm-force-reload-all",
+        )
         parser.add_argument(
             "--toml-path",
             type=str,
diff --git a/src/pysonar_scanner/configuration/properties.py b/src/pysonar_scanner/configuration/properties.py
index c8ca1bed..508a975e 100644
--- a/src/pysonar_scanner/configuration/properties.py
+++ b/src/pysonar_scanner/configuration/properties.py
@@ -53,18 +53,41 @@
 SONAR_SCANNER_PROXY_PORT: Key = "sonar.scanner.proxyPort"
 SONAR_SCANNER_PROXY_USER: Key = "sonar.scanner.proxyUser"
 SONAR_SCANNER_PROXY_PASSWORD: Key = "sonar.scanner.proxyPassword"
-SONAR_PROJECT_BASE_DIR: Key = "sonar.projectBaseDir"
+SONAR_SCANNER_METADATA_FILEPATH: Key = "sonar.scanner.metadataFilePath"
 SONAR_SCANNER_JAVA_OPTS: Key = "sonar.scanner.javaOpts"
+SONAR_PROJECT_BASE_DIR: Key = "sonar.projectBaseDir"
 SONAR_PROJECT_KEY: Key = "sonar.projectKey"
 SONAR_PROJECT_NAME: Key = "sonar.projectName"
+SONAR_PROJECT_VERSION: Key = "sonar.projectVersion"
+SONAR_PROJECT_DESCRIPTION: Key = "sonar.projectDescription"
+SONAR_SCM_EXCLUSIONS_DISABLED = "sonar.scm.exclusions.disabled"
 SONAR_SOURCES: Key = "sonar.sources"
 SONAR_EXCLUSIONS: Key = "sonar.exclusions"
 SONAR_TESTS: Key = "sonar.tests"
-SONAR_PROJECT_VERSION: Key = "sonar.projectVersion"
-SONAR_PROJECT_DESCRIPTION: Key = "sonar.projectDescription"
+SONAR_FILESIZE_LIMIT: Key = "sonar.filesize.limit"
+SONAR_CPD_PYTHON_MINIMUM_TOKENS: Key = "sonar.cpd.python.minimumTokens"
+SONAR_CPD_PYTHON_MINIMUM_LINES: Key = "sonar.cpd.python.minimumLines"
+SONAR_LOG_LEVEL: Key = "sonar.log.level"
+SONAR_QUALITYGATE_WAIT: Key = "sonar.qualitygate.wait"
+SONAR_QUALITYGATE_TIMEOUT: Key = "sonar.qualitygate.timeout"
+SONAR_EXTERNAL_ISSUES_REPORT_PATHS: Key = "sonar.externalIssuesReportPaths"
+SONAR_SARIF_REPORT_PATHS: Key = "sonar.sarifReportPaths"
+SONAR_LINKS_CI: Key = "sonar.links.ci"
+SONAR_LINKS_HOMEPAGE: Key = "sonar.links.homepage"
+SONAR_LINKS_ISSUE: Key = "sonar.links.issue"
+SONAR_LINKS_SCM: Key = "sonar.links.scm"
+SONAR_BRANCH_NAME: Key = "sonar.branch.name"
+SONAR_PULLREQUEST_KEY: Key = "sonar.pullrequest.key"
+SONAR_PULLREQUEST_BRANCH: Key = "sonar.pullrequest.branch"
+SONAR_PULLREQUEST_BASE: Key = "sonar.pullrequest.base"
 SONAR_PYTHON_VERSION: Key = "sonar.python.version"
+SONAR_NEWCODE_REFERENCE_BRANCH: Key = "sonar.newCode.referenceBranch"
+SONAR_SCM_REVISION: Key = "sonar.scm.revision"
+SONAR_BUILD_STRING: Key = "sonar.buildString"
+SONAR_SOURCE_ENCODING: Key = "sonar.sourceEncoding"
+SONAR_WORKING_DIRECTORY: Key = "sonar.working.directory"
+SONAR_SCM_FORCE_RELOAD_ALL: Key = "sonar.scm.forceReloadAll"
 
-# pysonar scanner specific properties
 TOML_PATH: Key = "toml-path"
 
 
@@ -261,20 +284,70 @@ def env_variable_name(self) -> str:
         default_value=None, 
         cli_getter=lambda args: args.sonar_scanner_java_opts
     ),
+    Property(
+        name=SONAR_SCANNER_METADATA_FILEPATH,
+        default_value=None,
+        cli_getter=lambda args: args.sonar_scanner_metadata_filepath
+    ),
     Property(
         name=SONAR_PROJECT_KEY, 
         default_value=None, 
         cli_getter=lambda args: args.sonar_project_key
     ),
     Property(
-            name=SONAR_PROJECT_NAME,
-            default_value=None,
-            cli_getter=lambda args: args.sonar_project_name
+        name=SONAR_PROJECT_NAME,
+        default_value=None,
+        cli_getter=lambda args: args.sonar_project_name
+    ),
+    Property(
+        name=SONAR_PROJECT_VERSION,
+        default_value=None,
+        cli_getter=lambda args: args.sonar_project_version
+    ),
+    Property(
+        name=SONAR_PROJECT_DESCRIPTION,
+        default_value=None,
+        cli_getter=lambda args: args.sonar_project_description
+    ),
+    Property(
+        name=SONAR_SOURCES,
+        default_value=None,
+        cli_getter=lambda args: args.sonar_sources
+    ),
+    Property(
+        name=SONAR_TESTS,
+        default_value=None,
+        cli_getter=lambda args: args.sonar_tests
+    ),
+    Property(
+        name=SONAR_FILESIZE_LIMIT,
+        default_value=None,
+        cli_getter=lambda args: args.sonar_filesize_limit
+    ),
+    Property(
+        name=SONAR_SCM_EXCLUSIONS_DISABLED,
+        default_value=None,
+        cli_getter=lambda args: args.sonar_scm_exclusions_disabled or getattr(args, "Dsonar.scm.exclusions.disabled")
+    ),
+    Property(
+        name=SONAR_CPD_PYTHON_MINIMUM_TOKENS,
+        default_value=None,
+        cli_getter=lambda args: args.sonar_cpd_python_minimum_tokens
+    ),
+    Property(
+        name=SONAR_CPD_PYTHON_MINIMUM_LINES,
+        default_value=None,
+        cli_getter=lambda args: args.sonar_cpd_python_minimum_lines
     ),
     Property(
-            name=TOML_PATH,
-            default_value=None,
-            cli_getter=lambda args: args.toml_path
+        name=SONAR_LOG_LEVEL,
+        default_value=None,
+        cli_getter=lambda args: args.sonar_log_level
+    ),
+    Property(
+        name=TOML_PATH,
+        default_value=None,
+        cli_getter=lambda args: args.toml_path
     ),
     Property(
                 name=SONAR_PROJECT_VERSION,
@@ -291,5 +364,96 @@ def env_variable_name(self) -> str:
                 default_value=None,
                 cli_getter=lambda args: args.sonar_python_version
     ),
+    Property(
+        name=SONAR_QUALITYGATE_WAIT, 
+        default_value=None, 
+        cli_getter=lambda args: args.sonar_qualitygate_wait or getattr(args, "Dsonar.qualitygate.wait")
+    ),
+    Property(
+        name=SONAR_QUALITYGATE_TIMEOUT, 
+        default_value=None, 
+        cli_getter=lambda args: args.sonar_qualitygate_timeout
+    ),
+    Property(
+        name=SONAR_EXTERNAL_ISSUES_REPORT_PATHS, 
+        default_value=None, 
+        cli_getter=lambda args: args.sonar_external_issues_report_paths
+    ),
+    Property(
+        name=SONAR_SARIF_REPORT_PATHS, 
+        default_value=None,
+        cli_getter=lambda args: args.sonar_sarif_report_paths
+    ),
+    Property(
+        name=SONAR_LINKS_CI, 
+        default_value=None, 
+        cli_getter=lambda args: args.sonar_links_ci
+    ),
+    Property(
+        name=SONAR_LINKS_HOMEPAGE, 
+        default_value=None, 
+        cli_getter=lambda args: args.sonar_links_homepage
+    ),
+    Property(
+        name=SONAR_LINKS_ISSUE, 
+        default_value=None, 
+        cli_getter=lambda args: args.sonar_links_issue
+    ),
+    Property(
+        name=SONAR_LINKS_SCM, 
+        default_value=None, 
+        cli_getter=lambda args: args.sonar_links_scm
+    ),
+    Property(
+        name=SONAR_BRANCH_NAME, 
+        default_value=None, 
+        cli_getter=lambda args: args.sonar_branch_name
+    ),
+    Property(
+        name=SONAR_PULLREQUEST_KEY, 
+        default_value=None, 
+        cli_getter=lambda args: args.sonar_pullrequest_key
+    ),
+    Property(
+        name=SONAR_PULLREQUEST_BRANCH, 
+        default_value=None, 
+        cli_getter=lambda args: args.sonar_pullrequest_branch
+    ),
+    Property(
+        name=SONAR_PULLREQUEST_BASE, 
+        default_value=None, 
+        cli_getter=lambda args: args.sonar_pullrequest_base
+    ),
+    Property(
+        name=SONAR_NEWCODE_REFERENCE_BRANCH, 
+        default_value=None, 
+        cli_getter=lambda args: args.sonar_newcode_reference_branch
+    ),
+    Property(
+        name=SONAR_SCM_REVISION, 
+        default_value=None, 
+        cli_getter=lambda args: args.sonar_scm_revision
+    ),
+    Property(
+        name=SONAR_BUILD_STRING, 
+        default_value=None, 
+        cli_getter=lambda args: args.sonar_build_string
+    ),
+    Property(
+        name=SONAR_SOURCE_ENCODING, 
+        default_value=None, 
+        cli_getter=lambda args: args.sonar_source_encoding
+    ),
+    Property(
+        name=SONAR_WORKING_DIRECTORY, 
+        default_value=None, 
+        cli_getter=lambda args: args.sonar_working_directory
+    ),
+    Property(
+        name=SONAR_SCM_FORCE_RELOAD_ALL, 
+        default_value=None, 
+        cli_getter=lambda args: args.sonar_scm_force_reload_all or getattr(args, "Dsonar.scm.forceReloadAll")
+    )
+
 ]
 # fmt: on
diff --git a/tests/unit/test_configuration_cli.py b/tests/unit/test_configuration_cli.py
index 11d4ee35..cf8ee2fd 100644
--- a/tests/unit/test_configuration_cli.py
+++ b/tests/unit/test_configuration_cli.py
@@ -51,9 +51,96 @@
     SONAR_TOKEN,
     SONAR_USER_HOME,
     SONAR_VERBOSE,
+    SONAR_SOURCES,
+    SONAR_TESTS,
     SONAR_PROJECT_NAME,
+    SONAR_PROJECT_VERSION,
+    SONAR_PROJECT_DESCRIPTION,
+    SONAR_FILESIZE_LIMIT,
+    SONAR_CPD_PYTHON_MINIMUM_TOKENS,
+    SONAR_CPD_PYTHON_MINIMUM_LINES,
+    SONAR_SCM_EXCLUSIONS_DISABLED,
+    SONAR_LOG_LEVEL,
+    SONAR_SCANNER_METADATA_FILEPATH,
+    SONAR_QUALITYGATE_WAIT,
+    SONAR_QUALITYGATE_TIMEOUT,
+    SONAR_EXTERNAL_ISSUES_REPORT_PATHS,
+    SONAR_SARIF_REPORT_PATHS,
+    SONAR_LINKS_CI,
+    SONAR_LINKS_HOMEPAGE,
+    SONAR_LINKS_ISSUE,
+    SONAR_LINKS_SCM,
+    SONAR_BRANCH_NAME,
+    SONAR_PULLREQUEST_KEY,
+    SONAR_PULLREQUEST_BRANCH,
+    SONAR_PULLREQUEST_BASE,
+    SONAR_NEWCODE_REFERENCE_BRANCH,
+    SONAR_SCM_REVISION,
+    SONAR_BUILD_STRING,
+    SONAR_SOURCE_ENCODING,
+    SONAR_WORKING_DIRECTORY,
+    SONAR_SCM_FORCE_RELOAD_ALL,
 )
 
+EXPECTED_CONFIGURATION = {
+    SONAR_TOKEN: "myToken",
+    SONAR_PROJECT_KEY: "myProjectKey",
+    SONAR_PROJECT_NAME: "myProjectName",
+    SONAR_PROJECT_VERSION: "myProjectVersion",
+    SONAR_PROJECT_DESCRIPTION: "myProjectDescription",
+    SONAR_PROJECT_BASE_DIR: "mySonarProjectBaseDir",
+    SONAR_VERBOSE: True,
+    SONAR_SOURCES: "mySources",
+    SONAR_TESTS: "myTests",
+    SONAR_HOST_URL: "mySonarHostUrl",
+    SONAR_SCANNER_SONARCLOUD_URL: "mySonarScannerCloudUrl",
+    SONAR_SCANNER_API_BASE_URL: "mySonarScannerApiUrl",
+    SONAR_SCANNER_OS: "windows",
+    SONAR_SCANNER_ARCH: "x64",
+    SONAR_SCANNER_CONNECT_TIMEOUT: 42,
+    SONAR_SCANNER_INTERNAL_DUMP_TO_FILE: "mySonarScannerInternalDumpToFile",
+    SONAR_SCANNER_INTERNAL_SQ_VERSION: "mySonarScannerInternalSqVersion",
+    SONAR_SCANNER_SOCKET_TIMEOUT: 43,
+    SONAR_SCANNER_RESPONSE_TIMEOUT: 44,
+    SONAR_SCANNER_TRUSTSTORE_PATH: "mySonarScannerTruststorePath",
+    SONAR_SCANNER_TRUSTSTORE_PASSWORD: "mySonarScannerTruststorePassword",
+    SONAR_SCANNER_KEYSTORE_PATH: "mySonarScannerKeystorePath",
+    SONAR_SCANNER_KEYSTORE_PASSWORD: "mySonarScannerKeystorePassword",
+    SONAR_SCANNER_PROXY_HOST: "mySonarScannerProxyHost",
+    SONAR_SCANNER_PROXY_PORT: 45,
+    SONAR_SCANNER_PROXY_USER: "mySonarScannerProxyUser",
+    SONAR_SCANNER_PROXY_PASSWORD: "mySonarScannerProxyPassword",
+    SONAR_SCANNER_SKIP_JRE_PROVISIONING: True,
+    SONAR_SCANNER_JAVA_EXE_PATH: "mySonarScannerJavaExePath",
+    SONAR_SCANNER_JAVA_OPTS: "mySonarScannerJavaOpts",
+    SONAR_SCANNER_METADATA_FILEPATH: "myMetadataFilepath",
+    SONAR_REGION: "us",
+    SONAR_USER_HOME: "mySonarUserHome",
+    SONAR_FILESIZE_LIMIT: 1000,
+    SONAR_CPD_PYTHON_MINIMUM_TOKENS: 15,
+    SONAR_CPD_PYTHON_MINIMUM_LINES: 100,
+    SONAR_SCM_EXCLUSIONS_DISABLED: True,
+    SONAR_LOG_LEVEL: "INFO",
+    SONAR_QUALITYGATE_WAIT: True,
+    SONAR_QUALITYGATE_TIMEOUT: 120,
+    SONAR_EXTERNAL_ISSUES_REPORT_PATHS: "path/to/external/issues",
+    SONAR_SARIF_REPORT_PATHS: "path/to/sarif/reports",
+    SONAR_LINKS_CI: "http://ci.example.com",
+    SONAR_LINKS_HOMEPAGE: "http://homepage.example.com",
+    SONAR_LINKS_ISSUE: "http://issues.example.com",
+    SONAR_LINKS_SCM: "http://scm.example.com",
+    SONAR_BRANCH_NAME: "feature-branch",
+    SONAR_PULLREQUEST_KEY: "123",
+    SONAR_PULLREQUEST_BRANCH: "feature-branch",
+    SONAR_PULLREQUEST_BASE: "main",
+    SONAR_NEWCODE_REFERENCE_BRANCH: "develop",
+    SONAR_SCM_REVISION: "abc123",
+    SONAR_BUILD_STRING: "build-42",
+    SONAR_SOURCE_ENCODING: "UTF-8",
+    SONAR_WORKING_DIRECTORY: "/tmp/sonar",
+    SONAR_SCM_FORCE_RELOAD_ALL: True,
+}
+
 
 class TestCliConfigurationLoader(unittest.TestCase):
     def setUp(self):
@@ -119,6 +206,14 @@ def test_impossible_os_choice(self):
             "myProjectKey",
             "--sonar-project-name",
             "myProjectName",
+            "--sonar-project-version",
+            "myProjectVersion",
+            "--sonar-project-description",
+            "myProjectDescription",
+            "--sonar-sources",
+            "mySources",
+            "--sonar-tests",
+            "myTests",
             "-v",
             "--sonar-host-url",
             "mySonarHostUrl",
@@ -139,6 +234,8 @@ def test_impossible_os_choice(self):
             "mySonarScannerJavaExePath",
             "--sonar-scanner-java-opts",
             "mySonarScannerJavaOpts",
+            "--sonar-scanner-metadata-filepath",
+            "myMetadataFilepath",
             "--sonar-scanner-internal-dump-to-file",
             "mySonarScannerInternalDumpToFile",
             "--sonar-scanner-internal-sq-version",
@@ -167,42 +264,54 @@ def test_impossible_os_choice(self):
             "mySonarScannerProxyPassword",
             "--sonar-project-base-dir",
             "mySonarProjectBaseDir",
+            "--sonar-filesize-limit",
+            "1000",
+            "--sonar-scm-exclusions-disabled",
+            "--sonar-cpd-python-minimum-tokens",
+            "15",
+            "--sonar-cpd-python-minimum-lines",
+            "100",
+            "--sonar-log-level",
+            "INFO",
+            "--sonar-qualitygate-wait",
+            "--sonar-qualitygate-timeout",
+            "120",
+            "--sonar-external-issues-report-paths",
+            "path/to/external/issues",
+            "--sonar-sarif-report-paths",
+            "path/to/sarif/reports",
+            "--sonar-links-ci",
+            "http://ci.example.com",
+            "--sonar-links-homepage",
+            "http://homepage.example.com",
+            "--sonar-links-issue",
+            "http://issues.example.com",
+            "--sonar-links-scm",
+            "http://scm.example.com",
+            "--sonar-branch-name",
+            "feature-branch",
+            "--sonar-pullrequest-key",
+            "123",
+            "--sonar-pullrequest-branch",
+            "feature-branch",
+            "--sonar-pullrequest-base",
+            "main",
+            "--sonar-newcode-reference-branch",
+            "develop",
+            "--sonar-scm-revision",
+            "abc123",
+            "--sonar-build-string",
+            "build-42",
+            "--sonar-source-encoding",
+            "UTF-8",
+            "--sonar-working-directory",
+            "/tmp/sonar",
+            "--sonar-scm-force-reload-all",
         ],
     )
     def test_all_cli_args(self):
         configuration = CliConfigurationLoader.load()
-        expected_configuration = {
-            SONAR_TOKEN: "myToken",
-            SONAR_PROJECT_KEY: "myProjectKey",
-            SONAR_PROJECT_NAME: "myProjectName",
-            SONAR_VERBOSE: True,
-            SONAR_HOST_URL: "mySonarHostUrl",
-            SONAR_SCANNER_SONARCLOUD_URL: "mySonarScannerCloudUrl",
-            SONAR_SCANNER_API_BASE_URL: "mySonarScannerApiUrl",
-            SONAR_SCANNER_OS: "windows",
-            SONAR_SCANNER_ARCH: "x64",
-            SONAR_SCANNER_CONNECT_TIMEOUT: 42,
-            SONAR_SCANNER_INTERNAL_DUMP_TO_FILE: "mySonarScannerInternalDumpToFile",
-            SONAR_SCANNER_INTERNAL_SQ_VERSION: "mySonarScannerInternalSqVersion",
-            SONAR_SCANNER_SOCKET_TIMEOUT: 43,
-            SONAR_SCANNER_RESPONSE_TIMEOUT: 44,
-            SONAR_SCANNER_TRUSTSTORE_PATH: "mySonarScannerTruststorePath",
-            SONAR_SCANNER_TRUSTSTORE_PASSWORD: "mySonarScannerTruststorePassword",
-            SONAR_SCANNER_KEYSTORE_PATH: "mySonarScannerKeystorePath",
-            SONAR_SCANNER_KEYSTORE_PASSWORD: "mySonarScannerKeystorePassword",
-            SONAR_SCANNER_PROXY_HOST: "mySonarScannerProxyHost",
-            SONAR_SCANNER_PROXY_PORT: 45,
-            SONAR_SCANNER_PROXY_USER: "mySonarScannerProxyUser",
-            SONAR_SCANNER_PROXY_PASSWORD: "mySonarScannerProxyPassword",
-            SONAR_SCANNER_SKIP_JRE_PROVISIONING: True,
-            SONAR_SCANNER_JAVA_EXE_PATH: "mySonarScannerJavaExePath",
-            SONAR_SCANNER_JAVA_OPTS: "mySonarScannerJavaOpts",
-            SONAR_REGION: "us",
-            SONAR_USER_HOME: "mySonarUserHome",
-            SONAR_PROJECT_BASE_DIR: "mySonarProjectBaseDir",
-        }
-
-        self.assertEqual(configuration, expected_configuration)
+        self.assertEqual(configuration, EXPECTED_CONFIGURATION)
 
     @patch(
         "sys.argv",
@@ -210,7 +319,12 @@ def test_all_cli_args(self):
             "myscript.py",
             "-Dsonar.token=myToken",
             "-Dsonar.projectKey=myProjectKey",
+            "-Dsonar.projectName=myProjectName",
+            "-Dsonar.projectVersion=myProjectVersion",
+            "-Dsonar.projectDescription=myProjectDescription",
             "-Dsonar.verbose",
+            "-Dsonar.sources=mySources",
+            "-Dsonar.tests=myTests",
             "-Dsonar.host.url=mySonarHostUrl",
             "-Dsonar.scanner.cloudUrl=mySonarScannerCloudUrl",
             "-Dsonar.scanner.apiUrl=mySonarScannerApiUrl",
@@ -232,42 +346,68 @@ def test_all_cli_args(self):
             "-Dsonar.scanner.skipJreProvisioning",
             "-Dsonar.scanner.javaExePath=mySonarScannerJavaExePath",
             "-Dsonar.scanner.javaOpts=mySonarScannerJavaOpts",
+            "-Dsonar.scanner.metadataFilepath=myMetadataFilepath",
             "-Dsonar.region=us",
             "-Dsonar.userHome=mySonarUserHome",
             "-Dsonar.projectBaseDir=mySonarProjectBaseDir",
+            "-Dsonar.filesize.limit=1000",
+            "-Dsonar.scm.exclusions.disabled=true",
+            "-Dsonar.cpd.python.minimumTokens=15",
+            "-Dsonar.cpd.python.minimumLines=100",
+            "-Dsonar.qualitygate.wait=true",
+            "-Dsonar.qualitygate.timeout=120",
+            "-Dsonar.externalIssuesReportPaths=path/to/external/issues",
+            "-Dsonar.sarifReportPaths=path/to/sarif/reports",
+            "-Dsonar.links.ci=http://ci.example.com",
+            "-Dsonar.links.homepage=http://homepage.example.com",
+            "-Dsonar.links.issue=http://issues.example.com",
+            "-Dsonar.links.scm=http://scm.example.com",
+            "-Dsonar.branch.name=feature-branch",
+            "-Dsonar.pullrequest.key=123",
+            "-Dsonar.pullrequest.branch=feature-branch",
+            "-Dsonar.pullrequest.base=main",
+            "-Dsonar.newCode.referenceBranch=develop",
+            "-Dsonar.scm.revision=abc123",
+            "-Dsonar.buildString=build-42",
+            "-Dsonar.sourceEncoding=UTF-8",
+            "-Dsonar.working.directory=/tmp/sonar",
+            "-Dsonar.scm.forceReloadAll=true",
+            "-Dsonar.log.level=INFO",
         ],
     )
     def test_jvm_style_cli_args(self):
         configuration = CliConfigurationLoader.load()
-        expected_configuration = {
-            "sonar.token": "myToken",
-            "sonar.projectKey": "myProjectKey",
-            "sonar.verbose": True,
-            "sonar.host.url": "mySonarHostUrl",
-            "sonar.scanner.sonarcloudUrl": "mySonarScannerCloudUrl",
-            "sonar.scanner.apiBaseUrl": "mySonarScannerApiUrl",
-            "sonar.scanner.os": "windows",
-            "sonar.scanner.arch": "x64",
-            "sonar.scanner.connectTimeout": 42,
-            "sonar.scanner.internal.dumpToFile": "mySonarScannerInternalDumpToFile",
-            "sonar.scanner.internal.sqVersion": "mySonarScannerInternalSqVersion",
-            "sonar.scanner.socketTimeout": 43,
-            "sonar.scanner.responseTimeout": 44,
-            "sonar.scanner.truststorePath": "mySonarScannerTruststorePath",
-            "sonar.scanner.truststorePassword": "mySonarScannerTruststorePassword",
-            "sonar.scanner.keystorePath": "mySonarScannerKeystorePath",
-            "sonar.scanner.keystorePassword": "mySonarScannerKeystorePassword",
-            "sonar.scanner.proxyHost": "mySonarScannerProxyHost",
-            "sonar.scanner.proxyPort": 45,
-            "sonar.scanner.proxyUser": "mySonarScannerProxyUser",
-            "sonar.scanner.proxyPassword": "mySonarScannerProxyPassword",
-            "sonar.scanner.skipJreProvisioning": True,
-            "sonar.scanner.javaExePath": "mySonarScannerJavaExePath",
-            "sonar.scanner.javaOpts": "mySonarScannerJavaOpts",
-            "sonar.region": "us",
-            "sonar.userHome": "mySonarUserHome",
-            "sonar.projectBaseDir": "mySonarProjectBaseDir",
-        }
-        for key in expected_configuration:
-            self.assertEqual(configuration[key], expected_configuration[key])
-        self.assertEqual(configuration, expected_configuration)
+        self.assertEqual(configuration, EXPECTED_CONFIGURATION)
+
+    def test_both_boolean_args_given(self):
+        patch_template = ["myscript.py", "--token", "myToken", "--sonar-project-key", "myProjectKey"]
+
+        with patch("sys.argv", patch_template):
+            configuration = CliConfigurationLoader.load()
+            self.assertFalse(configuration.get(SONAR_SCM_EXCLUSIONS_DISABLED))
+
+        # the python args parser allows to use --no-* prefix to pass a False value to a boolean option
+        with patch("sys.argv", [*patch_template, "--no-sonar-scm-exclusions-disabled"]):
+            configuration = CliConfigurationLoader.load()
+            self.assertFalse(configuration.get(SONAR_SCM_EXCLUSIONS_DISABLED))
+
+        # When both options are given, a logic OR is applied on the two
+        with patch(
+            "sys.argv", [*patch_template, "--no-sonar-scm-exclusions-disabled", "-Dsonar.scm.exclusions.disabled=true"]
+        ):
+            configuration = CliConfigurationLoader.load()
+            self.assertTrue(configuration.get(SONAR_SCM_EXCLUSIONS_DISABLED))
+
+        with patch(
+            "sys.argv", [*patch_template, "-Dsonar.scm.exclusions.disabled=true", "--sonar-scm-exclusions-disabled"]
+        ):
+            configuration = CliConfigurationLoader.load()
+            self.assertTrue(configuration.get(SONAR_SCM_EXCLUSIONS_DISABLED))
+
+        with patch("sys.argv", [*patch_template, "--sonar-scm-exclusions-disabled"]):
+            configuration = CliConfigurationLoader.load()
+            self.assertTrue(configuration.get(SONAR_SCM_EXCLUSIONS_DISABLED))
+
+        with patch("sys.argv", [*patch_template, "-Dsonar.scm.exclusions.disabled=true"]):
+            configuration = CliConfigurationLoader.load()
+            self.assertTrue(configuration.get(SONAR_SCM_EXCLUSIONS_DISABLED))


Reviews:
user: login: thomas-serre-sonarsource
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-24T15:55:04Z
user: login: thomas-serre-sonarsource
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-24T15:55:59Z
user: login: Seppli11
body: The actual implementation look good. Thanks for doing the Sisyphus work of actually adding all the supported parameters.

I've left a few nitpicks, as well as a bigger question. Because of that I've marked the PR as "request changes". 
state: CHANGES_REQUESTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-25T10:39:04Z
user: login: Seppli11
body: Thanks for the changes.

I've left some nitpicks, but nothing big enough to warrant it going through review again.
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-03-26T07:42:38Z
user: login: thomas-serre-sonarsource
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-27T13:21:43Z
user: login: thomas-serre-sonarsource
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-27T13:47:32Z

Review comments:
diff_hunk: @@ -53,15 +53,41 @@
 SONAR_SCANNER_PROXY_PORT: Key = "sonar.scanner.proxyPort"
 SONAR_SCANNER_PROXY_USER: Key = "sonar.scanner.proxyUser"
 SONAR_SCANNER_PROXY_PASSWORD: Key = "sonar.scanner.proxyPassword"
-SONAR_PROJECT_BASE_DIR: Key = "sonar.projectBaseDir"
path: src/pysonar_scanner/configuration/properties.py
user: login: thomas-serre-sonarsource
body: moved below to be close to the other SONAR_PROJECT_* properties
created_at: 2025-03-24T15:55:03Z
author_association: CONTRIBUTOR
diff_hunk: @@ -243,20 +269,160 @@ def python_name(self) -> str:
         default_value=None, 
         cli_getter=lambda args: args.sonar_scanner_java_opts
     ),
+    Property(
+        name=SONAR_SCANNER_METADATA_FILEPATH,
+        default_value=None,
+        cli_getter=lambda args: args.sonar_scanner_metadata_filepath
+    ),
     Property(
         name=SONAR_PROJECT_KEY, 
         default_value=None, 
         cli_getter=lambda args: args.sonar_project_key
     ),
     Property(
-            name=SONAR_PROJECT_NAME,
-            default_value=None,
-            cli_getter=lambda args: args.sonar_project_name
+        name=SONAR_PROJECT_NAME,
+        default_value=None,
+        cli_getter=lambda args: args.sonar_project_name
+    ),
+    Property(
+        name=SONAR_PROJECT_VERSION,
+        default_value=None,
+        cli_getter=lambda args: args.sonar_project_version
+    ),
+    Property(
+        name=SONAR_PROJECT_DESCRIPTION,
+        default_value=None,
+        cli_getter=lambda args: args.sonar_project_description
+    ),
+    Property(
+        name=SONAR_SOURCES,
+        default_value=None,
+        cli_getter=lambda args: args.sonar_sources
+    ),
+    Property(
+        name=SONAR_TESTS,
+        default_value=None,
+        cli_getter=lambda args: args.sonar_tests
+    ),
+    Property(
+        name=SONAR_FILESIZE_LIMIT,
+        default_value=None,
+        cli_getter=lambda args: args.sonar_filesize_limit
+    ),
+    Property(
+        name=SONAR_SCM_EXCLUSIONS_DISABLED,
+        default_value=None,
+        cli_getter=lambda args: args.sonar_scm_exclusions_disabled
+    ),
+    Property(
+        name=SONAR_CPD_PYTHON_MINIMUM_TOKENS,
+        default_value=None,
+        cli_getter=lambda args: args.sonar_cpd_python_minimum_tokens
     ),
     Property(
-            name=TOML_PATH,
-            default_value=None,
-            cli_getter=lambda args: args.toml_path
path: src/pysonar_scanner/configuration/properties.py
user: login: thomas-serre-sonarsource
body: Moved below and realigned
created_at: 2025-03-24T15:55:59Z
author_association: CONTRIBUTOR
diff_hunk: @@ -243,20 +268,160 @@ def python_name(self) -> str:
         default_value=None, 
         cli_getter=lambda args: args.sonar_scanner_java_opts
     ),
+    Property(
+        name=SONAR_SCANNER_METADATA_FILEPATH,
+        default_value=None,
+        cli_getter=lambda args: args.sonar_scanner_metadata_filepath
+    ),
     Property(
         name=SONAR_PROJECT_KEY, 
         default_value=None, 
         cli_getter=lambda args: args.sonar_project_key
     ),
     Property(
-            name=SONAR_PROJECT_NAME,
-            default_value=None,
-            cli_getter=lambda args: args.sonar_project_name
+        name=SONAR_PROJECT_NAME,
+        default_value=None,
+        cli_getter=lambda args: args.sonar_project_name
+    ),
+    Property(
+        name=SONAR_PROJECT_VERSION,
+        default_value=None,
+        cli_getter=lambda args: args.sonar_project_version
+    ),
+    Property(
+        name=SONAR_PROJECT_DESCRIPTION,
+        default_value=None,
+        cli_getter=lambda args: args.sonar_project_description
     ),
     Property(
-            name=TOML_PATH,
-            default_value=None,
-            cli_getter=lambda args: args.toml_path
+        name=SONAR_SOURCES,
+        default_value=None,
+        cli_getter=lambda args: args.sonar_sources
     ),
+    Property(
+        name=SONAR_TESTS,
+        default_value=None,
+        cli_getter=lambda args: args.sonar_tests
+    ),
+    Property(
+        name=SONAR_FILESIZE_LIMIT,
+        default_value=None,
+        cli_getter=lambda args: args.sonar_filesize_limit
+    ),
+    Property(
+        name=SONAR_SCM_EXCLUSIONS_DISABLED,
+        default_value=None,
+        cli_getter=lambda args: args.sonar_scm_exclusions_disabled
+    ),
+    Property(
+        name=SONAR_CPD_PYTHON_MINIMUM_TOKENS,
+        default_value=None,
+        cli_getter=lambda args: args.sonar_cpd_python_minimum_tokens
+    ),
+    Property(
+        name=SONAR_CPD_PYTHON_MINIMUM_LINES,
+        default_value=None,
+        cli_getter=lambda args: args.sonar_cpd_python_minimum_lines
+    ),
+    Property(
+        name=SONAR_LOG_LEVEL,
+        default_value=None,
+        cli_getter=lambda args: args.sonar_log_level
+    ),
+    Property(
+        name=TOML_PATH,
+        default_value=None,
+        cli_getter=lambda args: args.toml_path
+    ),
+    Property(
+        name=SONAR_QUALITYGATE_WAIT, 
+        default_value=None, 
+        cli_getter=lambda args: args.sonar_qualitygate_wait
+        ),
path: src/pysonar_scanner/configuration/properties.py
user: login: Seppli11
body: nitpick: from here on is the formatting of the closing parenthesis off
created_at: 2025-03-24T16:20:55Z
author_association: CONTRIBUTOR
diff_hunk: @@ -114,6 +137,12 @@ def __parse_cli_args(cls) -> argparse.Namespace:
             choices=["x64", "aarch64"],
             help="Architecture on which the scanner will be running",
         )
+        parser.add_argument(
+            "--sonar-scanner-metadata-filepath",
+            "-Dsonar.scanner.metadata.filepath",
path: src/pysonar_scanner/configuration/cli.py
user: login: Seppli11
body: in the documentation this is refereed to as `sonar.scanner.metadataFilePath`
```suggestion
            "-Dsonar.scanner.metadataFilePath",
```
created_at: 2025-03-24T16:24:02Z
author_association: CONTRIBUTOR
diff_hunk: @@ -207,6 +236,136 @@ def __parse_cli_args(cls) -> argparse.Namespace:
             help="Directory containing the project to be analyzed. Default is the current directory",
         )
 
+        parser.add_argument(
path: src/pysonar_scanner/configuration/cli.py
user: login: Seppli11
body: Having an argument where you have to specify true or false feels strange for a CLI (especially when we do have `--verbose` which acts as a switch). However, since we want to be compatible with the previous scanner this is almost a must. 
I wonder though if we could treat `--sonar-scm-exclusions-disabled` as a `BooleanOptionalAction` and `-Dsonar.scm.exclusion.disabled` is stays a `bool`. 
I think this would require two `add_argument` calls, however, they could be unified in the `Property.cli_getter` of this property.
created_at: 2025-03-24T16:36:28Z
author_association: CONTRIBUTOR
diff_hunk: @@ -207,6 +236,136 @@ def __parse_cli_args(cls) -> argparse.Namespace:
             help="Directory containing the project to be analyzed. Default is the current directory",
         )
 
+        parser.add_argument(
+            "--sonar-scm-exclusions-disabled",
+            "-Dsonar.scm.exclusions.disabled",
+            type=bool,
+            help="Defines whether files ignored by the SCM, e.g., files listed in .gitignore, will be excluded from the analysis or not",
+        )
+
+        parser.add_argument(
+            "--sonar-filesize-limit",
+            "-Dsonar.filesize.limit",
+            type=int,
+            help="Sets the limit in MB for files to be discarded from the analysis scope if the size is greater than specified",
+        )
+
+        parser.add_argument(
+            "--sonar-cpd-python-minimum-tokens",
+            "-Dsonar.cpd.python.minimumTokens",
+            type=int,
+            help="Minimum number of tokens to be considered as a duplicated block of code",
+        )
+        parser.add_argument(
+            "--sonar-cpd-python-minimum-lines",
+            "-Dsonar.cpd.python.minimumLines",
+            type=int,
+            help="Minimum number of tokens to be considered as a duplicated block of code",
+        )
+
+        parser.add_argument(
+            "--sonar-log-level",
+            "-Dsonar.log.level",
+            type=str,
+            choices=["TRACE", "DEBUG", "INFO", "WARN", "ERROR"],
+            help="Log level during the analysis",
+        )
+        parser.add_argument(
+            "--sonar-qualitygate-wait",
+            "-Dsonar.qualitygate.wait",
+            type=bool,
+            help="Forces the analysis step to poll the server instance and wait for the Quality Gate status",
+        )
+        parser.add_argument(
+            "--sonar-qualitygate-timeout",
+            "-Dsonar.qualitygate.timeout",
path: src/pysonar_scanner/configuration/cli.py
user: login: Seppli11
body: same question as a above
created_at: 2025-03-24T16:37:08Z
author_association: CONTRIBUTOR
diff_hunk: @@ -207,6 +236,136 @@ def __parse_cli_args(cls) -> argparse.Namespace:
             help="Directory containing the project to be analyzed. Default is the current directory",
         )
 
+        parser.add_argument(
+            "--sonar-scm-exclusions-disabled",
+            "-Dsonar.scm.exclusions.disabled",
+            type=bool,
+            help="Defines whether files ignored by the SCM, e.g., files listed in .gitignore, will be excluded from the analysis or not",
+        )
+
+        parser.add_argument(
+            "--sonar-filesize-limit",
+            "-Dsonar.filesize.limit",
+            type=int,
+            help="Sets the limit in MB for files to be discarded from the analysis scope if the size is greater than specified",
+        )
+
+        parser.add_argument(
+            "--sonar-cpd-python-minimum-tokens",
+            "-Dsonar.cpd.python.minimumTokens",
+            type=int,
+            help="Minimum number of tokens to be considered as a duplicated block of code",
+        )
+        parser.add_argument(
+            "--sonar-cpd-python-minimum-lines",
+            "-Dsonar.cpd.python.minimumLines",
+            type=int,
+            help="Minimum number of tokens to be considered as a duplicated block of code",
+        )
+
+        parser.add_argument(
+            "--sonar-log-level",
+            "-Dsonar.log.level",
+            type=str,
+            choices=["TRACE", "DEBUG", "INFO", "WARN", "ERROR"],
+            help="Log level during the analysis",
+        )
+        parser.add_argument(
+            "--sonar-qualitygate-wait",
+            "-Dsonar.qualitygate.wait",
+            type=bool,
+            help="Forces the analysis step to poll the server instance and wait for the Quality Gate status",
+        )
+        parser.add_argument(
+            "--sonar-qualitygate-timeout",
+            "-Dsonar.qualitygate.timeout",
+            type=int,
+            help="The number of seconds that the scanner should wait for a report to be processed",
+        )
+        parser.add_argument(
+            "--sonar-external-issues-report-paths",
+            "-Dsonar.externalIssuesReportPaths",
+            type=str,
+            help="Comma-delimited list of paths to generic issue reports",
+        )
+        parser.add_argument(
+            "--sonar-sarif-report-paths",
+            "-Dsonar.sarifReportPaths",
+            type=str,
+            help="Comma-delimited list of paths to SARIF issue reports",
+        )
+        parser.add_argument(
+            "--sonar-links-ci", "-Dsonar.links.ci", type=str, help="The URL of the continuous integration system used"
+        )
+        parser.add_argument(
+            "--sonar-links-homepage", "-Dsonar.links.homepage", type=str, help="The URL of the build project home page"
+        )
+        parser.add_argument(
+            "--sonar-links-issue", "-Dsonar.links.issue", type=str, help="The URL to the issue tracker being used"
+        )
+        parser.add_argument(
+            "--sonar-links-scm",
+            "-Dsonar.links.scm",
+            type=str,
+            help="The URL of the build project source code repository",
+        )
+        parser.add_argument(
+            "--sonar-branch-name", "-Dsonar.branch.name", type=str, help="Name of the branch being analyzed"
+        )
+        parser.add_argument(
+            "--sonar-pullrequest-key",
+            "-Dsonar.pullrequest.key",
+            type=str,
+            help="Key of the pull request being analyzed",
+        )
+        parser.add_argument(
+            "--sonar-pullrequest-branch",
+            "-Dsonar.pullrequest.branch",
+            type=str,
+            help="Branch of the pull request being analyzed",
+        )
+        parser.add_argument(
+            "--sonar-pullrequest-base",
+            "-Dsonar.pullrequest.base",
+            type=str,
+            help="Base branch of the pull request being analyzed",
+        )
+        parser.add_argument(
+            "--sonar-newcode-reference-branch",
+            "-Dsonar.newCode.referenceBranch",
+            type=str,
+            help="Reference branch for new code definition",
+        )
+        parser.add_argument(
+            "--sonar-scm-revision",
+            "-Dsonar.scm.revision",
+            type=str,
+            help="Overrides the revision, for instance, the Git sha1, displayed in analysis results",
+        )
+        parser.add_argument(
+            "--sonar-build-string",
+            "-Dsonar.buildString",
+            type=str,
+            help="The string passed with this property will be stored with the analysis and available in the results of api/project_analyses/search, thus allowing you to later identify a specific analysis and obtain its key for use with api/new_code_periods/set on the SPECIFIC_ANALYSIS type",
+        )
+        parser.add_argument(
+            "--sonar-source-encoding",
+            "-Dsonar.sourceEncoding",
+            type=str,
+            help="Encoding of the source files. For example, UTF-8, MacRoman, Shift_JIS",
+        )
+        parser.add_argument(
+            "--sonar-working-directory",
+            "-Dsonar.working.directory",
+            type=str,
+            help="Path to the working directory used by the Sonar scanner during a project analysis to store temporary data",
+        )
+        parser.add_argument(
+            "--sonar-scm-force-reload-all",
+            "-Dsonar.scm.forceReloadAll",
+            type=bool,
path: src/pysonar_scanner/configuration/cli.py
user: login: Seppli11
body: same question as above
created_at: 2025-03-24T16:37:32Z
author_association: CONTRIBUTOR
diff_hunk: @@ -27,7 +27,7 @@ class CliConfigurationLoader:
     @classmethod
     def load(cls) -> dict[str, any]:
         args = cls.__parse_cli_args()
-
+        print(args)
path: src/pysonar_scanner/configuration/cli.py
user: login: Seppli11
body: That's probably for debugging?
created_at: 2025-03-25T15:53:53Z
author_association: CONTRIBUTOR
diff_hunk: @@ -362,10 +373,15 @@ def __parse_cli_args(cls) -> argparse.Namespace:
         )
         parser.add_argument(
             "--sonar-scm-force-reload-all",
-            "-Dsonar.scm.forceReloadAll",
             type=bool,
+            action=argparse.BooleanOptionalAction,
             help="Set this property to true to load blame information for all files, which may significantly increase analysis duration",
         )
+        parser.add_argument(
+            "-Dsonar.scm.forceReloadAll",
+            type=bool,
+            help="Equivalent to --sonar-scm-force-reload-all",
+        )
path: src/pysonar_scanner/configuration/cli.py
user: login: Seppli11
body: Alternatively to using `getattr`, you can also set the `dest` arg (see [here](https://docs.python.org/3/library/argparse.html#dest)). But there is no real advantage in either approach.

```suggestion
        parser.add_argument(
            "-Dsonar.scm.forceReloadAll",
            type=bool,
            help="Equivalent to --sonar-scm-force-reload-all",
            dest="sonar_scm_force_reload_all_alternative",
        )
```
created_at: 2025-03-25T16:00:29Z
author_association: CONTRIBUTOR
path: tests/test_configuration_cli.py
user: login: Seppli11
body: It would be nice to have a dedicated test around the introduced boolean arguments. E.g. what happens when both are present
created_at: 2025-03-26T07:41:59Z
author_association: CONTRIBUTOR
diff_hunk: @@ -27,7 +27,7 @@ class CliConfigurationLoader:
     @classmethod
     def load(cls) -> dict[str, any]:
         args = cls.__parse_cli_args()
-
+        print(args)
path: src/pysonar_scanner/configuration/cli.py
user: login: thomas-serre-sonarsource
body: arf thanks for spotting this ... Second time I forget to clean  my mess :s 
created_at: 2025-03-27T13:21:42Z
author_association: CONTRIBUTOR
path: tests/test_configuration_cli.py
user: login: thomas-serre-sonarsource
body: I ve added a few :) Thanks for the suggestion ! <3
created_at: 2025-03-27T13:47:31Z
author_association: CONTRIBUTOR

PR comments:
user: login: sonarqube-next[bot]
created_at: 2025-03-27T13:48:28Z
body: ## [![Quality Gate passed](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v104/checks/QualityGateBadge/passed-16px.png 'Quality Gate passed')](https://next.sonarqube.com/sonarqube/dashboard?id=SonarSource_sonar-scanner-python&pullRequest=163) **Quality Gate passed for 'Python Scanner'**  
Issues  
[![](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v104/common/passed-16px.png '')](https://next.sonarqube.com/sonarqube/project/issues?id=SonarSource_sonar-scanner-python&pullRequest=163&resolved=false) [0 New issues](https://next.sonarqube.com/sonarqube/project/issues?id=SonarSource_sonar-scanner-python&pullRequest=163&resolved=false)  
[![](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v104/common/fixed-16px.png '')](https://next.sonarqube.com/sonarqube/project/issues?id=SonarSource_sonar-scanner-python&fixedInPullRequest=163) [0 Fixed issues](https://next.sonarqube.com/sonarqube/project/issues?id=SonarSource_sonar-scanner-python&fixedInPullRequest=163)  
[![](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v104/common/accepted-16px.png '')](https://next.sonarqube.com/sonarqube/project/issues?id=SonarSource_sonar-scanner-python&pullRequest=163&issueStatuses=ACCEPTED) [0 Accepted issues](https://next.sonarqube.com/sonarqube/project/issues?id=SonarSource_sonar-scanner-python&pullRequest=163&issueStatuses=ACCEPTED)

Measures  
[![](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v104/common/passed-16px.png '')](https://next.sonarqube.com/sonarqube/security_hotspots?id=SonarSource_sonar-scanner-python&pullRequest=163) [0 Security Hotspots](https://next.sonarqube.com/sonarqube/security_hotspots?id=SonarSource_sonar-scanner-python&pullRequest=163)  
[![](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v104/common/passed-16px.png '')](https://next.sonarqube.com/sonarqube/component_measures?id=SonarSource_sonar-scanner-python&pullRequest=163&metric=new_coverage&view=list) [100.0% Coverage on New Code](https://next.sonarqube.com/sonarqube/component_measures?id=SonarSource_sonar-scanner-python&pullRequest=163&metric=new_coverage&view=list)  
[![](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v104/common/passed-16px.png '')](https://next.sonarqube.com/sonarqube/component_measures?id=SonarSource_sonar-scanner-python&pullRequest=163&metric=new_duplicated_lines_density&view=list) [0.0% Duplication on New Code](https://next.sonarqube.com/sonarqube/component_measures?id=SonarSource_sonar-scanner-python&pullRequest=163&metric=new_duplicated_lines_density&view=list)  
  
[See analysis details on SonarQube](https://next.sonarqube.com/sonarqube/dashboard?id=SonarSource_sonar-scanner-python&pullRequest=163)


author_association: NONE