Skip to content

Commit

Permalink
fix(expand-extensions): use the Application's project
Browse files Browse the repository at this point in the history
Fixes LP bug https://bugs.launchpad.net/snapcraft/+bug/2083964

Instead of parsing the project again itself, expand-extensions now uses
the project provided by the application. The output is changed slightly,
but I believe it reflects a more accurate expansion.
  • Loading branch information
lengau committed Oct 9, 2024
1 parent 82fa41a commit c64cea8
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 45 deletions.
33 changes: 5 additions & 28 deletions snapcraft/commands/extensions.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
"""Snapcraft extension commands."""

import textwrap
from typing import Dict, List
from typing import Dict, List, cast

import tabulate
from craft_application.commands import AppCommand
Expand All @@ -26,13 +26,6 @@
from pydantic import BaseModel

from snapcraft import extensions, models
from snapcraft.parts.yaml_utils import (
apply_yaml,
extract_parse_info,
get_snap_project,
process_yaml,
)
from snapcraft.utils import get_host_architecture
from snapcraft_legacy.internal.project_loader import (
find_extension,
supported_extension_names,
Expand Down Expand Up @@ -114,25 +107,9 @@ class ExpandExtensionsCommand(AppCommand):
"""
)

always_load_project = True

@overrides
def run(self, parsed_args):
snap_project = get_snap_project()

# load yaml file and trigger legacy behavior if base is core, core18, or core20
yaml_data = process_yaml(snap_project.project_file)

# process yaml before unmarshalling the data
arch = get_host_architecture()
yaml_data_for_arch = apply_yaml(yaml_data, arch, arch)

# `apply_yaml()` adds or replaces the architectures keyword with an Architecture
# object, which does not easily dump to a yaml file
yaml_data_for_arch.pop("architectures", None)
yaml_data_for_arch.pop("platforms", None)

# `parse-info` keywords must be removed before unmarshalling, because they are
# not part of the Project model
extract_parse_info(yaml_data_for_arch)

project_data = models.Project.unmarshal(yaml_data_for_arch)
emit.message(project_data.to_yaml_string())
project = cast(models.Project, self._services.project)
emit.message(project.to_yaml_string())
59 changes: 42 additions & 17 deletions tests/unit/commands/test_expand_extensions.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,14 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.

from argparse import Namespace
from dataclasses import dataclass
from pathlib import Path
from textwrap import dedent

import pytest
from craft_platforms import DebianArchitecture

from snapcraft import commands, const
from snapcraft import application, const


@dataclass
Expand All @@ -45,7 +44,7 @@ def valid_core_data(request) -> CoreData:


@pytest.mark.usefixtures("fake_extension")
def test_expand_extensions_simple_core22(new_dir, emitter):
def test_expand_extensions_simple_core22(new_dir, emitter, mocker):
"""Expand an extension for a simple snapcraft.yaml file."""
with Path("snapcraft.yaml").open("w") as yaml_file:
print(
Expand Down Expand Up @@ -73,8 +72,8 @@ def test_expand_extensions_simple_core22(new_dir, emitter):
file=yaml_file,
)

cmd = commands.ExpandExtensionsCommand(None)
cmd.run(Namespace())
mocker.patch("sys.argv", ["snapcraft", "expand-extensions"])
application.main()
emitter.assert_message(
dedent(
f"""\
Expand Down Expand Up @@ -110,7 +109,7 @@ def test_expand_extensions_simple_core22(new_dir, emitter):


@pytest.mark.usefixtures("fake_extension")
def test_expand_extensions_simple(new_dir, emitter, valid_core_data):
def test_expand_extensions_simple(new_dir, emitter, valid_core_data, mocker):
"""Expand an extension for a simple snapcraft.yaml file."""
with Path("snapcraft.yaml").open("w") as yaml_file:
print(
Expand Down Expand Up @@ -139,8 +138,8 @@ def test_expand_extensions_simple(new_dir, emitter, valid_core_data):
file=yaml_file,
)

cmd = commands.ExpandExtensionsCommand(None)
cmd.run(Namespace())
mocker.patch("sys.argv", ["snapcraft", "expand-extensions"])
application.main()
emitter.assert_message(
dedent(
f"""\
Expand Down Expand Up @@ -216,11 +215,11 @@ def test_expand_extensions_complex_core22(new_dir, emitter, mocker):
file=yaml_file,
)

cmd = commands.ExpandExtensionsCommand(None)
cmd.run(Namespace())
mocker.patch("sys.argv", ["snapcraft", "expand-extensions"])
application.main()
emitter.assert_message(
dedent(
f"""\
"""\
name: test-name
version: '0.1'
summary: testing extensions
Expand All @@ -241,9 +240,17 @@ def test_expand_extensions_complex_core22(new_dir, emitter, mocker):
grade: stable
architectures:
- build-on:
- {DebianArchitecture.from_host()}
- amd64
build-for:
- amd64
- build-on:
- arm64
build-for:
- {DebianArchitecture.from_host()}
- arm64
- build-on:
- armhf
build-for:
- armhf
apps:
app1:
command: app1
Expand Down Expand Up @@ -279,7 +286,10 @@ def test_expand_extensions_complex(new_dir, emitter, mocker, valid_core_data):
build-base: {valid_core_data.build_base}
confinement: strict
grade: {valid_core_data.grade}
platforms: [amd64, arm64, armhf]
platforms:
amd64:
arm64:
armhf:
apps:
app1:
Expand All @@ -301,9 +311,8 @@ def test_expand_extensions_complex(new_dir, emitter, mocker, valid_core_data):
),
file=yaml_file,
)

cmd = commands.ExpandExtensionsCommand(None)
cmd.run(Namespace())
mocker.patch("sys.argv", ["snapcraft", "expand-extensions"])
application.main()
emitter.assert_message(
dedent(
f"""\
Expand All @@ -313,6 +322,22 @@ def test_expand_extensions_complex(new_dir, emitter, mocker, valid_core_data):
description: expand a fake extension
base: {valid_core_data.base}
build-base: {valid_core_data.build_base}
platforms:
amd64:
build-on:
- amd64
build-for:
- amd64
arm64:
build-on:
- arm64
build-for:
- arm64
armhf:
build-on:
- armhf
build-for:
- armhf
parts:
nil:
plugin: nil
Expand Down
6 changes: 6 additions & 0 deletions tests/unit/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,12 @@ def reset_plugins():
plugins.unregister_all()


@pytest.fixture(autouse=True)
def set_debug(monkeypatch):
# Instead of eating exceptions, calls to app.run() will raise them.
monkeypatch.setenv("CRAFT_DEBUG", "1")


@pytest.fixture
def snapcraft_yaml(new_dir):
"""Return a fixture that can write a snapcraft.yaml."""
Expand Down

0 comments on commit c64cea8

Please sign in to comment.