Skip to content

Commit

Permalink
Merge pull request #93 from canonical/fix-metadata-autoload
Browse files Browse the repository at this point in the history
loosened metadata checks
  • Loading branch information
PietroPasotti authored Jan 9, 2024
2 parents de4a1d0 + 7a2a83f commit 22d48dc
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 14 deletions.
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ build-backend = "setuptools.build_meta"
[project]
name = "ops-scenario"

version = "5.8"
version = "5.8.1"

authors = [
{ name = "Pietro Pasotti", email = "[email protected]" }
Expand Down
19 changes: 15 additions & 4 deletions scenario/state.py
Original file line number Diff line number Diff line change
Expand Up @@ -942,6 +942,20 @@ def jsonpatch_delta(self, other: "State"):
return sort_patch(patch)


def _is_valid_charmcraft_25_metadata(meta: Dict[str, Any]):
# Check whether this dict has the expected mandatory metadata fields according to the
# charmcraft >2.5 charmcraft.yaml schema
if (config_type := meta.get("type")) != "charm":
logger.debug(
f"Not a charm: charmcraft yaml config ``.type`` is {config_type!r}.",
)
return False
if not all(field in meta for field in {"name", "summary", "description"}):
logger.debug("Not a charm: charmcraft yaml misses some required fields")
return False
return True


@dataclasses.dataclass(frozen=True)
class _CharmSpec(_DCBase):
"""Charm spec."""
Expand Down Expand Up @@ -976,10 +990,7 @@ def _load_metadata(charm_root: Path):
"""Load metadata from charm projects created with Charmcraft >= 2.5."""
metadata_path = charm_root / "charmcraft.yaml"
meta = yaml.safe_load(metadata_path.open()) if metadata_path.exists() else {}
if (config_type := meta.get("type")) != "charm":
logger.debug(
f"Not a charm: charmcraft yaml config ``.type`` is {config_type!r}.",
)
if not _is_valid_charmcraft_25_metadata(meta):
meta = {}
config = meta.pop("config", None)
actions = meta.pop("actions", None)
Expand Down
27 changes: 18 additions & 9 deletions tests/test_charm_spec_autoload.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

from scenario import Context, Relation, State
from scenario.context import ContextSetupError
from scenario.state import _CharmSpec, MetadataNotFoundError
from scenario.state import MetadataNotFoundError, _CharmSpec

CHARM = """
from ops import CharmBase
Expand Down Expand Up @@ -46,13 +46,13 @@ def create_tempcharm(
charmpy = src / "charm.py"
charmpy.write_text(charm)

if legacy:
# we add a charmcraft.yaml file to verify that _CharmSpec._load_metadata
# is able to tell that the presence of charmcraft.yaml ALONE is not enough
# to make this a valid charm
charmcraft = {"builds-on": "literally anywhere! isn't that awesome?"}
(root / "charmcraft.yaml").write_text(yaml.safe_dump(charmcraft))
# we add a charmcraft.yaml file to verify that _CharmSpec._load_metadata
# is able to tell that the presence of charmcraft.yaml ALONE is not enough
# to make this a valid charm
charmcraft = {"builds-on": "literally anywhere! isn't that awesome?"}
(root / "charmcraft.yaml").write_text(yaml.safe_dump(charmcraft))

if legacy:
if meta is not None:
(root / "metadata.yaml").write_text(yaml.safe_dump(meta))

Expand Down Expand Up @@ -109,7 +109,9 @@ def test_autoload_legacy_type_passes(tmp_path, config_type):
@pytest.mark.parametrize("legacy", (True, False))
def test_meta_autoload(tmp_path, legacy):
with create_tempcharm(
tmp_path, legacy=legacy, meta={"type": "charm", "name": "foo"}
tmp_path,
legacy=legacy,
meta={"type": "charm", "name": "foo", "summary": "foo", "description": "foo"},
) as charm:
ctx = Context(charm)
ctx.run("start", State())
Expand All @@ -133,6 +135,8 @@ def test_relations_ok(tmp_path, legacy):
legacy=legacy,
meta={
"type": "charm",
"summary": "foo",
"description": "foo",
"name": "josh",
"requires": {"cuddles": {"interface": "arms"}},
},
Expand All @@ -146,7 +150,12 @@ def test_config_defaults(tmp_path, legacy):
with create_tempcharm(
tmp_path,
legacy=legacy,
meta={"type": "charm", "name": "josh"},
meta={
"type": "charm",
"name": "josh",
"summary": "foo",
"description": "foo",
},
config={"options": {"foo": {"type": "bool", "default": True}}},
) as charm:
# this would fail if there were no 'cuddles' relation defined in meta
Expand Down

0 comments on commit 22d48dc

Please sign in to comment.