Skip to content

Commit

Permalink
fix: use VersionStr in model and add write test
Browse files Browse the repository at this point in the history
Signed-off-by: Sergio Schvezov <sergio.schvezov@canonical.com>
  • Loading branch information
sergiusens committed Mar 1, 2024
1 parent 383a857 commit 4f09926
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 61 deletions.
6 changes: 2 additions & 4 deletions snapcraft/models/project.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@

import pydantic
from craft_application import models
from craft_application.models import BuildInfo, UniqueStrList
from craft_application.models import BuildInfo, UniqueStrList, VersionStr
from craft_cli import emit
from craft_grammar.models import GrammarSingleEntryDictList, GrammarStr, GrammarStrList
from craft_providers import bases
Expand All @@ -45,10 +45,8 @@
# fmt: off
if TYPE_CHECKING:
ProjectName = str
ProjectVersion = str
else:
ProjectName = constr(max_length=40)
ProjectVersion = constr(max_length=32, strict=True)
# fmt: on


Expand Down Expand Up @@ -444,7 +442,7 @@ class Project(models.Project):
name: ProjectName # type: ignore[assignment]
build_base: Optional[str]
compression: Literal["lzo", "xz"] = "xz"
version: Optional[ProjectVersion] # type: ignore[assignment]
version: Optional[VersionStr] # type: ignore[assignment]
donation: Optional[Union[str, UniqueStrList]]
# snapcraft's `source_code` is more general than craft-application
source_code: Optional[str] # type: ignore[assignment]
Expand Down
2 changes: 1 addition & 1 deletion snapcraft/parts/update_metadata.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ def _update_project_variables(project: Project, project_vars: Dict[str, str]):
"""Update project fields with values set during lifecycle processing."""
try:
if project_vars["version"]:
project.version = project_vars["version"]
project.version = cast(VersionStr, project_vars["version"])
if project_vars["grade"]:
project.grade = project_vars["grade"] # type: ignore
except pydantic.ValidationError as err:
Expand Down
65 changes: 12 additions & 53 deletions tests/unit/models/test_projects.py
Original file line number Diff line number Diff line change
Expand Up @@ -258,59 +258,18 @@ def test_project_version_valid(self, version, project_yaml_data):
project = Project.unmarshal(project_yaml_data(version=version))
assert project.version == version

@pytest.mark.parametrize(
"version,error",
[
(
"1_0",
"Invalid version '1_0': Snap versions consist of",
), # _ is an invalid character
(
"1=1",
"Invalid version '1=1': Snap versions consist of",
), # = is an invalid character
(
".1",
"Invalid version '.1': Snap versions consist of",
), # cannot start with period
(
":1",
"Invalid version ':1': Snap versions consist of",
), # cannot start with colon
(
"+1",
r"Invalid version '\+1': Snap versions consist of",
), # cannot start with plus sign
# escaping + from the regex string to match.
(
"~1",
"Invalid version '~1': Snap versions consist of",
), # cannot start with tilde
(
"-1",
"Invalid version '-1': Snap versions consist of",
), # cannot start with hyphen
(
"1.",
"Invalid version '1.': Snap versions consist of",
), # cannot end with period
(
"1:",
"Invalid version '1:': Snap versions consist of",
), # cannot end with colon
(
"1-",
"Invalid version '1-': Snap versions consist of",
), # cannot end with hyphen
(
"123456789012345678901234567890123",
"ensure this value has at most 32 characters",
), # too large
],
)
def test_project_version_invalid(self, version, error, project_yaml_data):
with pytest.raises(errors.ProjectValidationError, match=error):
Project.unmarshal(project_yaml_data(version=version))
def test_project_version_invalid(self, project_yaml_data):
# We only test one invalid version as this model is inherited
# from Craft Application.
with pytest.raises(errors.ProjectValidationError) as raised:

Project.unmarshal(project_yaml_data(version="1=1"))

assert str(raised.value) == (
"Bad snapcraft.yaml content:\n- string does not match regex "
'"^[a-zA-Z0-9](?:[a-zA-Z0-9:.+~-]*[a-zA-Z0-9+~])?$" '
"(in field 'version')"
)

@pytest.mark.parametrize(
"snap_type",
Expand Down
43 changes: 40 additions & 3 deletions tests/unit/services/test_package.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,17 @@
"""Tests for the Snapcraft Package service."""

from pathlib import Path
from textwrap import dedent

from craft_application.models import SummaryStr
import pytest
from craft_application.models import SummaryStr, VersionStr

from snapcraft import linters, meta, pack, services
from snapcraft.application import APP_METADATA


def test_pack(package_service, default_factory, mocker):
@pytest.mark.usefixtures("default_factory")
def test_pack(package_service, mocker):
mock_pack_snap = mocker.patch.object(pack, "pack_snap")
mocker.patch.object(linters, "run_linters")
mocker.patch.object(linters, "report")
Expand Down Expand Up @@ -72,7 +75,7 @@ def test_metadata(package_service, default_factory, default_build_plan, new_dir)
assert package_service.metadata == meta.SnapMetadata(
name="default",
title=None,
version="1.0",
version=VersionStr("1.0"),
summary=SummaryStr("default project"),
description="default project",
license="MIT",
Expand All @@ -96,3 +99,37 @@ def test_metadata(package_service, default_factory, default_build_plan, new_dir)
provenance=None,
links=None,
)


def test_write_metadata(
package_service,
default_factory,
default_build_plan,
new_dir,
):
default_factory.set_kwargs(
"lifecycle",
work_dir=Path("work"),
cache_dir=new_dir,
build_plan=default_build_plan,
)

package_service.write_metadata(new_dir)

assert (new_dir / "meta" / "snap.yaml").read_text() == dedent(
"""\
name: default
version: '1.0'
summary: default project
description: default project
license: MIT
architectures:
- amd64
base: core24
confinement: devmode
grade: devel
environment:
LD_LIBRARY_PATH: ${SNAP_LIBRARY_PATH}${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}
PATH: $SNAP/usr/sbin:$SNAP/usr/bin:$SNAP/sbin:$SNAP/bin:$PATH
"""
)

0 comments on commit 4f09926

Please sign in to comment.