From df9fc5418c1b8a8e6d76c34c076b923e742ea315 Mon Sep 17 00:00:00 2001 From: Giancarlo Cicellyn Comneno Date: Mon, 27 Apr 2026 16:51:34 +0200 Subject: [PATCH] fix(init): allow long directory names --- snapcraft/services/init.py | 27 +++++++++++++++++---------- tests/unit/commands/test_init.py | 18 ++++++++++++++++++ tests/unit/services/test_init.py | 17 ++++++++++------- 3 files changed, 45 insertions(+), 17 deletions(-) diff --git a/snapcraft/services/init.py b/snapcraft/services/init.py index 501c5e75f3..57ead245ce 100644 --- a/snapcraft/services/init.py +++ b/snapcraft/services/init.py @@ -32,23 +32,30 @@ class Init(services.InitService): """Service class for initializing a project.""" @override - def initialise_project( - self, - *, - project_dir: pathlib.Path, - project_name: str, - template_dir: pathlib.Path, - ) -> None: + def validate_project_name(self, name: str, *, use_default: bool = False) -> str: + """Validate that ``name`` is valid as a snap name.""" try: - validate_name(name=project_name, field_name="snap") - if len(project_name) > 40: + validate_name(name=name, field_name="snap") + if len(name) > 40: raise ValueError("snap names must be 40 characters or less") except ValueError as err: + if use_default: + return self._default_name raise errors.SnapcraftError( - message=f"Invalid snap name {project_name!r}: {str(err)}.", + message=f"Invalid snap name {name!r}: {str(err)}.", resolution="Provide a valid name with '--name' or rename the project directory.", ) from err + return name + + @override + def initialise_project( + self, + *, + project_dir: pathlib.Path, + project_name: str, + template_dir: pathlib.Path, + ) -> None: super().initialise_project( project_dir=project_dir, project_name=project_name, diff --git a/tests/unit/commands/test_init.py b/tests/unit/commands/test_init.py index eceebdacaf..78c7a834f7 100644 --- a/tests/unit/commands/test_init.py +++ b/tests/unit/commands/test_init.py @@ -102,6 +102,24 @@ def test_init_default(profile, name, project_dir, emitter, valid_new_dir, mocker emitter.assert_message("Successfully initialised project.") +def test_init_default_long_directory_name(emitter, tmp_path, monkeypatch, mocker): + """Use the default project name when the directory name is too long.""" + new_dir = tmp_path / "this-working-directory-has-a-very-long-name" + new_dir.mkdir() + monkeypatch.chdir(new_dir) + snapcraft_yaml = new_dir / "snap/snapcraft.yaml" + mocker.patch.object(sys, "argv", _create_command()) + + app = application.create_app() + app.run() + + assert snapcraft_yaml.exists() + data = apply_yaml(process_yaml(snapcraft_yaml), "amd64", "amd64") + project = Project.unmarshal(data) + assert project.name == "my-project" + emitter.assert_message("Successfully initialised project.") + + @pytest.mark.parametrize("yaml_content", ["", "just a string"]) def test_init_existing_yaml_invalid(yaml_content, emitter, valid_new_dir, mocker): """Test the 'snapcraft init' command with existing empty/invalid snapcraft.yaml.""" diff --git a/tests/unit/services/test_init.py b/tests/unit/services/test_init.py index d550e80263..021204bb12 100644 --- a/tests/unit/services/test_init.py +++ b/tests/unit/services/test_init.py @@ -82,16 +82,19 @@ def test_init_valid_name(name, init_service, new_dir, emitter): ), ], ) -def test_init_invalid_name(name, error, init_service, new_dir): - """Error on invalid names.""" +def test_validate_project_name_invalid_name(name, error, init_service): + """Error on invalid snap names.""" expected_error = f"Invalid snap name {name!r}: {error}." with pytest.raises(errors.SnapcraftError, match=expected_error): - init_service.initialise_project( - project_dir=new_dir, - project_name=name, - template_dir=template_dir(), - ) + init_service.validate_project_name(name) + + +def test_validate_project_name_uses_default_for_long_directory_name(init_service): + """Use the default name when the project directory name is too long.""" + name = "a2345678901234567890123456789012345678901" + + assert init_service.validate_project_name(name, use_default=True) == "my-project" def test_init_snap_dir_exists(init_service, new_dir, emitter):