From 7ce4182ed52a5d44643f0b87f51230b84d603f38 Mon Sep 17 00:00:00 2001 From: Alex Lowe Date: Wed, 3 Apr 2024 17:31:14 -0400 Subject: [PATCH] fix: reorganise charmcraft.yaml preprocessing (#1622) This makes a few related changes: 1. Extensions are applied on the rawest charmcraft.yaml data we have 2. Charms with a "bases" key (not just bundles) get a default part. 3. Always expect a dictionary for parts. --- charmcraft/application/main.py | 7 +++---- charmcraft/preprocess.py | 13 ++++++++----- tests/unit/models/test_project.py | 15 ++++++++++----- .../models/valid_charms_yaml/basic-bases.yaml | 2 ++ tests/unit/test_preprocess.py | 4 ++++ 5 files changed, 27 insertions(+), 14 deletions(-) diff --git a/charmcraft/application/main.py b/charmcraft/application/main.py index cd59750fb..bb814d4a1 100644 --- a/charmcraft/application/main.py +++ b/charmcraft/application/main.py @@ -65,15 +65,14 @@ def _project_vars(self, yaml_data: dict[str, Any]) -> dict[str, str]: def _extra_yaml_transform( self, yaml_data: dict[str, Any], *, build_on: str, build_for: str | None ) -> dict[str, Any]: - yaml_data = yaml_data.copy() + # Extensions get applied on as close as possible to what the user provided. + yaml_data = extensions.apply_extensions(self.project_dir, yaml_data.copy()) + # Preprocessing "magic" to create a fully-formed charm. preprocess.add_default_parts(yaml_data) preprocess.add_bundle_snippet(self.project_dir, yaml_data) preprocess.add_config(self.project_dir, yaml_data) preprocess.add_actions(self.project_dir, yaml_data) - - yaml_data = extensions.apply_extensions(self.project_dir, yaml_data) - preprocess.add_metadata(self.project_dir, yaml_data) return yaml_data diff --git a/charmcraft/preprocess.py b/charmcraft/preprocess.py index 08295335c..0eae25022 100644 --- a/charmcraft/preprocess.py +++ b/charmcraft/preprocess.py @@ -32,13 +32,16 @@ def add_default_parts(yaml_data: dict[str, Any]) -> None: :param yaml_data: The raw YAML dictionary of the project. :returns: The same dictionary passed in, with necessary mutations. """ - if (yaml_data.get("type")) != "bundle": - return - parts = yaml_data.setdefault("parts", {}) - if parts: # Only operate if there aren't any parts declared. + if "parts" in yaml_data: # Only operate if there isn't a parts key return - parts["bundle"] = {"plugin": "bundle", "source": "."} + if yaml_data.get("type") == "bundle": + yaml_data["parts"] = {"bundle": {"plugin": "bundle", "source": "."}} + elif yaml_data.get("type") == "charm": + # Only for backwards compatibility for bases charms. + # Platforms charms expect parts to be explicit. + if "bases" in yaml_data: + yaml_data["parts"] = {"charm": {"plugin": "charm", "source": "."}} def add_metadata(project_dir: pathlib.Path, yaml_data: dict[str, Any]) -> None: diff --git a/tests/unit/models/test_project.py b/tests/unit/models/test_project.py index ac18bbab5..08a5873a8 100644 --- a/tests/unit/models/test_project.py +++ b/tests/unit/models/test_project.py @@ -55,6 +55,7 @@ "build-on": [{"channel": "22.04", "name": "ubuntu"}], "run-on": [{"channel": "22.04", "name": "ubuntu"}], } +BASIC_CHARM_PARTS = {"charm": {"plugin": "charm", "source": "."}} MINIMAL_CHARMCRAFT_YAML = """\ type: charm @@ -477,35 +478,39 @@ def test_unmarshal_invalid_type(type_): None, None, None, - {}, + {"parts": BASIC_CHARM_PARTS}, ), ( MINIMAL_CHARMCRAFT_YAML, SIMPLE_METADATA_YAML, None, None, - {}, + {"parts": BASIC_CHARM_PARTS}, ), ( SIMPLE_CHARMCRAFT_YAML, None, SIMPLE_CONFIG_YAML, None, - {"config": SIMPLE_CONFIG_DICT}, + {"config": SIMPLE_CONFIG_DICT, "parts": BASIC_CHARM_PARTS}, ), ( SIMPLE_CHARMCRAFT_YAML, None, None, SIMPLE_ACTIONS_YAML, - {"actions": SIMPLE_ACTIONS_DICT}, + {"actions": SIMPLE_ACTIONS_DICT, "parts": BASIC_CHARM_PARTS}, ), ( MINIMAL_CHARMCRAFT_YAML, SIMPLE_METADATA_YAML, SIMPLE_CONFIG_YAML, SIMPLE_ACTIONS_YAML, - {"actions": SIMPLE_ACTIONS_DICT, "config": SIMPLE_CONFIG_DICT}, + { + "actions": SIMPLE_ACTIONS_DICT, + "config": SIMPLE_CONFIG_DICT, + "parts": BASIC_CHARM_PARTS, + }, ), ], ) diff --git a/tests/unit/models/valid_charms_yaml/basic-bases.yaml b/tests/unit/models/valid_charms_yaml/basic-bases.yaml index dfa995840..225fef360 100644 --- a/tests/unit/models/valid_charms_yaml/basic-bases.yaml +++ b/tests/unit/models/valid_charms_yaml/basic-bases.yaml @@ -11,3 +11,5 @@ bases: run-on: - name: ubuntu channel: '22.04' + +parts: {} diff --git a/tests/unit/test_preprocess.py b/tests/unit/test_preprocess.py index c7fb429fd..bd7c49f42 100644 --- a/tests/unit/test_preprocess.py +++ b/tests/unit/test_preprocess.py @@ -22,6 +22,8 @@ from charmcraft import const, errors, preprocess BASIC_BUNDLE = {"type": "bundle", "parts": {"bundle": {"plugin": "bundle", "source": "."}}} +BASIC_CHARM = {"type": "charm", "parts": {"charm": {"plugin": "charm", "source": "."}}} +BASIC_BASES_CHARM = {**BASIC_CHARM, "bases": [{"name": "ubuntu", "channel": "22.04"}]} @pytest.mark.parametrize( @@ -30,6 +32,8 @@ pytest.param({}, {}, id="no-type"), pytest.param({"type": "bundle"}, BASIC_BUNDLE, id="empty-bundle"), pytest.param(BASIC_BUNDLE.copy(), BASIC_BUNDLE, id="prefilled-bundle"), + pytest.param({"type": "charm"}, {"type": "charm"}, id="empty-charm"), + pytest.param(BASIC_CHARM.copy(), BASIC_CHARM, id="empty-charm"), ], ) def test_add_default_parts_correct(yaml_data, expected):