Skip to content

Commit 0ea9c7a

Browse files
Chris PattersonSergio Schvezov
authored andcommitted
plugin handler: fix local plugin class detection with direct imports
If a local plugin imports a snapcraft in-tree plugin directly, e.g. `from snapcraft.plugins.v1 import AutotoolsPlugin`, _get_local_plugin_class() will find an return the AutotoolsPlugin attribute, not the desired plugin class, which inherits from AutotoolsPlugin. This change filters out any attributes that has a __module__ from snapcraft.plugins.v1. This allows us to remove the direct check for PluginV1, which was likely the first case of filtering for this problem. Spread tests: - add another x-local test with this logic for PluginV1. - modify from-nilplugin to use the direct import of NilPlugin. Signed-off-by: Chris Patterson <chris.patterson@canonical.com>
1 parent c2d6012 commit 0ea9c7a

5 files changed

Lines changed: 59 additions & 3 deletions

File tree

snapcraft/internal/pluginhandler/_plugin_loader.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,12 @@ def _get_local_plugin_class(*, plugin_name: str, local_plugins_dir: str):
124124
continue
125125
if not issubclass(attr, plugins.v1.PluginV1):
126126
continue
127-
if attr == plugins.v1.PluginV1:
127+
if not hasattr(attr, "__module__"):
128+
continue
129+
logger.debug(
130+
f"Plugin attribute {attr!r} has __module__: {attr.__module__!r}"
131+
)
132+
if attr.__module__.startswith("snapcraft.plugins"):
128133
continue
129134
return attr
130135
else:

tests/spread/plugins/v1/x-local/local-plugin/task.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ summary: Use local plugins to build a snap
33
environment:
44
SNAP_DIR/baseplugin: ../snaps/from-baseplugin
55
SNAP_DIR/nilplugin: ../snaps/from-nilplugin
6+
SNAP_DIR/pluginv1: ../snaps/from-pluginv1
67

78
prepare: |
89
#shellcheck source=tests/spread/tools/snapcraft-yaml.sh

tests/spread/plugins/v1/x-local/snaps/from-nilplugin/snap/plugins/x_local_plugin.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,10 @@
1414
# You should have received a copy of the GNU General Public License
1515
# along with this program. If not, see <http://www.gnu.org/licenses/>.
1616

17-
from snapcraft.plugins import nil
17+
from snapcraft.plugins.v1 import NilPlugin
1818

1919

20-
class LocalPlugin(nil.NilPlugin):
20+
class LocalPlugin(NilPlugin):
2121
@classmethod
2222
def schema(cls):
2323
schema = super().schema()
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# -*- Mode:Python; indent-tabs-mode:nil; tab-width:4 -*-
2+
#
3+
# Copyright (C) 2015 Canonical Ltd
4+
#
5+
# This program is free software: you can redistribute it and/or modify
6+
# it under the terms of the GNU General Public License version 3 as
7+
# published by the Free Software Foundation.
8+
#
9+
# This program is distributed in the hope that it will be useful,
10+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
# GNU General Public License for more details.
13+
#
14+
# You should have received a copy of the GNU General Public License
15+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
16+
17+
from snapcraft.plugins.v1 import PluginV1
18+
19+
20+
class LocalPlugin(PluginV1):
21+
@classmethod
22+
def schema(cls):
23+
schema = super().schema()
24+
25+
schema["properties"]["foo"] = {"type": "string"}
26+
27+
return schema
28+
29+
@classmethod
30+
def get_pull_properties(cls):
31+
return ["foo", "stage-packages"]
32+
33+
@classmethod
34+
def get_build_properties(cls):
35+
return ["foo", "stage-packages"]
36+
37+
def build(self):
38+
return self.run(["touch", "build-stamp"], self.installdir)
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
name: test-local-plugins
2+
base: core18
3+
version: "0.1"
4+
summary: local plugin in snap/plugins
5+
description: Tests if local plugins load and can build
6+
confinement: strict
7+
grade: devel
8+
9+
parts:
10+
x-local-plugin:
11+
plugin: x-local-plugin
12+
source: .

0 commit comments

Comments
 (0)