Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: use init command from craft-application #5129

Merged
merged 8 commits into from
Nov 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions MANIFEST.in
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
include schema/*
include extensions/*
recursive-include snapcraft/templates *
6 changes: 3 additions & 3 deletions requirements-devel.txt
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ click==8.1.7
codespell==2.3.0
colorama==0.4.6
coverage==7.6.1
craft-application==4.2.7
craft-application==4.4.0
craft-archives==2.0.1
craft-cli==2.7.0
craft-cli==2.10.0
craft-grammar==2.0.1
craft-parts==2.1.2
craft-platforms==0.4.0
Expand Down Expand Up @@ -89,7 +89,7 @@ pbr==6.0.0
pexpect==4.9.0
plaster==1.1.2
plaster-pastedeploy==1.0.1
platformdirs==4.2.2
platformdirs==4.3.6
pluggy==1.5.0
polib==1.2.0
progressbar==2.5
Expand Down
6 changes: 3 additions & 3 deletions requirements-docs.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ chardet==5.2.0
charset-normalizer==3.3.2
click==8.1.7
colorama==0.4.6
craft-application==4.2.7
craft-application==4.4.0
craft-archives==2.0.1
craft-cli==2.7.0
craft-cli==2.10.0
craft-grammar==2.0.1
craft-parts==2.1.2
craft-platforms==0.4.0
Expand Down Expand Up @@ -69,7 +69,7 @@ natsort==8.4.0
oauthlib==3.2.2
overrides==7.7.0
packaging==24.1
platformdirs==4.2.2
platformdirs==4.3.6
polib==1.2.0
progressbar==2.5
protobuf==5.27.3
Expand Down
6 changes: 3 additions & 3 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ cffi==1.17.1
chardet==5.2.0
charset-normalizer==3.3.2
click==8.1.7
craft-application==4.2.7
craft-application==4.4.0
craft-archives==2.0.1
craft-cli==2.7.0
craft-cli==2.10.0
craft-grammar==2.0.1
craft-parts==2.1.2
craft-platforms==0.4.0
Expand Down Expand Up @@ -37,7 +37,7 @@ mypy-extensions==1.0.0
oauthlib==3.2.2
overrides==7.7.0
packaging==24.1
platformdirs==4.2.2
platformdirs==4.3.6
progressbar==2.5
protobuf==5.27.3
psutil==6.0.0
Expand Down
8 changes: 6 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,9 +98,9 @@ def recursive_data_files(directory, install_directory):
"attrs",
"catkin-pkg; sys_platform == 'linux'",
"click",
"craft-application>=4.2.7,<5.0.0",
"craft-application~=4.4",
"craft-archives~=2.0",
"craft-cli~=2.6",
"craft-cli~=2.9",
"craft-grammar>=2.0.1,<3.0.0",
"craft-parts>=2.1.2,<3.0.0",
"craft-platforms~=0.4",
Expand Down Expand Up @@ -174,6 +174,10 @@ def recursive_data_files(directory, install_directory):
+ recursive_data_files("keyrings", "share/snapcraft")
+ recursive_data_files("extensions", "share/snapcraft")
),
include_package_data=True,
package_data={
"snapcraft": ["templates/*"],
},
python_requires=">=3.10",
install_requires=install_requires,
extras_require=extras_requires,
Expand Down
12 changes: 1 addition & 11 deletions snapcraft/application.py
Original file line number Diff line number Diff line change
Expand Up @@ -150,16 +150,6 @@ def _configure_services(self, provider_name: str | None) -> None:

super()._configure_services(provider_name)

@property
def command_groups(self):
"""Replace craft-application's LifecycleCommand group."""
_command_groups = super().command_groups
for index, command_group in enumerate(_command_groups):
if command_group.name == "Lifecycle":
_command_groups[index] = cli.CORE24_LIFECYCLE_COMMAND_GROUP

return _command_groups
mr-cal marked this conversation as resolved.
Show resolved Hide resolved

@override
def _resolve_project_path(self, project_dir: pathlib.Path | None) -> pathlib.Path:
"""Overridden to handle the two possible locations for snapcraft.yaml."""
Expand Down Expand Up @@ -467,7 +457,7 @@ def create_app() -> Snapcraft:
services=snapcraft_services,
)

for group in cli.COMMAND_GROUPS:
for group in [cli.CORE24_LIFECYCLE_COMMAND_GROUP, *cli.COMMAND_GROUPS]:
app.add_command_group(group.name, group.commands)

return app
Expand Down
1 change: 0 additions & 1 deletion snapcraft/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,6 @@
"Other",
[
commands.LintCommand,
commands.InitCommand,
],
),
]
Expand Down
2 changes: 0 additions & 2 deletions snapcraft/commands/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@
ExtensionsCommand,
ListExtensionsCommand,
)
from .init import InitCommand
from .legacy import (
StoreLegacyCreateKeyCommand,
StoreLegacyGatedCommand,
Expand Down Expand Up @@ -67,7 +66,6 @@
__all__ = [
"ExpandExtensionsCommand",
"ExtensionsCommand",
"InitCommand",
"LintCommand",
"ListExtensionsCommand",
"ListPluginsCommand",
Expand Down
89 changes: 0 additions & 89 deletions snapcraft/commands/init.py

This file was deleted.

2 changes: 1 addition & 1 deletion snapcraft/extensions/env_injector.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ def get_parts_snippet(self) -> Dict[str, Any]:

cargo build --target {toolchain} --release
mkdir -p $SNAPCRAFT_PART_INSTALL/bin/command-chain

cp target/{toolchain}/release/env-exporter $SNAPCRAFT_PART_INSTALL/bin/command-chain
""",
}
Expand Down
6 changes: 3 additions & 3 deletions snapcraft/models/project.py
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ def _validate_version_name(version: str, model_name: str) -> None:
)


def _validate_name(*, name: str, field_name: str) -> str:
def validate_name(*, name: str, field_name: str) -> str:
"""Validate a name.

:param name: The name to validate.
Expand Down Expand Up @@ -261,7 +261,7 @@ def _validate_component(name: str) -> str:
raise ValueError(
"component names cannot start with the reserved prefix 'snap-'"
)
return _validate_name(name=name, field_name="component")
return validate_name(name=name, field_name="component")


def _get_partitions_from_components(
Expand Down Expand Up @@ -729,7 +729,7 @@ def _validate_mandatory_base(self):
@pydantic.field_validator("name")
@classmethod
def _validate_snap_name(cls, name):
return _validate_name(name=name, field_name="snap")
return validate_name(name=name, field_name="snap")

@pydantic.field_validator("components")
@classmethod
Expand Down
12 changes: 10 additions & 2 deletions snapcraft/parts/yaml_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -218,13 +218,21 @@ def apply_yaml(
return yaml_data


def get_snap_project() -> _SnapProject:
def get_snap_project(project_dir: Path | None = None) -> _SnapProject:
"""Find the snapcraft.yaml to load.

:param project_dir: The directory to search for the project yaml file. If not
provided, the current working directory is used.

:raises SnapcraftError: if the project yaml file cannot be found.
"""
for snap_project in _SNAP_PROJECT_FILES:
if snap_project.project_file.exists():
if project_dir:
snap_project_path = project_dir / snap_project.project_file
else:
snap_project_path = snap_project.project_file

if snap_project_path.exists():
return snap_project

raise errors.ProjectMissing()
Expand Down
2 changes: 2 additions & 0 deletions snapcraft/services/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
"""Snapcraft services."""

from snapcraft.services.assertions import Assertion
from snapcraft.services.init import Init
from snapcraft.services.lifecycle import Lifecycle
from snapcraft.services.package import Package
from snapcraft.services.provider import Provider
Expand All @@ -26,6 +27,7 @@

__all__ = [
"Assertion",
"Init",
"Lifecycle",
"Package",
"Provider",
Expand Down
83 changes: 83 additions & 0 deletions snapcraft/services/init.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
# -*- Mode:Python; indent-tabs-mode:nil; tab-width:4 -*-
#
# Copyright 2024 Canonical Ltd.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 3 as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.

"""Service for initializing a project."""

import pathlib

import craft_cli
from craft_application import services
from typing_extensions import override

from snapcraft import errors
from snapcraft.models.project import validate_name
from snapcraft.parts.yaml_utils import get_snap_project


class Init(services.InitService):
"""Service class for initializing a project."""

@override
def initialise_project(
self,
*,
project_dir: pathlib.Path,
project_name: str,
template_dir: pathlib.Path,
) -> None:
try:
validate_name(name=project_name, field_name="snap")
if len(project_name) > 40:
raise ValueError("snap names must be 40 characters or less")
except ValueError as err:
raise errors.SnapcraftError(
message=f"Invalid snap name {project_name!r}: {str(err)}.",
resolution="Provide a valid name with '--name' or rename the project directory.",
) from err

super().initialise_project(
project_dir=project_dir,
project_name=project_name,
template_dir=template_dir,
)
craft_cli.emit.message(
mr-cal marked this conversation as resolved.
Show resolved Hide resolved
"Go to https://docs.snapcraft.io/the-snapcraft-format/8337 for more "
"information about the snapcraft.yaml format."
)

@override
def check_for_existing_files(
self,
*,
project_dir: pathlib.Path,
template_dir: pathlib.Path,
) -> None:
try:
craft_cli.emit.progress("Checking for an existing 'snapcraft.yaml'.")
project = get_snap_project(project_dir)
# the `ProjectMissing` error means a new project can be initialised
except errors.ProjectMissing:
craft_cli.emit.debug("Could not find an existing 'snapcraft.yaml'.")
else:
raise errors.SnapcraftError(
"Could not initialise a new snapcraft project because "
f"{str(project.project_file)!r} already exists"
)
mr-cal marked this conversation as resolved.
Show resolved Hide resolved

super().check_for_existing_files(
project_dir=project_dir,
template_dir=template_dir,
)
3 changes: 3 additions & 0 deletions snapcraft/services/service_factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ class SnapcraftServiceFactory(ServiceFactory):
project: models.Project | None = None # type: ignore[reportIncompatibleVariableOverride]

# These are overrides of default ServiceFactory services
InitClass: type[services.Init] = ( # type: ignore[reportIncompatibleVariableOverride]
services.Init
)
LifecycleClass: type[services.Lifecycle] = ( # type: ignore[reportIncompatibleVariableOverride]
services.Lifecycle
)
Expand Down
Loading
Loading