diff --git a/src/poetry/console/commands/init.py b/src/poetry/console/commands/init.py index 18d7c4356da..c54b224f9ee 100644 --- a/src/poetry/console/commands/init.py +++ b/src/poetry/console/commands/init.py @@ -16,6 +16,7 @@ from poetry.console.commands.command import Command from poetry.console.commands.env_command import EnvCommand +from poetry.factory import Factory from poetry.utils.dependency_specification import RequirementsParser from poetry.utils.env.python import Python @@ -268,6 +269,16 @@ def _init_pyproject( return 1 + # Validate fields before creating pyproject.toml file. If any validations fail, throw an error. + validation_results = Factory().validate(pyproject.data) + if validation_results.get("errors"): + message = "" + for error in validation_results.get("errors", []): + message += f" - {error}\n" + + self.line_error(f"Validation failed: \n{message}") + return 1 + pyproject.save() if create_layout: diff --git a/tests/console/commands/test_init.py b/tests/console/commands/test_init.py index 98222c385ac..fdf6145eece 100644 --- a/tests/console/commands/test_init.py +++ b/tests/console/commands/test_init.py @@ -1207,3 +1207,32 @@ def test_init_does_not_create_project_structure_in_non_empty_directory( # Existing files should remain assert (source_dir / "existing_file.txt").exists() assert (source_dir / "existing_dir").exists() + + +def test_noninteractive_validation_shows_error( + app: PoetryTestApplication, mocker: MockerFixture +) -> None: + command = app.find("init") + assert isinstance(command, InitCommand) + + expected_error = r"Validation failed: \n - project.name must match pattern ^([a-zA-Z\d]|[a-zA-Z\d][\w.-]*[a-zA-Z\d])$" + + # Set Factory.validate to return a mocked error message + # We mock Factory.validate() because this test focuses on _init_pyproject(), not on the validation logic itself. + mocked_validate = mocker.patch( + "poetry.console.commands.init.Factory.validate", + return_value={"errors": [expected_error]}, + ) + + init_tester = CommandTester(command) + args = '--name "new project"' + result = init_tester.execute(args=args, interactive=False) + + # Check that the command fails + assert result == 1 + + error_output = init_tester.io.fetch_error() + assert expected_error in error_output + + # Verify that validate() was called + mocked_validate.assert_called_once()