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

feat(lint): migrate lint command #4732

Merged
merged 3 commits into from
Apr 18, 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
23 changes: 20 additions & 3 deletions snapcraft/application.py
Original file line number Diff line number Diff line change
Expand Up @@ -171,12 +171,27 @@ def _extra_yaml_transform(
self._parse_info = extract_parse_info(new_yaml_data)
return apply_root_packages(new_yaml_data)

@staticmethod
def _get_argv_command() -> str | None:
"""Return the first non-option argument."""
for arg in sys.argv[1:]:
if arg.startswith("-"):
continue
return arg

return None

@override
def _get_dispatcher(self) -> craft_cli.Dispatcher:
# Handle "multiplexing" of Snapcraft "codebases" depending on the
# project's base (if any). Here, we handle the case where there *is*
# a project and it's core24, which means it should definitely fall into
# the craft-application-based flow.
argv_command = self._get_argv_command()
if argv_command == "lint":
# We don't need to check for core24 if we're just linting
return super()._get_dispatcher()

if self._snapcraft_yaml_path:
with self._snapcraft_yaml_path.open() as file:
yaml_data = util.safe_yaml_load(file)
Expand All @@ -186,9 +201,11 @@ def _get_dispatcher(self) -> craft_cli.Dispatcher:
if "core24" in (base, build_base) or build_base == "devel":
# We know for sure that we're handling a core24 project
self._known_core24 = True
elif any(arg in ("version", "--version", "-V") for arg in sys.argv):
elif (
argv_command == "version" or "--version" in sys.argv or "-V" in sys.argv
):
pass
elif "remote-build" in sys.argv and any(
elif argv_command == "remote-build" and any(
b in ("core20", "core22") for b in (base, build_base)
):
build_strategy = os.environ.get("SNAPCRAFT_REMOTE_BUILD_STRATEGY", None)
Expand Down Expand Up @@ -327,7 +344,7 @@ def create_app() -> Snapcraft:
"Other",
list(craft_app_commands.get_other_command_group().commands)
+ [
unimplemented.Lint,
commands.LintCommand,
unimplemented.Init,
],
)
Expand Down
1 change: 0 additions & 1 deletion snapcraft/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,6 @@
craft_cli.CommandGroup(
"Other",
[
commands.core22.LintCommand,
commands.core22.InitCommand,
],
),
Expand Down
2 changes: 2 additions & 0 deletions snapcraft/commands/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
StoreLegacyValidateCommand,
)
from .lifecycle import SnapCommand
from .lint import LintCommand
from .manage import StoreCloseCommand, StoreReleaseCommand
from .names import (
StoreLegacyListCommand,
Expand All @@ -58,6 +59,7 @@

__all__ = [
"ExpandExtensions",
"LintCommand",
"ListExtensions",
"RemoteBuildCommand",
"SnapCommand",
Expand Down
2 changes: 0 additions & 2 deletions snapcraft/commands/core22/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,13 @@
StageCommand,
TryCommand,
)
from .lint import LintCommand

__all__ = [
"BuildCommand",
"CleanCommand",
"ExpandExtensionsCommand",
"ExtensionsCommand",
"InitCommand",
"LintCommand",
"ListExtensionsCommand",
"ListPluginsCommand",
"PackCommand",
Expand Down
3 changes: 2 additions & 1 deletion snapcraft/commands/core22/extensions.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,8 @@ def run(self, parsed_args):

# `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")
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
Expand Down
19 changes: 12 additions & 7 deletions snapcraft/commands/core22/lint.py → snapcraft/commands/lint.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# -*- Mode:Python; indent-tabs-mode:nil; tab-width:4 -*-
#
# Copyright 2023 Canonical Ltd.
# Copyright 2023-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
Expand All @@ -24,9 +24,10 @@
import textwrap
from contextlib import contextmanager
from pathlib import Path, PurePosixPath
from typing import Iterator, Optional
from typing import Any, Iterator, Optional

from craft_cli import BaseCommand, emit
from craft_application.commands import AppCommand
from craft_cli import emit
from craft_cli.errors import ArgumentParsingError
from craft_providers.multipass import MultipassProvider
from craft_providers.util import snap_cmd
Expand All @@ -42,9 +43,10 @@
)


class LintCommand(BaseCommand):
class LintCommand(AppCommand):
"""Lint-related commands."""

always_load_project = False
name = "lint"
help_msg = "Lint a snap file"
overview = textwrap.dedent(
Expand All @@ -58,7 +60,7 @@ class LintCommand(BaseCommand):
)

@overrides
def fill_parser(self, parser: "argparse.ArgumentParser") -> None:
def fill_parser(self, parser: argparse.ArgumentParser) -> None:
parser.add_argument(
"snap_file",
metavar="snap-file",
Expand All @@ -78,8 +80,11 @@ def fill_parser(self, parser: "argparse.ArgumentParser") -> None:
help="Set https proxy",
)

@overrides
def run(self, parsed_args: argparse.Namespace):
def run( # pylint: disable=unused-argument
self,
parsed_args: argparse.Namespace,
**kwargs: Any,
) -> None:
"""Run the linter command.

:param parsed_args: snapcraft's argument namespace
Expand Down
6 changes: 0 additions & 6 deletions snapcraft/commands/unimplemented.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,9 +105,3 @@ class Try(
UnimplementedMixin, commands.core22.TryCommand
): # noqa: D101 (missing docstring)
pass


class Lint(
UnimplementedMixin, commands.core22.LintCommand
): # noqa: D101 (missing docstring)
pass
19 changes: 17 additions & 2 deletions snapcraft/parts/yaml_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -196,8 +196,23 @@ def apply_yaml(
parts_yaml_data=yaml_data["parts"], arch=build_on, target_arch=build_for
)

# replace all architectures with the architectures in the current build plan
yaml_data["architectures"] = [Architecture(build_on=build_on, build_for=build_for)]
if any(
b.startswith("core20") or b.startswith("core22")
for b in (
yaml_data.get("base", ""),
yaml_data.get("build-base", ""),
yaml_data.get("name", ""),
)
):
# replace all architectures with the architectures in the current build plan
yaml_data["architectures"] = [
Architecture(build_on=build_on, build_for=build_for)
]
else:
# replace all platforms with the platform in the current build plan
yaml_data["platforms"] = {
build_for: {"build-on": build_on, "build-for": build_for}
}

return yaml_data

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
Running linters...
Running linter: library
Lint warnings:
- library: linter-test: missing dependency 'libcaca.so.0'. (https://snapcraft.io/docs/linters-library)
- library: libpng16.so.16: unused library 'usr/lib/x86_64-linux-gnu/libpng16.so.16.37.0'. (https://snapcraft.io/docs/linters-library)
Lint warnings:
- library: linter-test: missing dependency 'libcaca.so.0'. (https://snapcraft.io/docs/linters-library)
- library: libogg.so.0: unused library 'usr/lib/x86_64-linux-gnu/libogg.so.0.8.5'. (https://snapcraft.io/docs/linters-library)
2 changes: 1 addition & 1 deletion tests/spread/core24/linters-file/lint-file/snapcraft.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,6 @@ parts:
- gcc
- libcaca-dev
stage-packages:
- libpng16-16
- libogg0
override-build:
gcc -o $CRAFT_PART_INSTALL/linter-test test.c -lcaca
18 changes: 13 additions & 5 deletions tests/spread/core24/linters-file/task.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
summary: Run snapcraft lint on a snap file.
# Disabled from regular CI runs until we have "snapcraft lint" in core24
manual: true

environment:
SNAP: lint-file
Expand All @@ -15,9 +13,19 @@ execute: |
# build the test snap destructively to save time
snapcraft --destructive-mode

snapcraft lint lint-file_0.1_*.snap 2> output.txt
snapcraft lint lint-file_0.1_*.snap 2> output.txt || {
lxc --project snapcraft start snapcraft-linter &&
sleep 10 &&
lxc --project snapcraft exec snapcraft-linter -- snap install --edge core24 &&
mr-cal marked this conversation as resolved.
Show resolved Hide resolved
snapcraft lint lint-file_0.1_*.snap 2> output.txt
}

# TODO: restore this when core24 is stable
# core24 testing has undefined symbol warnings
# get the lint warnings at end of the log file
sed -n '/Running linters.../,+4 p' < output.txt > linter-output.txt
#sed -n '/Running linters.../,+4 p' < output.txt > linter-output.txt

diff -u linter-output.txt expected-linter-output.txt
#diff -u linter-output.txt expected-linter-output.txt

MATCH "library: linter-test: missing dependency 'libcaca.so.0'" < output.txt
MATCH "library: libogg.so.0: unused library" < output.txt
Loading
Loading