diff --git a/CLI_ARGS.md b/CLI_ARGS.md index c476719a..a019443d 100644 --- a/CLI_ARGS.md +++ b/CLI_ARGS.md @@ -96,7 +96,7 @@ | `--sonar-source-encoding`, `-Dsonar.sourceEncoding` | Encoding of the source files. For example, UTF-8, MacRoman, Shift_JIS | | `--sonar-user-home`, `-Dsonar.userHome` | Base sonar directory, ~/.sonar by default | | `--sonar-working-directory`, `-Dsonar.working.directory` | Path to the working directory used by the Sonar scanner during a project analysis to store temporary data | -| `--toml-path` | Path to the pyproject.toml file. If not provided, it will look in the SONAR_PROJECT_BASE_DIR | +| `--toml-path` | Path to the pyproject.toml file or to the folder containing it. If not provided, it will look in the SONAR_PROJECT_BASE_DIR | | `-Dsonar.python.skipUnchanged` | Equivalent to --sonar-python-skip-unchanged | | `-Dsonar.python.xunit.skipDetails` | Equivalent to -Dsonar.python.xunit.skipDetails | | `-Dsonar.qualitygate.wait` | Equivalent to --sonar-qualitygate-wait | diff --git a/README.md b/README.md index ad000b01..9a63842b 100644 --- a/README.md +++ b/README.md @@ -85,12 +85,18 @@ Properties in `pyproject.toml` files are expected to be provided in camel case. project-key=My Project key # valid alias for projectKey ``` -By default, the scanner will expect the `pyproject.toml` file to be present in the current directory. However, its path can be provided manually through the `toml-path` CLI argument as well as through the `sonar.projectBaseDir` argument. For instance: +By default, the scanner will expect the `pyproject.toml` file to be present in the current directory. However, its path can be provided manually through the `toml-path` CLI argument as well as through the `sonar.projectBaseDir` argument. The `--toml-path` argument accepts either the path to the `pyproject.toml` file itself or to the folder containing it. For instance: ``` pysonar --toml-path "path/to/pyproject.toml" ``` +Or equivalently: + +``` +pysonar --toml-path "path/to" +``` + Or: ``` diff --git a/src/pysonar_scanner/configuration/cli.py b/src/pysonar_scanner/configuration/cli.py index 1ddaa280..87566ad4 100644 --- a/src/pysonar_scanner/configuration/cli.py +++ b/src/pysonar_scanner/configuration/cli.py @@ -142,7 +142,7 @@ def __create_parser(cls): parser.add_argument( "--toml-path", type=str, - help="Path to the pyproject.toml file. If not provided, it will look in the SONAR_PROJECT_BASE_DIR", + help="Path to the pyproject.toml file or to the folder containing it. If not provided, it will look in the SONAR_PROJECT_BASE_DIR", ) parser.add_argument( diff --git a/src/pysonar_scanner/configuration/configuration_loader.py b/src/pysonar_scanner/configuration/configuration_loader.py index b09a1718..74f33fec 100644 --- a/src/pysonar_scanner/configuration/configuration_loader.py +++ b/src/pysonar_scanner/configuration/configuration_loader.py @@ -49,8 +49,8 @@ def load() -> dict[Key, Any]: base_dir = Path(cli_properties.get(SONAR_PROJECT_BASE_DIR, ".")) toml_path_property = cli_properties.get("toml-path", ".") - toml_dir = Path(toml_path_property) if "toml-path" in cli_properties else base_dir - toml_properties = TomlConfigurationLoader.load(toml_dir) + toml_path = Path(toml_path_property) if "toml-path" in cli_properties else base_dir + toml_properties = TomlConfigurationLoader.load(toml_path) coverage_properties = CoverageRCConfigurationLoader.load_exclusion_properties(base_dir) resolved_properties = get_static_default_properties() diff --git a/src/pysonar_scanner/configuration/pyproject_toml.py b/src/pysonar_scanner/configuration/pyproject_toml.py index 1d3ddb91..b60e9eba 100644 --- a/src/pysonar_scanner/configuration/pyproject_toml.py +++ b/src/pysonar_scanner/configuration/pyproject_toml.py @@ -37,8 +37,11 @@ def __init__(self, sonar_properties: Dict[str, str], project_properties: Dict[st class TomlConfigurationLoader: @staticmethod - def load(base_dir: Path) -> TomlProperties: - filepath = base_dir / "pyproject.toml" + def load(toml_path: Path) -> TomlProperties: + if toml_path.name == "pyproject.toml": + filepath = toml_path + else: + filepath = toml_path / "pyproject.toml" if not os.path.isfile(filepath): logging.debug(f"No pyproject.toml at {filepath}") return TomlProperties({}, {}) diff --git a/tests/unit/test_configuration_loader.py b/tests/unit/test_configuration_loader.py index a3846186..a221acc8 100644 --- a/tests/unit/test_configuration_loader.py +++ b/tests/unit/test_configuration_loader.py @@ -308,6 +308,58 @@ def test_load_pyproject_toml_from_toml_path(self, mock_get_os, mock_get_arch): } self.assertDictEqual(configuration, expected_configuration) + @patch( + "sys.argv", + [ + "myscript.py", + "--token", + "myToken", + "--sonar-project-key", + "myProjectKey", + "--toml-path", + "custom/path/pyproject.toml", + ], + ) + def test_load_pyproject_toml_from_toml_path_with_file(self, mock_get_os, mock_get_arch): + self.fs.create_dir("custom/path") + self.fs.create_file( + "custom/path/pyproject.toml", + contents=( + """ + [tool.sonar] + projectKey = "custom-path-project-key" + project-name = "Custom Path Project" + sources = "src/main" + tests= "src/test" + scanner.javaHeapSize = "8000Mb" + """ + ), + ) + configuration = ConfigurationLoader.load() + expected_configuration = { + SONAR_TOKEN: "myToken", + SONAR_PROJECT_KEY: "myProjectKey", + SONAR_PROJECT_NAME: "Custom Path Project", + SONAR_SOURCES: "src/main", + SONAR_TESTS: "src/test", + SONAR_SCANNER_APP: "python", + SONAR_SCANNER_APP_VERSION: "1.0", + SONAR_SCANNER_BOOTSTRAP_START_TIME: configuration[SONAR_SCANNER_BOOTSTRAP_START_TIME], + SONAR_VERBOSE: False, + SONAR_SCANNER_SKIP_JRE_PROVISIONING: False, + SONAR_PROJECT_BASE_DIR: os.getcwd(), + SONAR_SCANNER_CONNECT_TIMEOUT: 5, + SONAR_SCANNER_SOCKET_TIMEOUT: 60, + SONAR_SCANNER_RESPONSE_TIMEOUT: 0, + SONAR_SCANNER_KEYSTORE_PASSWORD: "changeit", + SONAR_SCANNER_TRUSTSTORE_PASSWORD: "changeit", + SONAR_SCANNER_OS: Os.LINUX.value, + SONAR_SCANNER_ARCH: Arch.X64.value, + TOML_PATH: "custom/path/pyproject.toml", + SONAR_SCANNER_JAVA_HEAP_SIZE: "8000Mb", + } + self.assertDictEqual(configuration, expected_configuration) + @patch( "sys.argv", [ diff --git a/tests/unit/test_pyproject_toml.py b/tests/unit/test_pyproject_toml.py index 6eab4f7a..1b836b2e 100644 --- a/tests/unit/test_pyproject_toml.py +++ b/tests/unit/test_pyproject_toml.py @@ -167,6 +167,25 @@ def test_load_toml_file_from_custom_dir(self): self.assertEqual(properties.sonar_properties.get("sonar.projectKey"), "custom-path-project") self.assertEqual(properties.sonar_properties.get("sonar.projectName"), "Custom Path Project") + def test_load_toml_file_from_direct_file_path(self): + self.fs.create_dir("custom/path") + self.fs.create_file( + "custom/path/pyproject.toml", + contents=""" + [tool.sonar] + projectKey = "direct-file-project" + projectName = "Direct File Project" + """, + ) + properties = TomlConfigurationLoader.load(Path("custom/path/pyproject.toml")) + + self.assertEqual(properties.sonar_properties.get("sonar.projectKey"), "direct-file-project") + self.assertEqual(properties.sonar_properties.get("sonar.projectName"), "Direct File Project") + + def test_load_toml_file_from_direct_file_path_missing(self): + properties = TomlConfigurationLoader.load(Path("nonexistent/pyproject.toml")) + self.assertEqual(len(properties.sonar_properties), 0) + def test_load_toml_file_project_content(self): self.fs.create_file( "pyproject.toml",