Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CLI_ARGS.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 |
Expand Down
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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:

```
Expand Down
2 changes: 1 addition & 1 deletion src/pysonar_scanner/configuration/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
4 changes: 2 additions & 2 deletions src/pysonar_scanner/configuration/configuration_loader.py
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down
7 changes: 5 additions & 2 deletions src/pysonar_scanner/configuration/pyproject_toml.py
Original file line number Diff line number Diff line change
Expand Up @@ -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({}, {})
Expand Down
52 changes: 52 additions & 0 deletions tests/unit/test_configuration_loader.py
Original file line number Diff line number Diff line change
Expand Up @@ -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",
[
Expand Down
19 changes: 19 additions & 0 deletions tests/unit/test_pyproject_toml.py
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
Loading