diff --git a/angrmanagement/plugins/plugin_description.py b/angrmanagement/plugins/plugin_description.py index 0cb9a21c59..41719ec180 100644 --- a/angrmanagement/plugins/plugin_description.py +++ b/angrmanagement/plugins/plugin_description.py @@ -1,19 +1,18 @@ -from dataclasses import dataclass, field import pathlib -from typing import List, Optional, Dict +from dataclasses import field +from typing import Dict, List, Optional import marshmallow.validate -import marshmallow_dataclass import tomlkit -from marshmallow_dataclass import dataclass as dataclass_with_schema +from marshmallow_dataclass import dataclass -@dataclass_with_schema +@dataclass class MetadataDescription: version: int = field(metadata={"validate": marshmallow.validate.OneOf([0])}) -@dataclass_with_schema +@dataclass class PackageDescription: """ Describes a plugin package. @@ -28,7 +27,7 @@ class PackageDescription: long_description: str = field(default="") -@dataclass_with_schema +@dataclass class PluginDescription: """ Describes an angr management plugin. Can be generated from plugin.toml. @@ -52,19 +51,16 @@ class PluginConfigFileDescription: plugins: Dict[str, PluginDescription] = field(default_factory=dict) -PluginConfigSchema = marshmallow_dataclass.class_schema(PluginConfigFileDescription)() - - def from_toml_string(toml_string: str) -> PluginConfigFileDescription: """ Load a plugin config file from a TOML string. """ - return PluginConfigSchema.load(tomlkit.parse(toml_string)) + return PluginConfigFileDescription.Schema().load(tomlkit.parse(toml_string)) def from_toml_file(toml_file: pathlib.Path) -> PluginConfigFileDescription: """ Load a plugin config file from a TOML file. """ - with open(toml_file, "r") as f: + with open(toml_file) as f: return from_toml_string(f.read()) diff --git a/docs/plugin_metadata_spec.md b/docs/plugin_metadata_spec.md index 6f29e25ef2..6562717b6f 100644 --- a/docs/plugin_metadata_spec.md +++ b/docs/plugin_metadata_spec.md @@ -2,10 +2,8 @@ Plugin Metadata Specification ============================= Each plugin directory must have a plugin.toml file. A plugin metadata file has -two types of sections: `meta` and `plugin`. Each plugin.toml must contain one -meta section, but may contain -Below are tables of keys for each -section. +three sections: `meta`, `package` and `plugins`. Each plugin.toml must contain +one meta section, but may contain Below are tables of keys for each sections. ## Meta section | Key | Type | Required | Notes | @@ -32,7 +30,7 @@ strings. See https://docs.python.org/3/library/sys.html#sys.platform to learn more about the `sys.platform` value in Python. -## Plugin section +## Plugins section | Key | Type | Required | Default | Notes | | ------------------ | ---------------------- | -------- | --------------------- | ------------------------------------------ | | name | string | yes | | | diff --git a/tests/test_plugin_desciption_loading.py b/tests/test_plugin_desciption_loading.py index 6c04085337..cd5386ffd3 100644 --- a/tests/test_plugin_desciption_loading.py +++ b/tests/test_plugin_desciption_loading.py @@ -1,14 +1,13 @@ import unittest import tomlkit +from marshmallow import ValidationError from angrmanagement.plugins.plugin_description import ( + MetadataDescription, PackageDescription, PluginDescription, from_toml_string, - MetadataDescription, - MetadataDescription, - MetadataDescription, ) @@ -19,7 +18,7 @@ def test_metadta_section(self): def test_metadata_section_invalid_version(self): test_data = "version = 1_000_000" - with self.assertRaises(Exception): + with self.assertRaises(ValidationError): MetadataDescription.Schema().load(tomlkit.parse(test_data)) def test_minimal_package(self): @@ -36,6 +35,17 @@ def test_minimal_plugin(self): """ PluginDescription.Schema().load(tomlkit.parse(test_data)) + def test_no_plugins(self): + test_data = """ +[metadata] +version = 0 + +[package] +name = "example" +version = "1.0" +""" + from_toml_string(test_data) + def test_minimal(self): test_data = """ [metadata] @@ -47,8 +57,7 @@ def test_minimal(self): [plugin.example] name = "Example" -version = "1.0" -entrypoints = ["example.py::ExamplePlugin"] +entrypoint = "example.py::ExamplePlugin" """ from_toml_string(test_data) @@ -61,24 +70,24 @@ def test_multiple(self): name = "example" version = "1.0" platforms = ["any"] -site_pacakges = "site-packages" +site_packages = "site-packages" authors = ["Example"] description = "An example plugin package" -long-description = "An example plugin package for testing angr management" +long_description = "An example plugin package for testing angr management" -[plugin.example1] +[plugins.example1] name = "Example 1" -entrypoints = ["example.py::ExamplePlugin1"] +entrypoint = "example.py::ExamplePlugin1" platforms = ["linux"] description = "An example plugin for testing angr management on linuz" -requires-workspace = false +requires_workspace = false -[plugin.example2] +[plugins.example2] name = "Example 2" -entrypoints = ["example.py::ExamplePlugin2"] +entrypoint = "example.py::ExamplePlugin2" platforms = ["win32", "cygwin"] description = "An example plugin for testing angr management on windows" -requires-workspace = true +requires_workspace = true """ from_toml_string(test_data)