Skip to content

Commit

Permalink
meta: write out metadata links
Browse files Browse the repository at this point in the history
Signed-off-by: Sergio Schvezov <[email protected]>
  • Loading branch information
sergiusens committed Jul 13, 2023
1 parent cfacbc5 commit 3d5123a
Show file tree
Hide file tree
Showing 3 changed files with 194 additions and 2 deletions.
31 changes: 30 additions & 1 deletion snapcraft/meta/snap_yaml.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
from pydantic_yaml import YamlModel

from snapcraft import errors
from snapcraft.projects import App, Project
from snapcraft.projects import App, Project, UniqueStrList
from snapcraft.utils import get_ld_library_paths, process_version


Expand Down Expand Up @@ -176,6 +176,31 @@ def get_content_dirs(self, installed_path: Path) -> Set[Path]:
return content_dirs


class Links(_SnapMetadataModel):
"""Metadata links used in snaps."""

contact: Optional[Union[str, UniqueStrList]]
donation: Optional[Union[str, UniqueStrList]]
issues: Optional[Union[str, UniqueStrList]]
source_code: Optional[str]
website: Optional[str]

@classmethod
def from_project(cls, project: Project) -> "Links":
return cls(
contact=project.contact,
donation=project.donation,
issues=project.issues,
source_code=project.source_code,
website=project.website,
)

def __bool__(self) -> bool:
return any(
[self.contact, self.donation, self.issues, self.source_code, self.website]
)


class SnapMetadata(_SnapMetadataModel):
"""The snap.yaml model.
Expand Down Expand Up @@ -210,6 +235,7 @@ class Config:
layout: Optional[Dict[str, Dict[str, str]]]
system_usernames: Optional[Dict[str, Any]]
provenance: Optional[str]
links: Optional[Links]

@classmethod
def unmarshal(cls, data: Dict[str, Any]) -> "SnapMetadata":
Expand Down Expand Up @@ -403,6 +429,8 @@ def write(project: Project, prime_dir: Path, *, arch: str):
# project provided assumes and computed assumes
total_assumes = sorted(project.assumes + list(assumes))

links = Links.from_project(project)

snap_metadata = SnapMetadata(
name=project.name,
title=project.title,
Expand All @@ -425,6 +453,7 @@ def write(project: Project, prime_dir: Path, *, arch: str):
layout=project.layout,
system_usernames=project.system_usernames,
provenance=project.provenance,
links=links if links else None,
)
if project.passthrough:
for name, value in project.passthrough.items():
Expand Down
10 changes: 9 additions & 1 deletion tests/spread/general/metadata-links/task.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,21 @@ environment:
prepare: |
snap install yq
#shellcheck source=tests/spread/tools/snapcraft-yaml.sh
. "$TOOLS_DIR/snapcraft-yaml.sh"
set_base snapcraft.yaml
restore: |
snapcraft clean
rm -rf ./*.snap
#shellcheck source=tests/spread/tools/snapcraft-yaml.sh
. "$TOOLS_DIR/snapcraft-yaml.sh"
restore_yaml snapcraft.yaml
execute: |
# Create a snap to trigger `snap pack`.
snapcraft
snapcraft pack
# Links exists
# SC2002: cat is useful for confined applications!
Expand Down
155 changes: 155 additions & 0 deletions tests/unit/meta/test_snap_yaml.py
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,104 @@ def test_assumes(simple_project, new_dir):
)


def test_links_scalars(simple_project, new_dir):
snap_yaml.write(
simple_project(
contact="[email protected]",
issues="https://hubhub.com/issues",
donation="https://moneyfornothing.com",
source_code="https://closed.acme.com",
website="https://acme.com",
),
prime_dir=Path(new_dir),
arch="amd64",
)
yaml_file = Path("meta/snap.yaml")
assert yaml_file.is_file()

content = yaml_file.read_text()
assert content == textwrap.dedent(
"""\
name: mytest
version: 1.29.3
summary: Single-line elevator pitch for your amazing snap
description: test-description
architectures:
- amd64
base: core22
apps:
app1:
command: bin/mytest
confinement: strict
grade: stable
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
links:
contact: [email protected]
donation: https://moneyfornothing.com
issues: https://hubhub.com/issues
source-code: https://closed.acme.com
website: https://acme.com
"""
)


def test_links_lists(simple_project, new_dir):
snap_yaml.write(
simple_project(
contact=[
"[email protected]",
"[email protected]",
],
issues=[
"https://hubhub.com/issues",
"https://corner.com/issues",
],
donation=["https://moneyfornothing.com", "https://prince.com"],
source_code="https://closed.acme.com",
website="https://acme.com",
),
prime_dir=Path(new_dir),
arch="amd64",
)
yaml_file = Path("meta/snap.yaml")
assert yaml_file.is_file()

content = yaml_file.read_text()
assert content == textwrap.dedent(
"""\
name: mytest
version: 1.29.3
summary: Single-line elevator pitch for your amazing snap
description: test-description
architectures:
- amd64
base: core22
apps:
app1:
command: bin/mytest
confinement: strict
grade: stable
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
links:
contact:
- [email protected]
- [email protected]
donation:
- https://moneyfornothing.com
- https://prince.com
issues:
- https://hubhub.com/issues
- https://corner.com/issues
source-code: https://closed.acme.com
website: https://acme.com
"""
)


@pytest.fixture
def complex_project():
snapcraft_yaml = textwrap.dedent(
Expand Down Expand Up @@ -1025,3 +1123,60 @@ def test_architectures_all(simple_project, new_dir):
"${SNAP_LIBRARY_PATH}${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}:"
"$SNAP/lib:$SNAP/usr/lib\n"
) in content


##############
# Test Links #
##############


def test_links_for_scalars(simple_project):
project = simple_project(
contact="[email protected]",
issues="https://hubhub.com/issues",
donation="https://moneyfornothing.com",
source_code="https://closed.acme.com",
website="https://acme.com",
)

links = snap_yaml.Links.from_project(project)

assert links.contact == project.contact
assert links.issues == links.issues
assert links.donation == links.donation
assert links.source_code == links.source_code
assert links.website == links.website

assert bool(links) is True


def test_links_for_lists(simple_project):
project = simple_project(
contact=[
"[email protected]",
"[email protected]",
],
issues=[
"https://hubhub.com/issues",
"https://corner.com/issues",
],
donation=["https://moneyfornothing.com", "https://prince.com"],
)

links = snap_yaml.Links.from_project(project)

assert links.contact == project.contact
assert links.issues == links.issues
assert links.donation == links.donation
assert links.source_code is None
assert links.website is None

assert bool(links) is True


def test_no_links(simple_project):
project = simple_project()

links = snap_yaml.Links.from_project(project)

assert bool(links) is False

0 comments on commit 3d5123a

Please sign in to comment.