Skip to content

Commit

Permalink
Add Cargo plugin and tests, update Toml plugin
Browse files Browse the repository at this point in the history
  • Loading branch information
Sebastian Simon committed Oct 9, 2024
1 parent cb5a1ee commit a405148
Show file tree
Hide file tree
Showing 8 changed files with 198 additions and 160 deletions.
56 changes: 56 additions & 0 deletions src/cfgnet/plugins/concept/cargo_plugin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# This file is part of the CfgNet module.
#
# This program is free software: you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free Software
# Foundation, either version 3 of the License, or (at your option) any later
# version.
#
# 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 <https://www.gnu.org/licenses/>.
from cfgnet.plugins.file_type.toml_plugin import TomlPlugin
from cfgnet.config_types.config_types import ConfigType


class CargoPlugin(TomlPlugin):
def __init__(self):
super().__init__("cargo")
self.excluded_keys = [
"description",
"authors",
"maintainers",
"readme",
"keywords",
"classifiers",
]

def is_responsible(self, abs_file_path: str) -> bool:
if abs_file_path.endswith("Cargo.toml"):
return True
return False

@staticmethod
def get_config_type(option_name: str) -> ConfigType:
"""
Find config type based on option name.
:param option_name: name of option
:return: config type
"""
if option_name in (
"homepage",
"repository",
"documentation",
"urls",
"url",
):
return ConfigType.URL
if option_name in ("include", "exclude"):
return ConfigType.PATH
if option_name in ("version", "dependencies", "dev-dependencies"):
return ConfigType.VERSION_NUMBER
return ConfigType.UNKNOWN
27 changes: 3 additions & 24 deletions src/cfgnet/plugins/file_type/toml_plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,31 +87,10 @@ def _iter_data(self, data, line_number_dict, parent):
if isinstance(value, dict):
self._iter_data(value, line_number_dict, option)
elif isinstance(value, list):
index = 0
for entry in value:
if isinstance(entry, dict):
virtual_option = OptionNode(
option.name + "_" + str(index), lineno
)
option.add_child(virtual_option)
self._iter_data(
entry, line_number_dict, virtual_option
)
index += 1
else:
name = (
f"{option.name}:{entry}"
if option.config_type
== ConfigType.VERSION_NUMBER
else entry
)
option.add_child(ValueNode(name))
value_node = ValueNode(name=str(value))
option.add_child(value_node)
else:
name = (
f"{option.name}:{value}"
if option.config_type == ConfigType.VERSION_NUMBER
else value
)
name = value
option.add_child(ValueNode(name))

# pylint: disable=unused-argument
Expand Down
2 changes: 2 additions & 0 deletions src/cfgnet/plugins/plugin_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
from cfgnet.plugins.concept.angular_plugin import AngularPlugin
from cfgnet.plugins.concept.mapreduce_plugin import MapReducePlugin
from cfgnet.plugins.concept.circleci_plugin import CircleCiPlugin
from cfgnet.plugins.concept.cargo_plugin import CargoPlugin


class PluginManager:
Expand Down Expand Up @@ -85,6 +86,7 @@ class PluginManager:
AngularPlugin(),
MapReducePlugin(),
CircleCiPlugin(),
CargoPlugin(),
]

file_type_plugins: List[Plugin] = [
Expand Down
85 changes: 85 additions & 0 deletions tests/cfgnet/plugins/concept/test_cargo_plugin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
# This file is part of the CfgNet module.
#
# This program is free software: you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free Software
# Foundation, either version 3 of the License, or (at your option) any later
# version.
#
# 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 <https://www.gnu.org/licenses/>.
import os
import pytest

from cfgnet.plugins.concept.cargo_plugin import CargoPlugin
from cfgnet.config_types.config_types import ConfigType
from tests.utility.id_creator import make_id


@pytest.fixture(name="get_plugin")
def get_plugin_():
plugin = CargoPlugin()
return plugin


def test_is_responsible(get_plugin):
plugin = get_plugin

assert plugin.is_responsible("tests/files/Cargo.toml")
assert not plugin.is_responsible("tests/files/test.toml")


def test_parse_pyproject_file(get_plugin):
plugin = get_plugin
file = os.path.abspath("tests/files/Cargo.toml")

artifact = plugin.parse_file(file, "Cargo.toml")
nodes = artifact.get_nodes()
ids = {node.id for node in nodes}

assert artifact is not None
assert len(nodes) == 13

assert make_id("Cargo.toml", "file", "Cargo.toml") in ids
assert make_id("Cargo.toml", "package", "name", "example") in ids
assert make_id("Cargo.toml", "package", "version", "0.1.0") in ids
assert make_id("Cargo.toml", "package", "edition", "2021") in ids
assert make_id("Cargo.toml", "package", "license", "MIT") in ids
assert make_id("Cargo.toml", "package", "homepage", "https://example.com") in ids
assert make_id("Cargo.toml", "package", "workspace", "path/to/workspace/root") in ids
assert make_id("Cargo.toml", "dependencies", "serde", "1.0") in ids
assert make_id("Cargo.toml", "dependencies", "rand", "0.8") in ids
assert make_id("Cargo.toml", "dev-dependencies", "tokio", "version", "1") in ids
assert make_id("Cargo.toml", "dev-dependencies", "tokio", "features", "['full']") in ids
assert make_id("Cargo.toml", "features", "default", "['serde']") in ids
assert make_id("Cargo.toml", "profile", "release", "opt-level", "3") in ids


def test_config_types(get_plugin):
plugin = get_plugin
file = os.path.abspath("tests/files/Cargo.toml")

artifact = plugin.parse_file(file, "Cargo.toml")
nodes = artifact.get_nodes()

name_node = next(filter(lambda x: x.id == make_id("Cargo.toml", "package", "name", "example"), nodes))
path_node = next(filter(lambda x: x.id == make_id("Cargo.toml", "package", "workspace", "path/to/workspace/root"), nodes))
number_node = next(filter(lambda x: x.id == make_id("Cargo.toml", "package", "edition", "2021"), nodes))
dep_node = next(filter(lambda x: x.id == make_id("Cargo.toml", "dependencies", "serde", "1.0"), nodes))
url_node = next(filter(lambda x: x.id == make_id("Cargo.toml", "package", "homepage", "https://example.com"), nodes))
version_node = next(filter(lambda x: x.id == make_id("Cargo.toml", "package", "version", "0.1.0"), nodes))
license_node = next(filter(lambda x: x.id == make_id("Cargo.toml", "package", "license", "MIT"), nodes))
number_node2 = next(filter(lambda x: x.id == make_id("Cargo.toml", "profile", "release", "opt-level", "3"), nodes))

assert path_node.config_type == ConfigType.PATH
assert url_node.config_type == ConfigType.URL
assert license_node.config_type == ConfigType.LICENSE
assert dep_node.config_type == ConfigType.VERSION_NUMBER
assert number_node.config_type == ConfigType.NUMBER
assert version_node.config_type == ConfigType.VERSION_NUMBER
assert name_node.config_type == ConfigType.NAME
assert number_node2.config_type == ConfigType.NUMBER
89 changes: 10 additions & 79 deletions tests/cfgnet/plugins/concept/test_pyproject_plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,88 +47,19 @@ def test_parse_pyproject_file(get_plugin):
ids = {node.id for node in nodes}

assert artifact is not None
assert len(nodes) == 12
assert len(nodes) == 11

assert make_id("pyproject.toml", "file", "pyproject.toml") in ids
assert make_id("pyproject.toml", "tool", "poetry", "name", "CfgNet") in ids
assert (
make_id("pyproject.toml", "tool", "poetry", "version", "version:1.0.0")
in ids
)
assert (
make_id("pyproject.toml", "tool", "poetry", "include", "test.py")
in ids
)
assert (
make_id("pyproject.toml", "tool", "poetry", "exclude", "hello.py")
in ids
)
assert (
make_id("pyproject.toml", "tool", "poetry", "license", "GPL-3.0+")
in ids
)
assert (
make_id(
"pyproject.toml",
"tool",
"poetry",
"homepage",
"https://github.com",
)
in ids
)
assert (
make_id(
"pyproject.toml",
"tool",
"poetry",
"packages",
"packages_0",
"include",
"cfgnet",
)
in ids
)
assert (
make_id(
"pyproject.toml",
"tool",
"poetry",
"packages",
"packages_0",
"from",
"src",
)
in ids
)
assert (
make_id(
"pyproject.toml",
"tool",
"poetry",
"dependencies",
"python",
"python:^3.8",
)
in ids
)
assert (
make_id(
"pyproject.toml",
"tool",
"poetry",
"dev-dependencies",
"cov",
"cov:5.1",
)
in ids
)
assert (
make_id(
"pyproject.toml", "tool", "poetry", "scripts", "cfgnet", "main"
)
in ids
)
assert make_id("pyproject.toml", "tool", "poetry", "version", "1.0.0") in ids
assert make_id("pyproject.toml", "tool", "poetry", "include", "['test.py']") in ids
assert make_id("pyproject.toml", "tool", "poetry", "exclude", "['hello.py']") in ids
assert make_id("pyproject.toml", "tool", "poetry", "license", "GPL-3.0+") in ids
assert make_id("pyproject.toml", "tool", "poetry", "homepage", "https://github.com") in ids
assert make_id("pyproject.toml", "tool", "poetry", "packages", "[{'include': 'cfgnet', 'from': 'src'}]") in ids
assert make_id("pyproject.toml", "tool", "poetry", "dependencies", "python", "^3.8") in ids
assert make_id("pyproject.toml", "tool", "poetry", "dev-dependencies", "cov", "5.1") in ids
assert make_id("pyproject.toml", "tool", "poetry", "scripts", "cfgnet", "main") in ids


def test_config_types(get_plugin):
Expand Down
29 changes: 3 additions & 26 deletions tests/cfgnet/plugins/file_type/test_toml_plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,35 +46,12 @@ def test_parse_toml_file(get_plugin):
ids = {node.id for node in nodes}

assert artifact is not None
assert len(nodes) == 8
assert len(nodes) == 7

assert make_id("test.toml", "file", "test.toml") in ids
assert make_id("test.toml", "tool", "poetry", "name", "cfgnet") in ids
assert make_id("test.toml", "tool", "poetry", "version", "v1.1.0") in ids
assert make_id("test.toml", "tool", "poetry", "keywords", "config") in ids
assert make_id("test.toml", "tool", "poetry", "keywords", "['config']") in ids
assert make_id("test.toml", "dependencies", "python", "^3.6") in ids
assert make_id("test.toml", "dependencies", "gitpython", "^3.0") in ids
assert (
make_id(
"test.toml",
"tool",
"poetry",
"packages",
"packages_0",
"include",
"cfgnet",
)
in ids
)
assert (
make_id(
"test.toml",
"tool",
"poetry",
"packages",
"packages_0",
"from",
"src",
)
in ids
)
assert make_id("test.toml", "tool", "poetry", "packages", "[{'include': 'cfgnet', 'from': 'src'}]") in ids
44 changes: 13 additions & 31 deletions tests/cfgnet/plugins/test_plugin_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,42 +19,22 @@
def test_get_all_plugins():
all_plugins = PluginManager.get_plugins()

assert len(all_plugins) == 27
assert len(all_plugins) == 28


def test_get_responsible_plugin():
plugins = PluginManager.get_plugins()

docker_plugin = PluginManager.get_responsible_plugin(
plugins, "path/to/Dockerfile"
)
maven_plugin = PluginManager.get_responsible_plugin(
plugins, "path/to/pom.xml"
)
nodejs_plugin = PluginManager.get_responsible_plugin(
plugins, "path/to/package.json"
)
docker_compose_plugin = PluginManager.get_responsible_plugin(
plugins, "path/to/docker-compose.yml"
)
travis_plugin = PluginManager.get_responsible_plugin(
plugins, "path/to/.travis.yml"
)
cypress_plugin = PluginManager.get_responsible_plugin(
plugins, "path/to/cypress.json"
)
tsconfig_plugin = PluginManager.get_responsible_plugin(
plugins, "path/to/tsconfig.json"
)
poetry_plugin = PluginManager.get_responsible_plugin(
plugins, "path/to/pyproject.toml"
)
spring_plugin = PluginManager.get_responsible_plugin(
plugins, "path/to/application.properties"
)
apache_webserver_plugin = PluginManager.get_responsible_plugin(
plugins, "path/to/httpd.conf"
)
docker_plugin = PluginManager.get_responsible_plugin(plugins, "path/to/Dockerfile")
maven_plugin = PluginManager.get_responsible_plugin(plugins, "path/to/pom.xml")
nodejs_plugin = PluginManager.get_responsible_plugin(plugins, "path/to/package.json")
docker_compose_plugin = PluginManager.get_responsible_plugin(plugins, "path/to/docker-compose.yml")
travis_plugin = PluginManager.get_responsible_plugin(plugins, "path/to/.travis.yml")
cypress_plugin = PluginManager.get_responsible_plugin(plugins, "path/to/cypress.json")
tsconfig_plugin = PluginManager.get_responsible_plugin(plugins, "path/to/tsconfig.json")
poetry_plugin = PluginManager.get_responsible_plugin(plugins, "path/to/pyproject.toml")
spring_plugin = PluginManager.get_responsible_plugin(plugins, "path/to/application.properties")
apache_webserver_plugin = PluginManager.get_responsible_plugin(plugins, "path/to/httpd.conf")
mysql_plugin = PluginManager.get_responsible_plugin(plugins, "path/to/my.cnf")
ansible_plugin = PluginManager.get_responsible_plugin(plugins, "path/to/ansible.cfg")
ansible_playbook_plugin = PluginManager.get_responsible_plugin(plugins, "path/to/playbooks/test.yaml")
Expand All @@ -72,6 +52,7 @@ def test_get_responsible_plugin():
angular_plugin = PluginManager.get_responsible_plugin(plugins, "path/to/angular.json")
mapreduce_plugin = PluginManager.get_responsible_plugin(plugins, "path/to/mapred-site.xml")
circleci_plugin = PluginManager.get_responsible_plugin(plugins, "path/to/.circleci/config.yml")
cargo_plugin = PluginManager.get_responsible_plugin(plugins, "path/to/Cargo.toml")

assert docker_plugin.concept_name == "docker"
assert maven_plugin.concept_name == "maven"
Expand Down Expand Up @@ -100,3 +81,4 @@ def test_get_responsible_plugin():
assert angular_plugin.concept_name == "angular"
assert mapreduce_plugin.concept_name == "mapreduce"
assert circleci_plugin.concept_name == "circleci"
assert cargo_plugin.concept_name == "cargo"
Loading

0 comments on commit a405148

Please sign in to comment.