From b6b11500c91b97de4ef725960eb78894cca58b3c Mon Sep 17 00:00:00 2001 From: Sebastian Simon Date: Thu, 26 Sep 2024 09:59:24 +0200 Subject: [PATCH] Update Maven plugin --- src/cfgnet/network/nodes.py | 2 +- src/cfgnet/plugins/concept/maven_plugin.py | 138 +++++++----------- tests/cfgnet/network/__init__.py | 0 tests/cfgnet/network/test_network.py | 16 +- .../concept/test_docker_compose_plugin.py | 6 +- .../plugins/concept/test_maven_plugin.py | 50 +++---- tests/files/pom.xml | 2 - .../0001-Add-Docker-and-maven-file.patch | 4 +- 8 files changed, 88 insertions(+), 130 deletions(-) create mode 100644 tests/cfgnet/network/__init__.py diff --git a/src/cfgnet/network/nodes.py b/src/cfgnet/network/nodes.py index cdbdf64f..6136065e 100644 --- a/src/cfgnet/network/nodes.py +++ b/src/cfgnet/network/nodes.py @@ -44,7 +44,7 @@ class Node: """ - def __init__(self, name: str, parent: Node = None): + def __init__(self, name: str, parent: Optional[Node] = None): self.name: str = name self.parent: Optional[Node] = parent self.children: List[Any] = [] diff --git a/src/cfgnet/plugins/concept/maven_plugin.py b/src/cfgnet/plugins/concept/maven_plugin.py index cf2c789f..a01c942e 100644 --- a/src/cfgnet/plugins/concept/maven_plugin.py +++ b/src/cfgnet/plugins/concept/maven_plugin.py @@ -98,98 +98,71 @@ def is_responsible(self, abs_file_path: str) -> bool: return False def parse_tree(self, subtree_root: _Element, parent_node: Node): - name = self._get_option_name(subtree_root) + name = subtree_root.tag + if name: - config_type = self.get_config_type(name) - option = OptionNode(name, subtree_root.sourceline, config_type) - parent_node.add_child(option) - - self._add_attribs(subtree_root, option) - - text = subtree_root.text - if text: - text = text.strip() - if text: - name = self._get_value_name( - text=text, config_type=config_type, parent=option - ) + if name in ["dependencies", "plugins"]: + config_type = self.get_config_type(name) + option = OptionNode(name, subtree_root.sourceline, config_type) + parent_node.add_child(option) - value_node = ValueNode(name=name) - option.add_child(value_node) + self._parse_artifacts(subtree_root, option) - for child in subtree_root: - if child.tag is not ET.Comment: - self.parse_tree(child, option) + else: + config_type = self.get_config_type(name) + option = OptionNode(name, subtree_root.sourceline, config_type) + parent_node.add_child(option) + + value_name = subtree_root.text.strip() + + if value_name: + value_node = ValueNode(name=value_name) + option.add_child(value_node) + else: + for child in subtree_root: + if child.tag is not ET.Comment: + self.parse_tree(child, option) # remove option nodes without children if not option.children: parent_node.children.remove(option) - @staticmethod - def _add_attribs(subtree_root: _Element, current_node: OptionNode): - current_attribs = subtree_root.attrib - for key in current_attribs: - config_type = MavenPlugin.get_config_type(key) - option = OptionNode(key, subtree_root.sourceline, config_type) - current_node.add_child(option) - value = current_attribs[key] - - name = MavenPlugin._get_value_name( - text=value, config_type=config_type, parent=option - ) - - value_node = ValueNode(name=name) - option.add_child(value_node) - - # pylint: disable=too-many-return-statements - @staticmethod - def _get_option_name(current_item: _Element) -> str: - """ - Construct a name for an option node to avoid ambiguous option nodes. - - :param current_item: lxml etree element that should be inserted as an option node - :return: constructed name - """ - id_element = current_item.find("id") - if id_element is not None: - if id_element.text is not None: - return current_item.tag + "_" + id_element.text - - artifact_id = current_item.find("artifactId") - if artifact_id is not None: - if artifact_id.text is not None: - return current_item.tag + "_" + artifact_id.text + def _parse_artifacts(self, subtree: _Element, current_node: OptionNode): + """Parse Maven artifacts.""" + for child in subtree: + if child.tag in ["dependency", "plugin"]: + qualified_name = self._get_fully_qualified_name(child) + config_type = self.get_config_type(qualified_name) + option_node = OptionNode( + name=qualified_name, + location=child.sourceline, + config_type=config_type, + ) + current_node.add_child(option_node) - if current_item.tag in TAGS_CONTAINING_LISTS: - if current_item.text is not None: - return current_item.tag + "_" + current_item.text + for element in child: + self.parse_tree( + subtree_root=element, parent_node=option_node + ) - return current_item.tag - - @staticmethod - def _get_value_name( - text: str, config_type: ConfigType, parent: OptionNode - ) -> str: - """Create name for value name.""" - if any(x in parent.id for x in ["dependencies", "plugins"]): - if parent.parent: - option_parts = parent.parent.name.split("_") - if len(option_parts) == 2: - option_name = option_parts[-1] - else: - option_name = parent.name - name = ( - f"{option_name}:{text}" - if config_type == ConfigType.VERSION_NUMBER - else text - ) - else: - name = ( - f"{parent.name}:{text}" - if config_type == ConfigType.VERSION_NUMBER - else text - ) - return name + # pylint: disable=invalid-name + def _get_fully_qualified_name(self, subtree: _Element) -> str: + """Get fully qualified name for Maven artifacts.""" + artifactID = None + groupID = None + version = None + for child in subtree: + if child.tag == "artifactId": + artifactID = child.text + if child.tag == "groupId": + groupID = child.text + if child.tag == "version": + version = child.text + + if version: + return f"{groupID}:{artifactID}:{version}" + + return f"{groupID}:{artifactID}" def _add_executable_name(self, artifact: ArtifactNode) -> None: try: @@ -306,6 +279,7 @@ def _get_packaging_for_executable_name( return "jar", None @staticmethod + # pylint: disable=too-many-return-statements def get_config_type(option_name: str) -> ConfigType: """ Get config type based on the option name. diff --git a/tests/cfgnet/network/__init__.py b/tests/cfgnet/network/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/cfgnet/network/test_network.py b/tests/cfgnet/network/test_network.py index 2524f5fb..d5ba0c0e 100644 --- a/tests/cfgnet/network/test_network.py +++ b/tests/cfgnet/network/test_network.py @@ -80,28 +80,20 @@ def test_enable_internal_links(get_config): config.enable_internal_links = True network = Network.init_network(cfg=config) - for node in network.get_nodes(node_type=ValueNode): - if "Dockerfile" in node.id: - print("Node: ", node, node.config_type) - - for link in network.links: - print("=======================") - print("Link: ", link) - print(f"{link.node_a.config_type}<->{link.node_b.config_type}") - expected_links = { "app.jar", "target/example-app-1.0.jar", "pom.xml", "builder", - "version:5.9", + "monitoring", + "5.9" } link_targets = { str(link).rsplit("::::", maxsplit=1)[-1] for link in network.links } - - assert len(network.links) == 5 + + assert len(network.links) == 6 assert expected_links == link_targets diff --git a/tests/cfgnet/plugins/concept/test_docker_compose_plugin.py b/tests/cfgnet/plugins/concept/test_docker_compose_plugin.py index 264c08c6..ede3427d 100644 --- a/tests/cfgnet/plugins/concept/test_docker_compose_plugin.py +++ b/tests/cfgnet/plugins/concept/test_docker_compose_plugin.py @@ -127,11 +127,7 @@ def test_config_types(get_plugin): artifact = docker_compose_plugin.parse_file(file, "docker-compose.yml") nodes = artifact.get_nodes() - - for node in nodes: - print(node) - - + port_node = next( filter( lambda x: x.id diff --git a/tests/cfgnet/plugins/concept/test_maven_plugin.py b/tests/cfgnet/plugins/concept/test_maven_plugin.py index 74cfc9fe..5ab82a23 100644 --- a/tests/cfgnet/plugins/concept/test_maven_plugin.py +++ b/tests/cfgnet/plugins/concept/test_maven_plugin.py @@ -50,24 +50,23 @@ def test_parse_maven_file(get_plugin): print(id) assert artifact is not None - assert len(value_nodes) == 33 - - assert make_id("pom.xml", "project", "dependencyManagement", "dependencies", "dependency_hibernate", "version", "hibernate:3.2.5.ga") in ids - assert make_id("pom.xml", "project", "dependencyManagement", "dependencies", "dependency_hibernate", "groupId", "org.hibernate") in ids - assert make_id("pom.xml", "project", "dependencyManagement", "dependencies", "dependency_hibernate", "artifactId", "hibernate") in ids - assert make_id("pom.xml", "project", "dependencyManagement", "dependencies", "dependency_ejb3-persistence", "version", "ejb3-persistence:1.0.1.GA") in ids - assert make_id("pom.xml", "project", "dependencyManagement", "dependencies", "dependency_ejb3-persistence", "groupId", "org.hibernate") in ids - assert make_id("pom.xml", "project", "dependencyManagement", "dependencies", "dependency_ejb3-persistence", "artifactId", "ejb3-persistence") in ids - assert make_id("pom.xml", "project", "dependencyManagement", "dependencies", "dependency_hibernate-core", "version", "hibernate-core:3.6.3.Final") in ids - assert make_id("pom.xml", "project", "dependencyManagement", "dependencies", "dependency_hibernate-core", "groupId", "org.hibernate") in ids - assert make_id("pom.xml", "project", "dependencyManagement", "dependencies", "dependency_hibernate-core", "artifactId", "hibernate-core") in ids + assert len(value_nodes) == 31 + + assert make_id("pom.xml", "project", "dependencyManagement", "dependencies", "org.hibernate:hibernate:3.2.5.ga", "version", "3.2.5.ga") in ids + assert make_id("pom.xml", "project", "dependencyManagement", "dependencies", "org.hibernate:hibernate:3.2.5.ga", "groupId", "org.hibernate") in ids + assert make_id("pom.xml", "project", "dependencyManagement", "dependencies", "org.hibernate:hibernate:3.2.5.ga", "artifactId", "hibernate") in ids + assert make_id("pom.xml", "project", "dependencyManagement", "dependencies", "org.hibernate:ejb3-persistence:1.0.1.GA", "version", "1.0.1.GA") in ids + assert make_id("pom.xml", "project", "dependencyManagement", "dependencies", "org.hibernate:ejb3-persistence:1.0.1.GA", "groupId", "org.hibernate") in ids + assert make_id("pom.xml", "project", "dependencyManagement", "dependencies", "org.hibernate:ejb3-persistence:1.0.1.GA", "artifactId", "ejb3-persistence") in ids + assert make_id("pom.xml", "project", "dependencyManagement", "dependencies", "org.hibernate:hibernate-core", "groupId", "org.hibernate") in ids + assert make_id("pom.xml", "project", "dependencyManagement", "dependencies", "org.hibernate:hibernate-core", "artifactId", "hibernate-core") in ids assert make_id("pom.xml", "project", "modules", "module", "config") in ids - assert make_id("pom.xml", "project", "modelVersion", "modelVersion:4.0.0") in ids + assert make_id("pom.xml", "project", "modelVersion", "4.0.0") in ids assert make_id("pom.xml", "project", "packaging", "jar") in ids assert make_id("pom.xml", "file", "pom.xml") in ids assert make_id("pom.xml", "project", "groupId", "com.example.apps") in ids assert make_id("pom.xml", "project", "artifactId", "my-cool-app") in ids - assert make_id("pom.xml", "project", "version", "version:42") in ids + assert make_id("pom.xml", "project", "version", "42") in ids assert make_id("pom.xml", "project", "packaging", "jar") in ids assert make_id("pom.xml", "ExecutableName", "target/my-cool-app-42.jar") in ids assert make_id("pom.xml", "ExecutableNameNoVersion", "target/my-cool-app.jar") in ids @@ -75,17 +74,16 @@ def test_parse_maven_file(get_plugin): assert make_id("pom.xml", "project", "distributionManagement", "downloadUrl", "http://test/my-project") in ids assert make_id("pom.xml", "project", "issueManagement", "system", "Bugzilla") in ids assert make_id("pom.xml", "project", "issueManagement", "url", "http://test/bugzilla/") in ids - assert make_id("pom.xml", "project", "build", "plugins", "plugin_maven-shade-plugin", "version", "maven-shade-plugin:1.4") in ids - assert make_id("pom.xml", "project", "build", "plugins", "plugin_maven-shade-plugin", "groupId", "org.apache.maven.plugins") in ids - assert make_id("pom.xml", "project", "build", "plugins", "plugin_maven-shade-plugin", "artifactId", "maven-shade-plugin") in ids - assert make_id("pom.xml", "project", "build", "plugins", "plugin_maven-shade-plugin", "executions", "execution", "phase", "package") in ids - assert make_id("pom.xml", "project", "build", "plugins", "plugin_maven-shade-plugin", "configuration", "finalName", "test") in ids - assert make_id("pom.xml", "project", "build", "plugins", "plugin_maven-shade-plugin", "executions", "execution", "goals", "goal_shade", "shade") in ids - assert make_id("pom.xml", "project", "build", "plugins", "plugin_maven-compiler-plugin", "version", "maven-compiler-plugin:2.3.2") in ids - assert make_id("pom.xml", "project", "build", "plugins", "plugin_maven-compiler-plugin", "groupId", "org.apache.maven.plugins") in ids - assert make_id("pom.xml", "project", "build", "plugins", "plugin_maven-compiler-plugin", "artifactId", "maven-compiler-plugin") in ids - assert make_id("pom.xml", "project", "build", "plugins", "plugin_maven-compiler-plugin", "configuration", "source", "source:1.6") in ids - assert make_id("pom.xml", "project", "build", "plugins", "plugin_maven-compiler-plugin", "configuration", "target", "target:1.6") in ids + assert make_id("pom.xml", "project", "build", "plugins", "org.apache.maven.plugins:maven-shade-plugin:1.4", "version", "1.4") in ids + assert make_id("pom.xml", "project", "build", "plugins", "org.apache.maven.plugins:maven-shade-plugin:1.4", "groupId", "org.apache.maven.plugins") in ids + assert make_id("pom.xml", "project", "build", "plugins", "org.apache.maven.plugins:maven-shade-plugin:1.4", "artifactId", "maven-shade-plugin") in ids + assert make_id("pom.xml", "project", "build", "plugins", "org.apache.maven.plugins:maven-shade-plugin:1.4", "executions", "execution", "phase", "package") in ids + assert make_id("pom.xml", "project", "build", "plugins", "org.apache.maven.plugins:maven-shade-plugin:1.4", "configuration", "finalName", "test") in ids + assert make_id("pom.xml", "project", "build", "plugins", "org.apache.maven.plugins:maven-shade-plugin:1.4", "executions", "execution", "goals", "goal", "shade") in ids + assert make_id("pom.xml", "project", "build", "plugins", "org.apache.maven.plugins:maven-compiler-plugin", "groupId", "org.apache.maven.plugins") in ids + assert make_id("pom.xml", "project", "build", "plugins", "org.apache.maven.plugins:maven-compiler-plugin", "artifactId", "maven-compiler-plugin") in ids + assert make_id("pom.xml", "project", "build", "plugins", "org.apache.maven.plugins:maven-compiler-plugin", "configuration", "source", "1.6") in ids + assert make_id("pom.xml", "project", "build", "plugins", "org.apache.maven.plugins:maven-compiler-plugin", "configuration", "target", "1.6") in ids def test_config_types(get_plugin): @@ -130,7 +128,7 @@ def test_config_types(get_plugin): version_node = next( filter( lambda x: x.id - == make_id("pom.xml", "project", "version", "version:42"), + == make_id("pom.xml", "project", "version", "42"), nodes, ) ) @@ -139,7 +137,7 @@ def test_config_types(get_plugin): filter( lambda x: x.id == make_id( - "pom.xml", "project", "modelVersion", "modelVersion:4.0.0" + "pom.xml", "project", "modelVersion", "4.0.0" ), nodes, ) diff --git a/tests/files/pom.xml b/tests/files/pom.xml index 459d6e9c..998c50cf 100644 --- a/tests/files/pom.xml +++ b/tests/files/pom.xml @@ -12,7 +12,6 @@ org.hibernate hibernate-core - 3.6.3.Final org.hibernate @@ -36,7 +35,6 @@ org.apache.maven.plugins maven-compiler-plugin - 2.3.2 1.6 1.6 diff --git a/tests/test_repos/maven_docker/0001-Add-Docker-and-maven-file.patch b/tests/test_repos/maven_docker/0001-Add-Docker-and-maven-file.patch index db5085ec..cd78ad3d 100644 --- a/tests/test_repos/maven_docker/0001-Add-Docker-and-maven-file.patch +++ b/tests/test_repos/maven_docker/0001-Add-Docker-and-maven-file.patch @@ -49,8 +49,8 @@ index 0000000..ddcc1c2 + + + -+ selenium -+ selenium_artifact ++ test ++ monitoring + 5.9 + +