From 4ca87ae1e7024413100a3371880d3d783353eee8 Mon Sep 17 00:00:00 2001 From: Bhavin Parmar Date: Tue, 3 Sep 2024 19:51:37 +0530 Subject: [PATCH 01/55] AC-3483:: SVC false-positive: modifying system.xml file from another module --- src/Analyzer/SystemXml/Analyzer.php | 72 ++++++++++++++++++++- src/Operation/SystemXml/FieldDuplicated.php | 34 ++++++++++ 2 files changed, 105 insertions(+), 1 deletion(-) create mode 100644 src/Operation/SystemXml/FieldDuplicated.php diff --git a/src/Analyzer/SystemXml/Analyzer.php b/src/Analyzer/SystemXml/Analyzer.php index 5fe050a3..2a4a3877 100644 --- a/src/Analyzer/SystemXml/Analyzer.php +++ b/src/Analyzer/SystemXml/Analyzer.php @@ -25,6 +25,7 @@ use Magento\SemanticVersionChecker\Registry\XmlRegistry; use PHPSemVerChecker\Registry\Registry; use PHPSemVerChecker\Report\Report; +use Magento\SemanticVersionChecker\Operation\SystemXml\FieldDuplicated; /** * Analyzes system.xml files: @@ -92,14 +93,63 @@ public function analyze($registryBefore, $registryAfter) $beforeFile = $registryBefore->mapping[XmlRegistry::NODES_KEY][$moduleName]; $this->reportRemovedNodes($beforeFile, $removedNodes); } + print_r('Added Nodes'); + print_r($addedNodes); if ($addedNodes) { $afterFile = $registryAfter->mapping[XmlRegistry::NODES_KEY][$moduleName]; - $this->reportAddedNodes($afterFile, $addedNodes); + $duplicateNode = $this->reportAddedNodesWithDuplicateCheck($afterFile, $addedNodes, $moduleNodesBefore); + print_r('Duplicate node '.$duplicateNode.' found'); + print_r("After file ". $afterFile ); + if ($duplicateNode) { + $this->reportDuplicateNodes($afterFile, $addedNodes); + } else { + $this->reportAddedNodes($afterFile, $addedNodes); + } } } return $this->report; } + /** + * Check and Report duplicate nodes + * + * @param $afterFile + * @param $addedNodes + * @param $moduleNodesBefore + * @return bool|void + */ + private function reportAddedNodesWithDuplicateCheck($afterFile, $addedNodes, $moduleNodesBefore) + { + print_r('Report Added Nodes function called.'); + foreach ($addedNodes as $nodeId => $node) { + // Check for duplicates by comparing node content except for 'id' + $isDuplicate = false; + foreach ($moduleNodesBefore as $existingNodeId => $existingNode) { + if ($this->isDuplicateNode($node, $existingNode)) { + $isDuplicate = true; + break; + } + } + return $isDuplicate; + } + } + + /** + * Check if node is duplicate or not + * + * @param $node + * @param $existingNode + * @return bool + */ + private function isDuplicateNode($node, $existingNode) + { + // Remove 'id' key for comparison + unset($node['id'], $existingNode['id']); + + // Compare the remaining parts of the nodes + return $node == $existingNode; + } + /** * Extracts the node from $registry as an associative array. * @@ -164,6 +214,26 @@ private function reportAddedNodes(string $file, array $nodes) } } + /** + * Creates reports for $nodes considering that they have been duplicated. + * + * @param string $file + * @param NodeInterface[] $nodes + */ + private function reportDuplicateNodes(string $file, array $nodes) + { + print_r('Duplicate Nodes switch case'); + foreach ($nodes as $node) { + echo "
$node->getPath()
"; + switch (true) { + case $node instanceof Field: + $this->report->add('system', new FieldDuplicated($file, $node->getPath())); + break; + default: + } + } + } + /** * Creates reports for $modules considering that system.xml has been removed from them. * diff --git a/src/Operation/SystemXml/FieldDuplicated.php b/src/Operation/SystemXml/FieldDuplicated.php new file mode 100644 index 00000000..6ce47bdf --- /dev/null +++ b/src/Operation/SystemXml/FieldDuplicated.php @@ -0,0 +1,34 @@ +field node is added. + */ +class FieldDuplicated extends AbstractOperation +{ + /** + * @var string + */ + protected $code = 'M302'; + + /** + * @var int + */ + protected $level = Level::PATCH; + + /** + * @var string + */ + protected $reason = 'A field-node was duplicated'; +} From cec6352a3cb8407283cffd14317ea48669164b18 Mon Sep 17 00:00:00 2001 From: Bhavin Parmar Date: Wed, 4 Sep 2024 12:43:20 +0530 Subject: [PATCH 02/55] AC-3483:: SVC false-positive: modifying system.xml file from another module --- src/Analyzer/SystemXml/Analyzer.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Analyzer/SystemXml/Analyzer.php b/src/Analyzer/SystemXml/Analyzer.php index 2a4a3877..87bae368 100644 --- a/src/Analyzer/SystemXml/Analyzer.php +++ b/src/Analyzer/SystemXml/Analyzer.php @@ -143,8 +143,10 @@ private function reportAddedNodesWithDuplicateCheck($afterFile, $addedNodes, $mo */ private function isDuplicateNode($node, $existingNode) { + $nodeData = $node->data; + $existingNodeData = $existingNode->data; // Remove 'id' key for comparison - unset($node['id'], $existingNode['id']); + unset($nodeData['id'], $existingNodeData['id']); // Compare the remaining parts of the nodes return $node == $existingNode; From 6ea687dd504ce2bceb8199240375230483f2389d Mon Sep 17 00:00:00 2001 From: Bhavin Parmar Date: Wed, 4 Sep 2024 14:08:40 +0530 Subject: [PATCH 03/55] AC-3483:: SVC false-positive: modifying system.xml file from another module --- src/Analyzer/SystemXml/Analyzer.php | 33 +++++++++++++++++++++++------ 1 file changed, 27 insertions(+), 6 deletions(-) diff --git a/src/Analyzer/SystemXml/Analyzer.php b/src/Analyzer/SystemXml/Analyzer.php index 87bae368..6abfe60f 100644 --- a/src/Analyzer/SystemXml/Analyzer.php +++ b/src/Analyzer/SystemXml/Analyzer.php @@ -143,13 +143,34 @@ private function reportAddedNodesWithDuplicateCheck($afterFile, $addedNodes, $mo */ private function isDuplicateNode($node, $existingNode) { - $nodeData = $node->data; - $existingNodeData = $existingNode->data; - // Remove 'id' key for comparison - unset($nodeData['id'], $existingNodeData['id']); + // Access the 'id' properties using possible getter methods + //Testing file + + $nodeId = $this->getPrivateProperty($node, 'id'); + $existingNodeId = $this->getPrivateProperty($existingNode, 'id'); - // Compare the remaining parts of the nodes - return $node == $existingNode; + // Access 'parent' properties if needed, depending on your logic + $nodeParent = $this->getPrivateProperty($node, 'parent'); + $existingNodeParent = $this->getPrivateProperty($existingNode, 'parent'); + + // Compare the nodes after ignoring 'id' + return $nodeParent == $existingNodeParent; + } + + /** + * Simplifies the reflection to get property + * + * @param $object + * @param $propertyName + * @return mixed + * @throws \ReflectionException + */ + private function getPrivateProperty($object, $propertyName) + { + $reflection = new \ReflectionClass($object); + $property = $reflection->getProperty($propertyName); + $property->setAccessible(true); + return $property->getValue($object); } /** From 0b32238321b85883e8e6338a978fc6231d0dfc80 Mon Sep 17 00:00:00 2001 From: Bhavin Parmar Date: Wed, 4 Sep 2024 14:41:21 +0530 Subject: [PATCH 04/55] AC-3483:: SVC false-positive: modifying system.xml file from another module --- src/Analyzer/SystemXml/Analyzer.php | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/src/Analyzer/SystemXml/Analyzer.php b/src/Analyzer/SystemXml/Analyzer.php index 6abfe60f..593aca0e 100644 --- a/src/Analyzer/SystemXml/Analyzer.php +++ b/src/Analyzer/SystemXml/Analyzer.php @@ -122,6 +122,7 @@ private function reportAddedNodesWithDuplicateCheck($afterFile, $addedNodes, $mo { print_r('Report Added Nodes function called.'); foreach ($addedNodes as $nodeId => $node) { + $this->inspectObject($node); // Check for duplicates by comparing node content except for 'id' $isDuplicate = false; foreach ($moduleNodesBefore as $existingNodeId => $existingNode) { @@ -134,6 +135,23 @@ private function reportAddedNodesWithDuplicateCheck($afterFile, $addedNodes, $mo } } + private function inspectObject($object) + { + $reflection = new \ReflectionClass($object); + $properties = $reflection->getProperties(); + $methods = $reflection->getMethods(); + + echo "\nProperties:\n"; + foreach ($properties as $property) { + echo $property->getName() . "\n"; + } + + echo "\nMethods:\n"; + foreach ($methods as $method) { + echo $method->getName() . "\n"; + } + } + /** * Check if node is duplicate or not * @@ -145,7 +163,7 @@ private function isDuplicateNode($node, $existingNode) { // Access the 'id' properties using possible getter methods //Testing file - + $nodeId = $this->getPrivateProperty($node, 'id'); $existingNodeId = $this->getPrivateProperty($existingNode, 'id'); From c8c6b179f296c23e7b9a798f20af382a66142fad Mon Sep 17 00:00:00 2001 From: Bhavin Parmar Date: Wed, 4 Sep 2024 18:09:11 +0530 Subject: [PATCH 05/55] AC-3483:: SVC false-positive: modifying system.xml file from another module --- src/Analyzer/SystemXml/Analyzer.php | 34 +++++++++++++++++++++-------- 1 file changed, 25 insertions(+), 9 deletions(-) diff --git a/src/Analyzer/SystemXml/Analyzer.php b/src/Analyzer/SystemXml/Analyzer.php index 593aca0e..69dff16d 100644 --- a/src/Analyzer/SystemXml/Analyzer.php +++ b/src/Analyzer/SystemXml/Analyzer.php @@ -161,18 +161,34 @@ private function inspectObject($object) */ private function isDuplicateNode($node, $existingNode) { - // Access the 'id' properties using possible getter methods - //Testing file + // Get node data excluding 'id' and 'parent' for comparison + $nodeData = $this->getNodeData($node); + $existingNodeData = $this->getNodeData($existingNode); - $nodeId = $this->getPrivateProperty($node, 'id'); - $existingNodeId = $this->getPrivateProperty($existingNode, 'id'); + // Compare the remaining parts of the nodes + return $nodeData == $existingNodeData; + } + + private function getNodeData($node) + { + $data = []; - // Access 'parent' properties if needed, depending on your logic - $nodeParent = $this->getPrivateProperty($node, 'parent'); - $existingNodeParent = $this->getPrivateProperty($existingNode, 'parent'); + // Use reflection to get accessible properties + $reflection = new \ReflectionClass($node); + foreach ($reflection->getMethods() as $method) { + // Skip 'getId' and 'getParent' methods for comparison + if ($method->getName() === 'getId' || $method->getName() === 'getParent') { + continue; + } + + // Dynamically call the getter methods + if (strpos($method->getName(), 'get') === 0) { + $propertyName = lcfirst(str_replace('get', '', $method->getName())); + $data[$propertyName] = $method->invoke($node); + } + } - // Compare the nodes after ignoring 'id' - return $nodeParent == $existingNodeParent; + return $data; } /** From 3945b35ac7e69ef09f72ceaadbc4927b1317560c Mon Sep 17 00:00:00 2001 From: Bhavin Parmar Date: Wed, 4 Sep 2024 18:42:56 +0530 Subject: [PATCH 06/55] AC-3483:: SVC false-positive: modifying system.xml file from another module --- src/Analyzer/SystemXml/Analyzer.php | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/Analyzer/SystemXml/Analyzer.php b/src/Analyzer/SystemXml/Analyzer.php index 69dff16d..79e66ed3 100644 --- a/src/Analyzer/SystemXml/Analyzer.php +++ b/src/Analyzer/SystemXml/Analyzer.php @@ -121,18 +121,21 @@ public function analyze($registryBefore, $registryAfter) private function reportAddedNodesWithDuplicateCheck($afterFile, $addedNodes, $moduleNodesBefore) { print_r('Report Added Nodes function called.'); + $isDuplicate = false; + foreach ($addedNodes as $nodeId => $node) { $this->inspectObject($node); + // Check for duplicates by comparing node content except for 'id' - $isDuplicate = false; foreach ($moduleNodesBefore as $existingNodeId => $existingNode) { if ($this->isDuplicateNode($node, $existingNode)) { $isDuplicate = true; - break; + break 2; // Break out of both loops if a duplicate is found } } - return $isDuplicate; } + + return $isDuplicate; } private function inspectObject($object) From 9c2501063de19cb093b5914e8f7055002d90e5a3 Mon Sep 17 00:00:00 2001 From: Bhavin Parmar Date: Thu, 5 Sep 2024 13:07:03 +0530 Subject: [PATCH 07/55] AC-3483:: SVC false-positive: modifying system.xml file from another module --- src/Analyzer/SystemXml/Analyzer.php | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/Analyzer/SystemXml/Analyzer.php b/src/Analyzer/SystemXml/Analyzer.php index 79e66ed3..33bbd78a 100644 --- a/src/Analyzer/SystemXml/Analyzer.php +++ b/src/Analyzer/SystemXml/Analyzer.php @@ -126,6 +126,9 @@ private function reportAddedNodesWithDuplicateCheck($afterFile, $addedNodes, $mo foreach ($addedNodes as $nodeId => $node) { $this->inspectObject($node); + print_r('Modules node before in reportAddedNodesWithDuplicateCheck method'); + print_r($moduleNodesBefore); + // Check for duplicates by comparing node content except for 'id' foreach ($moduleNodesBefore as $existingNodeId => $existingNode) { if ($this->isDuplicateNode($node, $existingNode)) { @@ -134,6 +137,7 @@ private function reportAddedNodesWithDuplicateCheck($afterFile, $addedNodes, $mo } } } + print_r("Duplicate node values: $isDuplicate"); return $isDuplicate; } @@ -164,10 +168,15 @@ private function inspectObject($object) */ private function isDuplicateNode($node, $existingNode) { + print_r('\nis Duplicated node\n'); // Get node data excluding 'id' and 'parent' for comparison $nodeData = $this->getNodeData($node); $existingNodeData = $this->getNodeData($existingNode); + echo "\nnddata\n"; + print_r($nodeData); + echo "\nexisting node\n"; + print_r($existingNodeData); // Compare the remaining parts of the nodes return $nodeData == $existingNodeData; } From 0dcb74a852db27d2ecd6a9045d65da9dd466c8c2 Mon Sep 17 00:00:00 2001 From: Bhavin Parmar Date: Thu, 5 Sep 2024 16:04:57 +0530 Subject: [PATCH 08/55] AC-3483:: SVC false-positive: modifying system.xml file from another module --- src/Analyzer/SystemXml/Analyzer.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Analyzer/SystemXml/Analyzer.php b/src/Analyzer/SystemXml/Analyzer.php index 33bbd78a..090cd73d 100644 --- a/src/Analyzer/SystemXml/Analyzer.php +++ b/src/Analyzer/SystemXml/Analyzer.php @@ -126,7 +126,7 @@ private function reportAddedNodesWithDuplicateCheck($afterFile, $addedNodes, $mo foreach ($addedNodes as $nodeId => $node) { $this->inspectObject($node); - print_r('Modules node before in reportAddedNodesWithDuplicateCheck method'); + print_r('Modulesfsdfsfdsf node before in reportAddedNodesWithDuplicateCheck method'); print_r($moduleNodesBefore); // Check for duplicates by comparing node content except for 'id' From e5c1ea14911035ef584107d026ac2d8dbba52864 Mon Sep 17 00:00:00 2001 From: Bhavin Parmar Date: Fri, 6 Sep 2024 10:42:27 +0530 Subject: [PATCH 09/55] AC-3483:: SVC false-positive: modifying system.xml file from another module --- src/Analyzer/SystemXml/Analyzer.php | 88 ++++++++++++++++++----------- 1 file changed, 56 insertions(+), 32 deletions(-) diff --git a/src/Analyzer/SystemXml/Analyzer.php b/src/Analyzer/SystemXml/Analyzer.php index 090cd73d..bcca2a6b 100644 --- a/src/Analyzer/SystemXml/Analyzer.php +++ b/src/Analyzer/SystemXml/Analyzer.php @@ -98,7 +98,7 @@ public function analyze($registryBefore, $registryAfter) if ($addedNodes) { $afterFile = $registryAfter->mapping[XmlRegistry::NODES_KEY][$moduleName]; $duplicateNode = $this->reportAddedNodesWithDuplicateCheck($afterFile, $addedNodes, $moduleNodesBefore); - print_r('Duplicate node '.$duplicateNode.' found'); + print_r('Duplicate node ' . ($duplicateNode ? 'found' : 'not found')); print_r("After file ". $afterFile ); if ($duplicateNode) { $this->reportDuplicateNodes($afterFile, $addedNodes); @@ -126,9 +126,6 @@ private function reportAddedNodesWithDuplicateCheck($afterFile, $addedNodes, $mo foreach ($addedNodes as $nodeId => $node) { $this->inspectObject($node); - print_r('Modulesfsdfsfdsf node before in reportAddedNodesWithDuplicateCheck method'); - print_r($moduleNodesBefore); - // Check for duplicates by comparing node content except for 'id' foreach ($moduleNodesBefore as $existingNodeId => $existingNode) { if ($this->isDuplicateNode($node, $existingNode)) { @@ -150,12 +147,12 @@ private function inspectObject($object) echo "\nProperties:\n"; foreach ($properties as $property) { - echo $property->getName() . "\n"; + // echo $property->getName() . "\n"; } echo "\nMethods:\n"; foreach ($methods as $method) { - echo $method->getName() . "\n"; + // echo $method->getName() . "\n"; } } @@ -168,17 +165,61 @@ private function inspectObject($object) */ private function isDuplicateNode($node, $existingNode) { - print_r('\nis Duplicated node\n'); - // Get node data excluding 'id' and 'parent' for comparison - $nodeData = $this->getNodeData($node); + // Extract data from both nodes + $newNodeData = $this->getNodeData($node); $existingNodeData = $this->getNodeData($existingNode); + /* echo "\n New Node\n"; + print_r($newNodeData); + echo "\n~~~~~~~~~~~~~~~\n"; + echo "\n Existing Node\n"; + print_r($existingNodeData);*/ + // Remove 'id' from both nodes for comparison, including from the path + unset($newNodeData['id'], $existingNodeData['id']); + $newNodePath = $this->removeLastPart($newNodeData['path']); + $existingNodePath = $this->removeLastPart($existingNodeData['path']); + + // print_r($newNodeData()); + + // Set the modified paths without the 'id' + $newNodeData['path'] = $newNodePath; + $existingNodeData['path'] = $existingNodePath; + + // Compare the remaining data (skip source_model since it's not provided) + foreach ($newNodeData as $key => $newValue) { + if (isset($existingNodeData[$key])) { + $existingValue = $existingNodeData[$key]; + echo "\nNew Value".$newValue ." !== Existing Value". $existingValue."\n"; + if (trim($newValue) == trim($existingValue)) { + echo "\nCame in condition.\n"; + echo "Property '$key' does not match between nodes.\n"; + return true; + } + } else { + echo "Property '$key' missing in the existing node.\n"; + return false; + } + } - echo "\nnddata\n"; - print_r($nodeData); - echo "\nexisting node\n"; - print_r($existingNodeData); - // Compare the remaining parts of the nodes - return $nodeData == $existingNodeData; + // If all properties match (except 'id'), the nodes are duplicates + echo "Nodes are duplicates based on their content.\n"; + return false; + } + + /* private function getNodeData($node) + { + return [ + 'path' => $node->getPath(), + 'uniqueKey' => $node->getUniqueKey(), + // Add more properties to compare if available, but exclude 'source_model' + ]; + }*/ + + private function removeLastPart($path) + { + // Remove the last part of the path (usually the 'id') to compare node structure without it + $pathParts = explode('/', $path); + array_pop($pathParts); // Remove the last part + return implode('/', $pathParts); // Return the path without the 'id' } private function getNodeData($node) @@ -203,22 +244,6 @@ private function getNodeData($node) return $data; } - /** - * Simplifies the reflection to get property - * - * @param $object - * @param $propertyName - * @return mixed - * @throws \ReflectionException - */ - private function getPrivateProperty($object, $propertyName) - { - $reflection = new \ReflectionClass($object); - $property = $reflection->getProperty($propertyName); - $property->setAccessible(true); - return $property->getValue($object); - } - /** * Extracts the node from $registry as an associative array. * @@ -293,7 +318,6 @@ private function reportDuplicateNodes(string $file, array $nodes) { print_r('Duplicate Nodes switch case'); foreach ($nodes as $node) { - echo "
$node->getPath()
"; switch (true) { case $node instanceof Field: $this->report->add('system', new FieldDuplicated($file, $node->getPath())); From 66389c14f20c16e6f0e336f3cde755fe37d85526 Mon Sep 17 00:00:00 2001 From: Bhavin Parmar Date: Fri, 13 Sep 2024 15:20:49 +0530 Subject: [PATCH 10/55] AC-3483:: SVC false-positive: modifying system.xml file from another module --- src/Analyzer/SystemXml/Analyzer.php | 255 ++++++++++++++++++---------- 1 file changed, 165 insertions(+), 90 deletions(-) diff --git a/src/Analyzer/SystemXml/Analyzer.php b/src/Analyzer/SystemXml/Analyzer.php index bcca2a6b..7f1a8363 100644 --- a/src/Analyzer/SystemXml/Analyzer.php +++ b/src/Analyzer/SystemXml/Analyzer.php @@ -26,6 +26,7 @@ use PHPSemVerChecker\Registry\Registry; use PHPSemVerChecker\Report\Report; use Magento\SemanticVersionChecker\Operation\SystemXml\FieldDuplicated; +use RecursiveDirectoryIterator; /** * Analyzes system.xml files: @@ -82,7 +83,7 @@ public function analyze($registryBefore, $registryAfter) //process removed files $this->reportRemovedFiles($removedModules, $registryBefore); - + $duplicateNode = []; //process common files foreach ($commonModules as $moduleName) { $moduleNodesBefore = $nodesBefore[$moduleName]; @@ -93,13 +94,12 @@ public function analyze($registryBefore, $registryAfter) $beforeFile = $registryBefore->mapping[XmlRegistry::NODES_KEY][$moduleName]; $this->reportRemovedNodes($beforeFile, $removedNodes); } - print_r('Added Nodes'); - print_r($addedNodes); + if ($addedNodes) { $afterFile = $registryAfter->mapping[XmlRegistry::NODES_KEY][$moduleName]; - $duplicateNode = $this->reportAddedNodesWithDuplicateCheck($afterFile, $addedNodes, $moduleNodesBefore); - print_r('Duplicate node ' . ($duplicateNode ? 'found' : 'not found')); - print_r("After file ". $afterFile ); + $duplicateNode = $this->reportAddedNodesWithDuplicateCheck($afterFile, $addedNodes); + + print_r($duplicateNode); if ($duplicateNode) { $this->reportDuplicateNodes($afterFile, $addedNodes); } else { @@ -111,117 +111,148 @@ public function analyze($registryBefore, $registryAfter) } /** - * Check and Report duplicate nodes + * Get Magento Base directory from the path * - * @param $afterFile - * @param $addedNodes - * @param $moduleNodesBefore - * @return bool|void + * @param string $filePath + * @return string|null */ - private function reportAddedNodesWithDuplicateCheck($afterFile, $addedNodes, $moduleNodesBefore) + private function getBaseDir($filePath) { - print_r('Report Added Nodes function called.'); - $isDuplicate = false; - - foreach ($addedNodes as $nodeId => $node) { - $this->inspectObject($node); - - // Check for duplicates by comparing node content except for 'id' - foreach ($moduleNodesBefore as $existingNodeId => $existingNode) { - if ($this->isDuplicateNode($node, $existingNode)) { - $isDuplicate = true; - break 2; // Break out of both loops if a duplicate is found - } + $currentDir = dirname($filePath); + while ($currentDir !== '/' && $currentDir !== false) { + // Check if current directory contains files unique to Magento root + if (file_exists($currentDir . '/SECURITY.md')) { + return $currentDir; // Found the Magento base directory } + $currentDir = dirname($currentDir); } - print_r("Duplicate node values: $isDuplicate"); - - return $isDuplicate; + return null; } - private function inspectObject($object) + /** + * Search for system.xml files in both app/code and vendor directories, excluding the provided file. + * + * @param string $magentoBaseDir The base directory of Magento. + * @param string $excludeFile The file to exclude from the search. + * @return array An array of paths to system.xml files, excluding the specified file. + */ + private function searchSystemXmlFiles($magentoBaseDir, $excludeFile = null) { - $reflection = new \ReflectionClass($object); - $properties = $reflection->getProperties(); - $methods = $reflection->getMethods(); + $systemXmlFiles = []; + $directoryToSearch = [ + $magentoBaseDir.'/app/code' + ]; - echo "\nProperties:\n"; - foreach ($properties as $property) { - // echo $property->getName() . "\n"; + // Check if 'vendor' directory exists, and only add it if it does + if (is_dir($magentoBaseDir . '/vendor')) { + $directoriesToSearch[] = $magentoBaseDir . '/vendor'; } - - echo "\nMethods:\n"; - foreach ($methods as $method) { - // echo $method->getName() . "\n"; + foreach ($directoryToSearch as $directory) { + $iterator = new \RecursiveIteratorIterator(new RecursiveDirectoryIterator($directory)); + foreach ($iterator as $file) { + if ($file->getfileName() === 'system.xml') { + $filePath = $file->getRealPath(); + if ($filePath !== $excludeFile) { + $systemXmlFiles[] = $file->getRealPath(); + } + } + } } + return $systemXmlFiles; } /** - * Check if node is duplicate or not + * Check and Report duplicate nodes * - * @param $node - * @param $existingNode + * @param $afterFile + * @param $addedNodes + * @param $moduleNodesBefore * @return bool + * @throws \Exception */ - private function isDuplicateNode($node, $existingNode) + private function reportAddedNodesWithDuplicateCheck($afterFile, $addedNodes) { - // Extract data from both nodes - $newNodeData = $this->getNodeData($node); - $existingNodeData = $this->getNodeData($existingNode); - /* echo "\n New Node\n"; - print_r($newNodeData); - echo "\n~~~~~~~~~~~~~~~\n"; - echo "\n Existing Node\n"; - print_r($existingNodeData);*/ - // Remove 'id' from both nodes for comparison, including from the path - unset($newNodeData['id'], $existingNodeData['id']); - $newNodePath = $this->removeLastPart($newNodeData['path']); - $existingNodePath = $this->removeLastPart($existingNodeData['path']); - - // print_r($newNodeData()); - - // Set the modified paths without the 'id' - $newNodeData['path'] = $newNodePath; - $existingNodeData['path'] = $existingNodePath; - - // Compare the remaining data (skip source_model since it's not provided) - foreach ($newNodeData as $key => $newValue) { - if (isset($existingNodeData[$key])) { - $existingValue = $existingNodeData[$key]; - echo "\nNew Value".$newValue ." !== Existing Value". $existingValue."\n"; - if (trim($newValue) == trim($existingValue)) { - echo "\nCame in condition.\n"; - echo "Property '$key' does not match between nodes.\n"; - return true; - } + $baseDir = $this->getBaseDir($afterFile); + $hasDuplicate = false; + + foreach ($addedNodes as $nodeId => $node) { + $newNodeData = $this->getNodeData($node); + $nodePath = $newNodeData['path']; + + // Extract section, group, and fieldId with error handling + $extractedData = $this->extractSectionGroupField($nodePath); + + // var_dump($extractedData); + if ($extractedData === null) { + // Skip the node if its path is invalid + // echo "Skipping node with invalid path: $nodePath\n"; + continue; + } + + // Extract section, group, and fieldId + list($sectionId, $groupId, $fieldId) = $extractedData; + + + + // Call function to check if this field is duplicated in other system.xml files + $isDuplicated = $this->isDuplicatedFieldInXml($baseDir, $sectionId, $groupId, $fieldId, $afterFile); + + if ($isDuplicated) { + $hasDuplicate = true; + echo "\n\nDuplicate found for the field: $fieldId\n\n"; } else { - echo "Property '$key' missing in the existing node.\n"; - return false; + + $hasDuplicate = false; + echo "\n\nNo duplicates for the field: $fieldId\n"; } + + // $nodeIds = strrpos($newNodeData['path'],'/'); + + // Extract the substring after the last "/" + // if ($nodeIds !== false) { + // $fieldId = substr($newNodeData['path'], $nodeIds + 1); + // } + // echo "\nDuplicate $hasDuplicate for the\n"; + // echo "Checking for duplicates for Section: $sectionId, Group: $groupId, Field: $fieldId\n"; + + // return $hasDuplicate; } - // If all properties match (except 'id'), the nodes are duplicates - echo "Nodes are duplicates based on their content.\n"; - return false; + return $hasDuplicate; + + // return $this->isDuplicatedFieldInXml($baseDir, $fieldId, $afterFile); } - /* private function getNodeData($node) + /** + * Method to extract section, group and field from the Node + * + * @param $nodePath + * @return array|null + */ + private function extractSectionGroupField($nodePath) { - return [ - 'path' => $node->getPath(), - 'uniqueKey' => $node->getUniqueKey(), - // Add more properties to compare if available, but exclude 'source_model' - ]; - }*/ + $parts = explode('/', $nodePath); - private function removeLastPart($path) - { - // Remove the last part of the path (usually the 'id') to compare node structure without it - $pathParts = explode('/', $path); - array_pop($pathParts); // Remove the last part - return implode('/', $pathParts); // Return the path without the 'id' + if (count($parts) < 3) { + // Invalid path if there are fewer than 3 parts + return null; + } + + $sectionId = $parts[0]; + $groupId = $parts[1]; + $fieldId = $parts[2]; + + + return [$sectionId, $groupId, $fieldId]; } + /** + * Method to get Node Data using reflection class + * + * @param $node + * @return array + * @throws \ReflectionException + */ private function getNodeData($node) { $data = []; @@ -316,7 +347,6 @@ private function reportAddedNodes(string $file, array $nodes) */ private function reportDuplicateNodes(string $file, array $nodes) { - print_r('Duplicate Nodes switch case'); foreach ($nodes as $node) { switch (true) { case $node instanceof Field: @@ -365,4 +395,49 @@ private function reportRemovedNodes(string $file, array $nodes) } } } + + /** + * @param string|null $baseDir + * @param string $sectionId + * @param string $groupId + * @param string $fieldId + * @param string $afterFile + * @return array + * @throws \Exception + */ + private function isDuplicatedFieldInXml(?string $baseDir, string $sectionId, string $groupId, string $fieldId, string $afterFile): array + { + if ($baseDir) { + $systemXmlFiles = $this->searchSystemXmlFiles($baseDir, $afterFile); + + $result = []; + + + foreach ($systemXmlFiles as $systemXmlFile) { + $xmlContent = file_get_contents($systemXmlFile); + try { + $xml = new \SimpleXMLElement($xmlContent); + } catch (\Exception $e) { + echo "\nError parsing XML: " . $e->getMessage() . "\n"; + continue; // Skip this file if there's a parsing error + } + // Find nodes with the given field ID + // XPath to search for within a specific section and group + $fields = $xml->xpath("//section[@id='$sectionId']/group[@id='$groupId']/field[@id='$fieldId']"); + + + if (!empty($fields)) { + echo "\n\nFound match in: $systemXmlFile\n"; + $result[] = [ + 'status' => 'patch', + 'field' => $fieldId + ]; + // break ; + } + } + + } + + return $result; + } } From 3ff6933ef06bddef6ce32990d2c2d719468ce3d1 Mon Sep 17 00:00:00 2001 From: Bhavin Parmar Date: Mon, 16 Sep 2024 13:12:53 +0530 Subject: [PATCH 11/55] AC-3483:: SVC false-positive: modifying system.xml file from another module --- src/Analyzer/SystemXml/Analyzer.php | 121 +++++++++------------------- 1 file changed, 39 insertions(+), 82 deletions(-) diff --git a/src/Analyzer/SystemXml/Analyzer.php b/src/Analyzer/SystemXml/Analyzer.php index 7f1a8363..395aef48 100644 --- a/src/Analyzer/SystemXml/Analyzer.php +++ b/src/Analyzer/SystemXml/Analyzer.php @@ -83,7 +83,7 @@ public function analyze($registryBefore, $registryAfter) //process removed files $this->reportRemovedFiles($removedModules, $registryBefore); - $duplicateNode = []; + //process common files foreach ($commonModules as $moduleName) { $moduleNodesBefore = $nodesBefore[$moduleName]; @@ -97,13 +97,30 @@ public function analyze($registryBefore, $registryAfter) if ($addedNodes) { $afterFile = $registryAfter->mapping[XmlRegistry::NODES_KEY][$moduleName]; - $duplicateNode = $this->reportAddedNodesWithDuplicateCheck($afterFile, $addedNodes); + $baseDir = $this->getBaseDir($afterFile); + foreach ($addedNodes as $nodeId => $node) { + $newNodeData = $this->getNodeData($node); + $nodePath = $newNodeData['path']; + + // Extract section, group, and fieldId with error handling + $extractedData = $this->extractSectionGroupField($nodePath); + if ($extractedData === null) { + // Skip the node if its path is invalid + continue; + } - print_r($duplicateNode); - if ($duplicateNode) { - $this->reportDuplicateNodes($afterFile, $addedNodes); - } else { - $this->reportAddedNodes($afterFile, $addedNodes); + // Extract section, group, and fieldId + list($sectionId, $groupId, $fieldId) = $extractedData; + + // Call function to check if this field is duplicated in other system.xml files + $isDuplicated = $this->isDuplicatedFieldInXml($baseDir, $sectionId, $groupId, $fieldId, $afterFile); + foreach ($isDuplicated as $isDuplicatedItem) { + if ($isDuplicatedItem['status'] === 'duplicate') { + $this->reportDuplicateNodes($afterFile, [$nodeId => $node ]); + } else { + $this->reportAddedNodes($afterFile, [$nodeId => $node ]); + } + } } } } @@ -161,68 +178,6 @@ private function searchSystemXmlFiles($magentoBaseDir, $excludeFile = null) return $systemXmlFiles; } - /** - * Check and Report duplicate nodes - * - * @param $afterFile - * @param $addedNodes - * @param $moduleNodesBefore - * @return bool - * @throws \Exception - */ - private function reportAddedNodesWithDuplicateCheck($afterFile, $addedNodes) - { - $baseDir = $this->getBaseDir($afterFile); - $hasDuplicate = false; - - foreach ($addedNodes as $nodeId => $node) { - $newNodeData = $this->getNodeData($node); - $nodePath = $newNodeData['path']; - - // Extract section, group, and fieldId with error handling - $extractedData = $this->extractSectionGroupField($nodePath); - - // var_dump($extractedData); - if ($extractedData === null) { - // Skip the node if its path is invalid - // echo "Skipping node with invalid path: $nodePath\n"; - continue; - } - - // Extract section, group, and fieldId - list($sectionId, $groupId, $fieldId) = $extractedData; - - - - // Call function to check if this field is duplicated in other system.xml files - $isDuplicated = $this->isDuplicatedFieldInXml($baseDir, $sectionId, $groupId, $fieldId, $afterFile); - - if ($isDuplicated) { - $hasDuplicate = true; - echo "\n\nDuplicate found for the field: $fieldId\n\n"; - } else { - - $hasDuplicate = false; - echo "\n\nNo duplicates for the field: $fieldId\n"; - } - - // $nodeIds = strrpos($newNodeData['path'],'/'); - - // Extract the substring after the last "/" - // if ($nodeIds !== false) { - // $fieldId = substr($newNodeData['path'], $nodeIds + 1); - // } - // echo "\nDuplicate $hasDuplicate for the\n"; - // echo "Checking for duplicates for Section: $sectionId, Group: $groupId, Field: $fieldId\n"; - - // return $hasDuplicate; - } - - return $hasDuplicate; - - // return $this->isDuplicatedFieldInXml($baseDir, $fieldId, $afterFile); - } - /** * Method to extract section, group and field from the Node * @@ -405,39 +360,41 @@ private function reportRemovedNodes(string $file, array $nodes) * @return array * @throws \Exception */ - private function isDuplicatedFieldInXml(?string $baseDir, string $sectionId, string $groupId, string $fieldId, string $afterFile): array + private function isDuplicatedFieldInXml(?string $baseDir, string $sectionId, string $groupId, ?string $fieldId, string $afterFile): array { + $hasDuplicate = false; if ($baseDir) { $systemXmlFiles = $this->searchSystemXmlFiles($baseDir, $afterFile); $result = []; - foreach ($systemXmlFiles as $systemXmlFile) { $xmlContent = file_get_contents($systemXmlFile); try { $xml = new \SimpleXMLElement($xmlContent); } catch (\Exception $e) { - echo "\nError parsing XML: " . $e->getMessage() . "\n"; continue; // Skip this file if there's a parsing error } // Find nodes with the given field ID // XPath to search for within a specific section and group $fields = $xml->xpath("//section[@id='$sectionId']/group[@id='$groupId']/field[@id='$fieldId']"); - - if (!empty($fields)) { - echo "\n\nFound match in: $systemXmlFile\n"; - $result[] = [ - 'status' => 'patch', - 'field' => $fieldId - ]; - // break ; + $hasDuplicate = true; // Set the duplicate flag to true if a match is found + break; // Since we found a duplicate, we don't need to check further for this field } } - + if ($hasDuplicate) { + $result[] = [ + 'status' => 'duplicate', + 'field' => $fieldId + ]; + } else { + $result[] = [ + 'status' => 'minor', + 'field' => $fieldId + ]; + } } - return $result; } } From 663e241ab8404efb97983a44f3a25d52defc4013 Mon Sep 17 00:00:00 2001 From: Bhavin Parmar Date: Mon, 16 Sep 2024 18:32:01 +0530 Subject: [PATCH 12/55] AC-3483:: SVC false-positive: modifying system.xml file from another module --- src/Analyzer/SystemXml/Analyzer.php | 9 +++++---- .../{FieldDuplicated.php => DuplicateFieldAdded.php} | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) rename src/Operation/SystemXml/{FieldDuplicated.php => DuplicateFieldAdded.php} (91%) diff --git a/src/Analyzer/SystemXml/Analyzer.php b/src/Analyzer/SystemXml/Analyzer.php index 395aef48..25457304 100644 --- a/src/Analyzer/SystemXml/Analyzer.php +++ b/src/Analyzer/SystemXml/Analyzer.php @@ -25,7 +25,7 @@ use Magento\SemanticVersionChecker\Registry\XmlRegistry; use PHPSemVerChecker\Registry\Registry; use PHPSemVerChecker\Report\Report; -use Magento\SemanticVersionChecker\Operation\SystemXml\FieldDuplicated; +use Magento\SemanticVersionChecker\Operation\SystemXml\DuplicateFieldAdded; use RecursiveDirectoryIterator; /** @@ -153,7 +153,7 @@ private function getBaseDir($filePath) * @param string $excludeFile The file to exclude from the search. * @return array An array of paths to system.xml files, excluding the specified file. */ - private function searchSystemXmlFiles($magentoBaseDir, $excludeFile = null) + private function getSystemXmlFiles($magentoBaseDir, $excludeFile = null) { $systemXmlFiles = []; $directoryToSearch = [ @@ -305,7 +305,7 @@ private function reportDuplicateNodes(string $file, array $nodes) foreach ($nodes as $node) { switch (true) { case $node instanceof Field: - $this->report->add('system', new FieldDuplicated($file, $node->getPath())); + $this->report->add('system', new DuplicateFieldAdded($file, $node->getPath())); break; default: } @@ -363,8 +363,9 @@ private function reportRemovedNodes(string $file, array $nodes) private function isDuplicatedFieldInXml(?string $baseDir, string $sectionId, string $groupId, ?string $fieldId, string $afterFile): array { $hasDuplicate = false; + if ($baseDir) { - $systemXmlFiles = $this->searchSystemXmlFiles($baseDir, $afterFile); + $systemXmlFiles = $this->getSystemXmlFiles($baseDir, $afterFile); $result = []; diff --git a/src/Operation/SystemXml/FieldDuplicated.php b/src/Operation/SystemXml/DuplicateFieldAdded.php similarity index 91% rename from src/Operation/SystemXml/FieldDuplicated.php rename to src/Operation/SystemXml/DuplicateFieldAdded.php index 6ce47bdf..8424574e 100644 --- a/src/Operation/SystemXml/FieldDuplicated.php +++ b/src/Operation/SystemXml/DuplicateFieldAdded.php @@ -15,7 +15,7 @@ /** * When a field node is added. */ -class FieldDuplicated extends AbstractOperation +class DuplicateFieldAdded extends AbstractOperation { /** * @var string From 162e923405afe29a516b673984ce89e523508740 Mon Sep 17 00:00:00 2001 From: Bhavin Parmar Date: Mon, 30 Sep 2024 16:06:03 +0530 Subject: [PATCH 13/55] AC-3483:: SVC false-positive: modifying system.xml file from another module --- src/Analyzer/SystemXml/Analyzer.php | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/Analyzer/SystemXml/Analyzer.php b/src/Analyzer/SystemXml/Analyzer.php index 25457304..b82b828c 100644 --- a/src/Analyzer/SystemXml/Analyzer.php +++ b/src/Analyzer/SystemXml/Analyzer.php @@ -114,6 +114,7 @@ public function analyze($registryBefore, $registryAfter) // Call function to check if this field is duplicated in other system.xml files $isDuplicated = $this->isDuplicatedFieldInXml($baseDir, $sectionId, $groupId, $fieldId, $afterFile); + foreach ($isDuplicated as $isDuplicatedItem) { if ($isDuplicatedItem['status'] === 'duplicate') { $this->reportDuplicateNodes($afterFile, [$nodeId => $node ]); @@ -197,7 +198,6 @@ private function extractSectionGroupField($nodePath) $groupId = $parts[1]; $fieldId = $parts[2]; - return [$sectionId, $groupId, $fieldId]; } @@ -307,7 +307,6 @@ private function reportDuplicateNodes(string $file, array $nodes) case $node instanceof Field: $this->report->add('system', new DuplicateFieldAdded($file, $node->getPath())); break; - default: } } } @@ -364,11 +363,14 @@ private function isDuplicatedFieldInXml(?string $baseDir, string $sectionId, str { $hasDuplicate = false; + $result = [ + 'status' => 'minor', + 'field' => $fieldId + ]; + if ($baseDir) { $systemXmlFiles = $this->getSystemXmlFiles($baseDir, $afterFile); - $result = []; - foreach ($systemXmlFiles as $systemXmlFile) { $xmlContent = file_get_contents($systemXmlFile); try { @@ -385,17 +387,15 @@ private function isDuplicatedFieldInXml(?string $baseDir, string $sectionId, str } } if ($hasDuplicate) { - $result[] = [ - 'status' => 'duplicate', - 'field' => $fieldId - ]; - } else { - $result[] = [ - 'status' => 'minor', - 'field' => $fieldId + return [ + [ + 'status' => 'duplicate', + 'field' => $fieldId + + ] ]; } } - return $result; + return [$result]; } } From e73049d00162e32dfef22708cc80e562f5ca93bc Mon Sep 17 00:00:00 2001 From: Bhavin Parmar Date: Tue, 8 Oct 2024 18:01:29 +0530 Subject: [PATCH 14/55] AC-3483:: SVC false-positive: modifying system.xml file from another module --- src/Analyzer/SystemXml/Analyzer.php | 44 ++++++++++++++++------------- 1 file changed, 24 insertions(+), 20 deletions(-) diff --git a/src/Analyzer/SystemXml/Analyzer.php b/src/Analyzer/SystemXml/Analyzer.php index b82b828c..8b6b123a 100644 --- a/src/Analyzer/SystemXml/Analyzer.php +++ b/src/Analyzer/SystemXml/Analyzer.php @@ -97,29 +97,33 @@ public function analyze($registryBefore, $registryAfter) if ($addedNodes) { $afterFile = $registryAfter->mapping[XmlRegistry::NODES_KEY][$moduleName]; - $baseDir = $this->getBaseDir($afterFile); - foreach ($addedNodes as $nodeId => $node) { - $newNodeData = $this->getNodeData($node); - $nodePath = $newNodeData['path']; - - // Extract section, group, and fieldId with error handling - $extractedData = $this->extractSectionGroupField($nodePath); - if ($extractedData === null) { - // Skip the node if its path is invalid - continue; - } + if (strpos($afterFile, '_files') !== false) { + $this->reportAddedNodes($afterFile,$addedNodes); + } else { + $baseDir = $this->getBaseDir($afterFile); + foreach ($addedNodes as $nodeId => $node) { + $newNodeData = $this->getNodeData($node); + $nodePath = $newNodeData['path']; + + // Extract section, group, and fieldId with error handling + $extractedData = $this->extractSectionGroupField($nodePath); + if ($extractedData === null) { + // Skip the node if its path is invalid + continue; + } - // Extract section, group, and fieldId - list($sectionId, $groupId, $fieldId) = $extractedData; + // Extract section, group, and fieldId + list($sectionId, $groupId, $fieldId) = $extractedData; - // Call function to check if this field is duplicated in other system.xml files - $isDuplicated = $this->isDuplicatedFieldInXml($baseDir, $sectionId, $groupId, $fieldId, $afterFile); + // Call function to check if this field is duplicated in other system.xml files + $isDuplicated = $this->isDuplicatedFieldInXml($baseDir, $sectionId, $groupId, $fieldId, $afterFile); - foreach ($isDuplicated as $isDuplicatedItem) { - if ($isDuplicatedItem['status'] === 'duplicate') { - $this->reportDuplicateNodes($afterFile, [$nodeId => $node ]); - } else { - $this->reportAddedNodes($afterFile, [$nodeId => $node ]); + foreach ($isDuplicated as $isDuplicatedItem) { + if ($isDuplicatedItem['status'] === 'duplicate') { + $this->reportDuplicateNodes($afterFile, [$nodeId => $node]); + } else { + $this->reportAddedNodes($afterFile, [$nodeId => $node]); + } } } } From fea14fe0c5dee99bb238b0598e9429a704c58c91 Mon Sep 17 00:00:00 2001 From: Bhavin Parmar Date: Tue, 8 Oct 2024 18:17:02 +0530 Subject: [PATCH 15/55] AC-3483:: SVC false-positive: modifying system.xml file from another module --- src/Analyzer/SystemXml/Analyzer.php | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/src/Analyzer/SystemXml/Analyzer.php b/src/Analyzer/SystemXml/Analyzer.php index 8b6b123a..d729144a 100644 --- a/src/Analyzer/SystemXml/Analyzer.php +++ b/src/Analyzer/SystemXml/Analyzer.php @@ -98,7 +98,7 @@ public function analyze($registryBefore, $registryAfter) if ($addedNodes) { $afterFile = $registryAfter->mapping[XmlRegistry::NODES_KEY][$moduleName]; if (strpos($afterFile, '_files') !== false) { - $this->reportAddedNodes($afterFile,$addedNodes); + $this->reportAddedNodes($afterFile, $addedNodes); } else { $baseDir = $this->getBaseDir($afterFile); foreach ($addedNodes as $nodeId => $node) { @@ -116,7 +116,13 @@ public function analyze($registryBefore, $registryAfter) list($sectionId, $groupId, $fieldId) = $extractedData; // Call function to check if this field is duplicated in other system.xml files - $isDuplicated = $this->isDuplicatedFieldInXml($baseDir, $sectionId, $groupId, $fieldId, $afterFile); + $isDuplicated = $this->isDuplicatedFieldInXml( + $baseDir, + $sectionId, + $groupId, + $fieldId, + $afterFile + ); foreach ($isDuplicated as $isDuplicatedItem) { if ($isDuplicatedItem['status'] === 'duplicate') { @@ -162,7 +168,7 @@ private function getSystemXmlFiles($magentoBaseDir, $excludeFile = null) { $systemXmlFiles = []; $directoryToSearch = [ - $magentoBaseDir.'/app/code' + $magentoBaseDir . '/app/code' ]; // Check if 'vendor' directory exists, and only add it if it does @@ -363,8 +369,13 @@ private function reportRemovedNodes(string $file, array $nodes) * @return array * @throws \Exception */ - private function isDuplicatedFieldInXml(?string $baseDir, string $sectionId, string $groupId, ?string $fieldId, string $afterFile): array - { + private function isDuplicatedFieldInXml( + ?string $baseDir, + string $sectionId, + string $groupId, + ?string $fieldId, + string $afterFile + ): array { $hasDuplicate = false; $result = [ From 15dd156b89afa0cfc93e23f6f28fa9870bb18dab Mon Sep 17 00:00:00 2001 From: Bhavin Parmar Date: Wed, 16 Oct 2024 12:59:50 +0530 Subject: [PATCH 16/55] AC-3483:: SVC false-positive: modifying system.xml file from another module --- src/Analyzer/SystemXml/Analyzer.php | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/Analyzer/SystemXml/Analyzer.php b/src/Analyzer/SystemXml/Analyzer.php index d729144a..b2b26168 100644 --- a/src/Analyzer/SystemXml/Analyzer.php +++ b/src/Analyzer/SystemXml/Analyzer.php @@ -164,7 +164,7 @@ private function getBaseDir($filePath) * @param string $excludeFile The file to exclude from the search. * @return array An array of paths to system.xml files, excluding the specified file. */ - private function getSystemXmlFiles($magentoBaseDir, $excludeFile = null) + private function getSystemXmlFiles($magentoBaseDir, $excludeFile = null): array { $systemXmlFiles = []; $directoryToSearch = [ @@ -195,7 +195,7 @@ private function getSystemXmlFiles($magentoBaseDir, $excludeFile = null) * @param $nodePath * @return array|null */ - private function extractSectionGroupField($nodePath) + private function extractSectionGroupField($nodePath): ?array { $parts = explode('/', $nodePath); @@ -218,7 +218,7 @@ private function extractSectionGroupField($nodePath) * @return array * @throws \ReflectionException */ - private function getNodeData($node) + private function getNodeData($node): array { $data = []; @@ -406,7 +406,6 @@ private function isDuplicatedFieldInXml( [ 'status' => 'duplicate', 'field' => $fieldId - ] ]; } From 2b16c36146a019eb28d65800b2bb81241606a9c4 Mon Sep 17 00:00:00 2001 From: Bhavin Parmar Date: Thu, 17 Oct 2024 16:00:05 +0530 Subject: [PATCH 17/55] AC-3483:: SVC false-positive: modifying system.xml file from another module --- src/Analyzer/SystemXml/Analyzer.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Analyzer/SystemXml/Analyzer.php b/src/Analyzer/SystemXml/Analyzer.php index b2b26168..a670bb34 100644 --- a/src/Analyzer/SystemXml/Analyzer.php +++ b/src/Analyzer/SystemXml/Analyzer.php @@ -309,8 +309,9 @@ private function reportAddedNodes(string $file, array $nodes) * * @param string $file * @param NodeInterface[] $nodes + * @return void */ - private function reportDuplicateNodes(string $file, array $nodes) + private function reportDuplicateNodes(string $file, array $nodes): void { foreach ($nodes as $node) { switch (true) { From 4f226f39361901225ba3251aa5551006ed54ac97 Mon Sep 17 00:00:00 2001 From: Bhavin Parmar Date: Wed, 20 Nov 2024 16:53:57 +0530 Subject: [PATCH 18/55] AC-13346: Deprecation of E_STRICT constant in PHP 8.4 --- dev/tests/Unit/bootstrap.php | 1 - 1 file changed, 1 deletion(-) diff --git a/dev/tests/Unit/bootstrap.php b/dev/tests/Unit/bootstrap.php index 0481b696..e5c95dd5 100644 --- a/dev/tests/Unit/bootstrap.php +++ b/dev/tests/Unit/bootstrap.php @@ -37,7 +37,6 @@ function ($errNo, $errStr, $errFile, $errLine) { E_USER_ERROR => 'User Error', E_USER_WARNING => 'User Warning', E_USER_NOTICE => 'User Notice', - E_STRICT => 'Strict', E_RECOVERABLE_ERROR => 'Recoverable Error', E_DEPRECATED => 'Deprecated', E_USER_DEPRECATED => 'User Deprecated', From 59d2251dcebcd76ff292888ac910f83ac2033628 Mon Sep 17 00:00:00 2001 From: Rajesh Kumar Date: Thu, 5 Dec 2024 15:32:43 +0530 Subject: [PATCH 19/55] AC-13306::Adobe Commerce 2.4.8 core code is compatible with PHP 8.4 --- composer.json | 2 +- composer.lock | 323 +++++++++++++++++++++++++------------------------- 2 files changed, 164 insertions(+), 161 deletions(-) diff --git a/composer.json b/composer.json index 0baa4051..e5c9c52f 100644 --- a/composer.json +++ b/composer.json @@ -8,7 +8,7 @@ ], "bin": ["bin/svc"], "require": { - "php": "~8.1.0||~8.2.0||~8.3.0", + "php": "~8.1.0||~8.2.0||~8.3.0||~8.4.0", "ext-json": "*", "laminas/laminas-stdlib": "^3.18", "nikic/php-parser": "^4.15", diff --git a/composer.lock b/composer.lock index 1bce5fca..d97f6e3f 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "33ac8c8057e26605bdd59f9d6162b506", + "content-hash": "fef25ea90a323b619f8947668fa74553", "packages": [ { "name": "hassankhan/config", @@ -70,30 +70,30 @@ }, { "name": "laminas/laminas-stdlib", - "version": "3.19.0", + "version": "3.20.0", "source": { "type": "git", "url": "https://github.com/laminas/laminas-stdlib.git", - "reference": "6a192dd0882b514e45506f533b833b623b78fff3" + "reference": "8974a1213be42c3e2f70b2c27b17f910291ab2f4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laminas/laminas-stdlib/zipball/6a192dd0882b514e45506f533b833b623b78fff3", - "reference": "6a192dd0882b514e45506f533b833b623b78fff3", + "url": "https://api.github.com/repos/laminas/laminas-stdlib/zipball/8974a1213be42c3e2f70b2c27b17f910291ab2f4", + "reference": "8974a1213be42c3e2f70b2c27b17f910291ab2f4", "shasum": "" }, "require": { - "php": "~8.1.0 || ~8.2.0 || ~8.3.0" + "php": "~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0" }, "conflict": { "zendframework/zend-stdlib": "*" }, "require-dev": { - "laminas/laminas-coding-standard": "^2.5", - "phpbench/phpbench": "^1.2.15", - "phpunit/phpunit": "^10.5.8", - "psalm/plugin-phpunit": "^0.18.4", - "vimeo/psalm": "^5.20.0" + "laminas/laminas-coding-standard": "^3.0", + "phpbench/phpbench": "^1.3.1", + "phpunit/phpunit": "^10.5.38", + "psalm/plugin-phpunit": "^0.19.0", + "vimeo/psalm": "^5.26.1" }, "type": "library", "autoload": { @@ -125,20 +125,20 @@ "type": "community_bridge" } ], - "time": "2024-01-19T12:39:49+00:00" + "time": "2024-10-29T13:46:07+00:00" }, { "name": "nikic/php-parser", - "version": "v4.19.1", + "version": "v4.19.4", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "4e1b88d21c69391150ace211e9eaf05810858d0b" + "reference": "715f4d25e225bc47b293a8b997fe6ce99bf987d2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/4e1b88d21c69391150ace211e9eaf05810858d0b", - "reference": "4e1b88d21c69391150ace211e9eaf05810858d0b", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/715f4d25e225bc47b293a8b997fe6ce99bf987d2", + "reference": "715f4d25e225bc47b293a8b997fe6ce99bf987d2", "shasum": "" }, "require": { @@ -147,7 +147,7 @@ }, "require-dev": { "ircmaxell/php-yacc": "^0.0.7", - "phpunit/phpunit": "^6.5 || ^7.0 || ^8.0 || ^9.0" + "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0" }, "bin": [ "bin/php-parse" @@ -179,9 +179,9 @@ ], "support": { "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v4.19.1" + "source": "https://github.com/nikic/PHP-Parser/tree/v4.19.4" }, - "time": "2024-03-17T08:10:35+00:00" + "time": "2024-09-29T15:01:53+00:00" }, { "name": "phpstan/phpdoc-parser", @@ -287,27 +287,27 @@ }, { "name": "sabre/uri", - "version": "2.3.3", + "version": "2.3.4", "source": { "type": "git", "url": "https://github.com/sabre-io/uri.git", - "reference": "7e0e7dfd0b7e14346a27eabd66e843a6e7f1812b" + "reference": "b76524c22de90d80ca73143680a8e77b1266c291" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sabre-io/uri/zipball/7e0e7dfd0b7e14346a27eabd66e843a6e7f1812b", - "reference": "7e0e7dfd0b7e14346a27eabd66e843a6e7f1812b", + "url": "https://api.github.com/repos/sabre-io/uri/zipball/b76524c22de90d80ca73143680a8e77b1266c291", + "reference": "b76524c22de90d80ca73143680a8e77b1266c291", "shasum": "" }, "require": { "php": "^7.4 || ^8.0" }, "require-dev": { - "friendsofphp/php-cs-fixer": "^3.17", - "phpstan/extension-installer": "^1.3", - "phpstan/phpstan": "^1.10", - "phpstan/phpstan-phpunit": "^1.3", - "phpstan/phpstan-strict-rules": "^1.5", + "friendsofphp/php-cs-fixer": "^3.63", + "phpstan/extension-installer": "^1.4", + "phpstan/phpstan": "^1.12", + "phpstan/phpstan-phpunit": "^1.4", + "phpstan/phpstan-strict-rules": "^1.6", "phpunit/phpunit": "^9.6" }, "type": "library", @@ -343,20 +343,20 @@ "issues": "https://github.com/sabre-io/uri/issues", "source": "https://github.com/fruux/sabre-uri" }, - "time": "2023-06-09T06:54:04+00:00" + "time": "2024-08-27T12:18:16+00:00" }, { "name": "sabre/xml", - "version": "2.2.6", + "version": "2.2.11", "source": { "type": "git", "url": "https://github.com/sabre-io/xml.git", - "reference": "9cde7cdab1e50893cc83b037b40cd47bfde42a2b" + "reference": "01a7927842abf3e10df3d9c2d9b0cc9d813a3fcc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sabre-io/xml/zipball/9cde7cdab1e50893cc83b037b40cd47bfde42a2b", - "reference": "9cde7cdab1e50893cc83b037b40cd47bfde42a2b", + "url": "https://api.github.com/repos/sabre-io/xml/zipball/01a7927842abf3e10df3d9c2d9b0cc9d813a3fcc", + "reference": "01a7927842abf3e10df3d9c2d9b0cc9d813a3fcc", "shasum": "" }, "require": { @@ -368,9 +368,9 @@ "sabre/uri": ">=1.0,<3.0.0" }, "require-dev": { - "friendsofphp/php-cs-fixer": "~2.17.1", + "friendsofphp/php-cs-fixer": "~2.17.1||3.63.2", "phpstan/phpstan": "^0.12", - "phpunit/phpunit": "^7.5 || ^8.5 || ^9.0" + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.6" }, "type": "library", "autoload": { @@ -412,20 +412,20 @@ "issues": "https://github.com/sabre-io/xml/issues", "source": "https://github.com/fruux/sabre-xml" }, - "time": "2023-06-28T12:56:05+00:00" + "time": "2024-09-06T07:37:46+00:00" }, { "name": "symfony/console", - "version": "v6.4.3", + "version": "v6.4.15", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "2aaf83b4de5b9d43b93e4aec6f2f8b676f7c567e" + "reference": "f1fc6f47283e27336e7cebb9e8946c8de7bff9bd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/2aaf83b4de5b9d43b93e4aec6f2f8b676f7c567e", - "reference": "2aaf83b4de5b9d43b93e4aec6f2f8b676f7c567e", + "url": "https://api.github.com/repos/symfony/console/zipball/f1fc6f47283e27336e7cebb9e8946c8de7bff9bd", + "reference": "f1fc6f47283e27336e7cebb9e8946c8de7bff9bd", "shasum": "" }, "require": { @@ -490,7 +490,7 @@ "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v6.4.3" + "source": "https://github.com/symfony/console/tree/v6.4.15" }, "funding": [ { @@ -506,20 +506,20 @@ "type": "tidelift" } ], - "time": "2024-01-23T14:51:35+00:00" + "time": "2024-11-06T14:19:14+00:00" }, { "name": "symfony/deprecation-contracts", - "version": "v3.4.0", + "version": "v3.5.1", "source": { "type": "git", "url": "https://github.com/symfony/deprecation-contracts.git", - "reference": "7c3aff79d10325257a001fcf92d991f24fc967cf" + "reference": "74c71c939a79f7d5bf3c1ce9f5ea37ba0114c6f6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/7c3aff79d10325257a001fcf92d991f24fc967cf", - "reference": "7c3aff79d10325257a001fcf92d991f24fc967cf", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/74c71c939a79f7d5bf3c1ce9f5ea37ba0114c6f6", + "reference": "74c71c939a79f7d5bf3c1ce9f5ea37ba0114c6f6", "shasum": "" }, "require": { @@ -528,7 +528,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "3.4-dev" + "dev-main": "3.5-dev" }, "thanks": { "name": "symfony/contracts", @@ -557,7 +557,7 @@ "description": "A generic function and convention to trigger deprecation notices", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/deprecation-contracts/tree/v3.4.0" + "source": "https://github.com/symfony/deprecation-contracts/tree/v3.5.1" }, "funding": [ { @@ -573,24 +573,24 @@ "type": "tidelift" } ], - "time": "2023-05-23T14:45:45+00:00" + "time": "2024-09-25T14:20:29+00:00" }, { "name": "symfony/polyfill-ctype", - "version": "v1.29.0", + "version": "v1.31.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "ef4d7e442ca910c4764bce785146269b30cb5fc4" + "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/ef4d7e442ca910c4764bce785146269b30cb5fc4", - "reference": "ef4d7e442ca910c4764bce785146269b30cb5fc4", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/a3cc8b044a6ea513310cbd48ef7333b384945638", + "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=7.2" }, "provide": { "ext-ctype": "*" @@ -636,7 +636,7 @@ "portable" ], "support": { - "source": "https://github.com/symfony/polyfill-ctype/tree/v1.29.0" + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.31.0" }, "funding": [ { @@ -652,24 +652,24 @@ "type": "tidelift" } ], - "time": "2024-01-29T20:11:03+00:00" + "time": "2024-09-09T11:45:10+00:00" }, { "name": "symfony/polyfill-intl-grapheme", - "version": "v1.29.0", + "version": "v1.31.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-grapheme.git", - "reference": "32a9da87d7b3245e09ac426c83d334ae9f06f80f" + "reference": "b9123926e3b7bc2f98c02ad54f6a4b02b91a8abe" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/32a9da87d7b3245e09ac426c83d334ae9f06f80f", - "reference": "32a9da87d7b3245e09ac426c83d334ae9f06f80f", + "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/b9123926e3b7bc2f98c02ad54f6a4b02b91a8abe", + "reference": "b9123926e3b7bc2f98c02ad54f6a4b02b91a8abe", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=7.2" }, "suggest": { "ext-intl": "For best performance" @@ -714,7 +714,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.29.0" + "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.31.0" }, "funding": [ { @@ -730,24 +730,24 @@ "type": "tidelift" } ], - "time": "2024-01-29T20:11:03+00:00" + "time": "2024-09-09T11:45:10+00:00" }, { "name": "symfony/polyfill-intl-normalizer", - "version": "v1.29.0", + "version": "v1.31.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-normalizer.git", - "reference": "bc45c394692b948b4d383a08d7753968bed9a83d" + "reference": "3833d7255cc303546435cb650316bff708a1c75c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/bc45c394692b948b4d383a08d7753968bed9a83d", - "reference": "bc45c394692b948b4d383a08d7753968bed9a83d", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/3833d7255cc303546435cb650316bff708a1c75c", + "reference": "3833d7255cc303546435cb650316bff708a1c75c", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=7.2" }, "suggest": { "ext-intl": "For best performance" @@ -795,7 +795,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.29.0" + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.31.0" }, "funding": [ { @@ -811,24 +811,24 @@ "type": "tidelift" } ], - "time": "2024-01-29T20:11:03+00:00" + "time": "2024-09-09T11:45:10+00:00" }, { "name": "symfony/polyfill-mbstring", - "version": "v1.29.0", + "version": "v1.31.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "9773676c8a1bb1f8d4340a62efe641cf76eda7ec" + "reference": "85181ba99b2345b0ef10ce42ecac37612d9fd341" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/9773676c8a1bb1f8d4340a62efe641cf76eda7ec", - "reference": "9773676c8a1bb1f8d4340a62efe641cf76eda7ec", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/85181ba99b2345b0ef10ce42ecac37612d9fd341", + "reference": "85181ba99b2345b0ef10ce42ecac37612d9fd341", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=7.2" }, "provide": { "ext-mbstring": "*" @@ -875,7 +875,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.29.0" + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.31.0" }, "funding": [ { @@ -891,25 +891,26 @@ "type": "tidelift" } ], - "time": "2024-01-29T20:11:03+00:00" + "time": "2024-09-09T11:45:10+00:00" }, { "name": "symfony/service-contracts", - "version": "v3.4.1", + "version": "v3.5.1", "source": { "type": "git", "url": "https://github.com/symfony/service-contracts.git", - "reference": "fe07cbc8d837f60caf7018068e350cc5163681a0" + "reference": "e53260aabf78fb3d63f8d79d69ece59f80d5eda0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/service-contracts/zipball/fe07cbc8d837f60caf7018068e350cc5163681a0", - "reference": "fe07cbc8d837f60caf7018068e350cc5163681a0", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/e53260aabf78fb3d63f8d79d69ece59f80d5eda0", + "reference": "e53260aabf78fb3d63f8d79d69ece59f80d5eda0", "shasum": "" }, "require": { "php": ">=8.1", - "psr/container": "^1.1|^2.0" + "psr/container": "^1.1|^2.0", + "symfony/deprecation-contracts": "^2.5|^3" }, "conflict": { "ext-psr": "<1.1|>=2" @@ -917,7 +918,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "3.4-dev" + "dev-main": "3.5-dev" }, "thanks": { "name": "symfony/contracts", @@ -957,7 +958,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/service-contracts/tree/v3.4.1" + "source": "https://github.com/symfony/service-contracts/tree/v3.5.1" }, "funding": [ { @@ -973,24 +974,24 @@ "type": "tidelift" } ], - "time": "2023-12-26T14:02:43+00:00" + "time": "2024-09-25T14:20:29+00:00" }, { "name": "symfony/string", - "version": "v6.4.3", + "version": "v7.2.0", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "7a14736fb179876575464e4658fce0c304e8c15b" + "reference": "446e0d146f991dde3e73f45f2c97a9faad773c82" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/7a14736fb179876575464e4658fce0c304e8c15b", - "reference": "7a14736fb179876575464e4658fce0c304e8c15b", + "url": "https://api.github.com/repos/symfony/string/zipball/446e0d146f991dde3e73f45f2c97a9faad773c82", + "reference": "446e0d146f991dde3e73f45f2c97a9faad773c82", "shasum": "" }, "require": { - "php": ">=8.1", + "php": ">=8.2", "symfony/polyfill-ctype": "~1.8", "symfony/polyfill-intl-grapheme": "~1.0", "symfony/polyfill-intl-normalizer": "~1.0", @@ -1000,11 +1001,12 @@ "symfony/translation-contracts": "<2.5" }, "require-dev": { - "symfony/error-handler": "^5.4|^6.0|^7.0", - "symfony/http-client": "^5.4|^6.0|^7.0", - "symfony/intl": "^6.2|^7.0", + "symfony/emoji": "^7.1", + "symfony/error-handler": "^6.4|^7.0", + "symfony/http-client": "^6.4|^7.0", + "symfony/intl": "^6.4|^7.0", "symfony/translation-contracts": "^2.5|^3.0", - "symfony/var-exporter": "^5.4|^6.0|^7.0" + "symfony/var-exporter": "^6.4|^7.0" }, "type": "library", "autoload": { @@ -1043,7 +1045,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v6.4.3" + "source": "https://github.com/symfony/string/tree/v7.2.0" }, "funding": [ { @@ -1059,20 +1061,20 @@ "type": "tidelift" } ], - "time": "2024-01-25T09:26:29+00:00" + "time": "2024-11-13T13:31:26+00:00" }, { "name": "symfony/yaml", - "version": "v6.4.3", + "version": "v6.4.13", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "d75715985f0f94f978e3a8fa42533e10db921b90" + "reference": "e99b4e94d124b29ee4cf3140e1b537d2dad8cec9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/d75715985f0f94f978e3a8fa42533e10db921b90", - "reference": "d75715985f0f94f978e3a8fa42533e10db921b90", + "url": "https://api.github.com/repos/symfony/yaml/zipball/e99b4e94d124b29ee4cf3140e1b537d2dad8cec9", + "reference": "e99b4e94d124b29ee4cf3140e1b537d2dad8cec9", "shasum": "" }, "require": { @@ -1115,7 +1117,7 @@ "description": "Loads and dumps YAML files", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/yaml/tree/v6.4.3" + "source": "https://github.com/symfony/yaml/tree/v6.4.13" }, "funding": [ { @@ -1131,7 +1133,7 @@ "type": "tidelift" } ], - "time": "2024-01-23T14:51:35+00:00" + "time": "2024-09-25T14:18:03+00:00" }, { "name": "tomzx/finder", @@ -1329,16 +1331,16 @@ "packages-dev": [ { "name": "myclabs/deep-copy", - "version": "1.11.1", + "version": "1.12.1", "source": { "type": "git", "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "7284c22080590fb39f2ffa3e9057f10a4ddd0e0c" + "reference": "123267b2c49fbf30d78a7b2d333f6be754b94845" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/7284c22080590fb39f2ffa3e9057f10a4ddd0e0c", - "reference": "7284c22080590fb39f2ffa3e9057f10a4ddd0e0c", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/123267b2c49fbf30d78a7b2d333f6be754b94845", + "reference": "123267b2c49fbf30d78a7b2d333f6be754b94845", "shasum": "" }, "require": { @@ -1346,11 +1348,12 @@ }, "conflict": { "doctrine/collections": "<1.6.8", - "doctrine/common": "<2.13.3 || >=3,<3.2.2" + "doctrine/common": "<2.13.3 || >=3 <3.2.2" }, "require-dev": { "doctrine/collections": "^1.6.8", "doctrine/common": "^2.13.3 || ^3.2.2", + "phpspec/prophecy": "^1.10", "phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13" }, "type": "library", @@ -1376,7 +1379,7 @@ ], "support": { "issues": "https://github.com/myclabs/DeepCopy/issues", - "source": "https://github.com/myclabs/DeepCopy/tree/1.11.1" + "source": "https://github.com/myclabs/DeepCopy/tree/1.12.1" }, "funding": [ { @@ -1384,7 +1387,7 @@ "type": "tidelift" } ], - "time": "2023-03-08T13:26:56+00:00" + "time": "2024-11-08T17:47:46+00:00" }, { "name": "phar-io/manifest", @@ -1506,32 +1509,32 @@ }, { "name": "phpunit/php-code-coverage", - "version": "10.1.14", + "version": "10.1.16", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "e3f51450ebffe8e0efdf7346ae966a656f7d5e5b" + "reference": "7e308268858ed6baedc8704a304727d20bc07c77" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/e3f51450ebffe8e0efdf7346ae966a656f7d5e5b", - "reference": "e3f51450ebffe8e0efdf7346ae966a656f7d5e5b", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/7e308268858ed6baedc8704a304727d20bc07c77", + "reference": "7e308268858ed6baedc8704a304727d20bc07c77", "shasum": "" }, "require": { "ext-dom": "*", "ext-libxml": "*", "ext-xmlwriter": "*", - "nikic/php-parser": "^4.18 || ^5.0", + "nikic/php-parser": "^4.19.1 || ^5.1.0", "php": ">=8.1", - "phpunit/php-file-iterator": "^4.0", - "phpunit/php-text-template": "^3.0", - "sebastian/code-unit-reverse-lookup": "^3.0", - "sebastian/complexity": "^3.0", - "sebastian/environment": "^6.0", - "sebastian/lines-of-code": "^2.0", - "sebastian/version": "^4.0", - "theseer/tokenizer": "^1.2.0" + "phpunit/php-file-iterator": "^4.1.0", + "phpunit/php-text-template": "^3.0.1", + "sebastian/code-unit-reverse-lookup": "^3.0.0", + "sebastian/complexity": "^3.2.0", + "sebastian/environment": "^6.1.0", + "sebastian/lines-of-code": "^2.0.2", + "sebastian/version": "^4.0.1", + "theseer/tokenizer": "^1.2.3" }, "require-dev": { "phpunit/phpunit": "^10.1" @@ -1543,7 +1546,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "10.1-dev" + "dev-main": "10.1.x-dev" } }, "autoload": { @@ -1572,7 +1575,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/10.1.14" + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/10.1.16" }, "funding": [ { @@ -1580,7 +1583,7 @@ "type": "github" } ], - "time": "2024-03-12T15:33:41+00:00" + "time": "2024-08-22T04:31:57+00:00" }, { "name": "phpunit/php-file-iterator", @@ -1827,16 +1830,16 @@ }, { "name": "phpunit/phpunit", - "version": "10.5.19", + "version": "10.5.38", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "c726f0de022368f6ed103e452a765d3304a996a4" + "reference": "a86773b9e887a67bc53efa9da9ad6e3f2498c132" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/c726f0de022368f6ed103e452a765d3304a996a4", - "reference": "c726f0de022368f6ed103e452a765d3304a996a4", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/a86773b9e887a67bc53efa9da9ad6e3f2498c132", + "reference": "a86773b9e887a67bc53efa9da9ad6e3f2498c132", "shasum": "" }, "require": { @@ -1846,26 +1849,26 @@ "ext-mbstring": "*", "ext-xml": "*", "ext-xmlwriter": "*", - "myclabs/deep-copy": "^1.10.1", - "phar-io/manifest": "^2.0.3", - "phar-io/version": "^3.0.2", + "myclabs/deep-copy": "^1.12.0", + "phar-io/manifest": "^2.0.4", + "phar-io/version": "^3.2.1", "php": ">=8.1", - "phpunit/php-code-coverage": "^10.1.5", - "phpunit/php-file-iterator": "^4.0", - "phpunit/php-invoker": "^4.0", - "phpunit/php-text-template": "^3.0", - "phpunit/php-timer": "^6.0", - "sebastian/cli-parser": "^2.0", - "sebastian/code-unit": "^2.0", - "sebastian/comparator": "^5.0", - "sebastian/diff": "^5.0", - "sebastian/environment": "^6.0", - "sebastian/exporter": "^5.1", - "sebastian/global-state": "^6.0.1", - "sebastian/object-enumerator": "^5.0", - "sebastian/recursion-context": "^5.0", - "sebastian/type": "^4.0", - "sebastian/version": "^4.0" + "phpunit/php-code-coverage": "^10.1.16", + "phpunit/php-file-iterator": "^4.1.0", + "phpunit/php-invoker": "^4.0.0", + "phpunit/php-text-template": "^3.0.1", + "phpunit/php-timer": "^6.0.0", + "sebastian/cli-parser": "^2.0.1", + "sebastian/code-unit": "^2.0.0", + "sebastian/comparator": "^5.0.3", + "sebastian/diff": "^5.1.1", + "sebastian/environment": "^6.1.0", + "sebastian/exporter": "^5.1.2", + "sebastian/global-state": "^6.0.2", + "sebastian/object-enumerator": "^5.0.0", + "sebastian/recursion-context": "^5.0.0", + "sebastian/type": "^4.0.0", + "sebastian/version": "^4.0.1" }, "suggest": { "ext-soap": "To be able to generate mocks based on WSDL files" @@ -1908,7 +1911,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", "security": "https://github.com/sebastianbergmann/phpunit/security/policy", - "source": "https://github.com/sebastianbergmann/phpunit/tree/10.5.19" + "source": "https://github.com/sebastianbergmann/phpunit/tree/10.5.38" }, "funding": [ { @@ -1924,7 +1927,7 @@ "type": "tidelift" } ], - "time": "2024-04-17T14:06:18+00:00" + "time": "2024-10-28T13:06:21+00:00" }, { "name": "sebastian/cli-parser", @@ -2096,16 +2099,16 @@ }, { "name": "sebastian/comparator", - "version": "5.0.1", + "version": "5.0.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "2db5010a484d53ebf536087a70b4a5423c102372" + "reference": "a18251eb0b7a2dcd2f7aa3d6078b18545ef0558e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/2db5010a484d53ebf536087a70b4a5423c102372", - "reference": "2db5010a484d53ebf536087a70b4a5423c102372", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/a18251eb0b7a2dcd2f7aa3d6078b18545ef0558e", + "reference": "a18251eb0b7a2dcd2f7aa3d6078b18545ef0558e", "shasum": "" }, "require": { @@ -2116,7 +2119,7 @@ "sebastian/exporter": "^5.0" }, "require-dev": { - "phpunit/phpunit": "^10.3" + "phpunit/phpunit": "^10.5" }, "type": "library", "extra": { @@ -2161,7 +2164,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/comparator/issues", "security": "https://github.com/sebastianbergmann/comparator/security/policy", - "source": "https://github.com/sebastianbergmann/comparator/tree/5.0.1" + "source": "https://github.com/sebastianbergmann/comparator/tree/5.0.3" }, "funding": [ { @@ -2169,7 +2172,7 @@ "type": "github" } ], - "time": "2023-08-14T13:18:12+00:00" + "time": "2024-10-18T14:56:07+00:00" }, { "name": "sebastian/complexity", @@ -2965,15 +2968,15 @@ ], "aliases": [], "minimum-stability": "stable", - "stability-flags": [], + "stability-flags": {}, "prefer-stable": false, "prefer-lowest": false, "platform": { - "php": "~8.1.0||~8.2.0||~8.3.0", + "php": "~8.1.0||~8.2.0||~8.3.0||~8.4.0", "ext-json": "*" }, "platform-dev": { "ext-dom": "*" }, - "plugin-api-version": "2.2.0" + "plugin-api-version": "2.6.0" } From 160d24b17dc7113393446d5aef84c4cbc985fe32 Mon Sep 17 00:00:00 2001 From: Rajesh Kumar Date: Fri, 6 Dec 2024 13:17:42 +0530 Subject: [PATCH 20/55] [SVC] Adding a new public method to API class should be a minor change, but not a patch --- src/ReportBuilder.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ReportBuilder.php b/src/ReportBuilder.php index d9e391af..e39d8682 100644 --- a/src/ReportBuilder.php +++ b/src/ReportBuilder.php @@ -126,7 +126,7 @@ protected function makeVersionReport() // Customize severity level of some @api changes LevelMapping::setOverrides( [ - 'V015' => Level::PATCH, // Add public method + 'V015' => Level::MINOR, // Add public method 'V016' => Level::PATCH, // Add protected method 'V019' => Level::MINOR, // Add public property 'V020' => Level::MINOR, // Add protected property From 2813ffa1483fd7e9a8b7cc86ad4122683672c978 Mon Sep 17 00:00:00 2001 From: Rajesh Kumar Date: Fri, 6 Dec 2024 22:55:20 +0530 Subject: [PATCH 21/55] [SVC] Adding a new public method to API class should be a minor change, but not a patch --- .../Console/Command/CompareSourceCommandApiClassesTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dev/tests/Unit/Console/Command/CompareSourceCommandApiClassesTest.php b/dev/tests/Unit/Console/Command/CompareSourceCommandApiClassesTest.php index 82d4ed6c..32dadfe9 100644 --- a/dev/tests/Unit/Console/Command/CompareSourceCommandApiClassesTest.php +++ b/dev/tests/Unit/Console/Command/CompareSourceCommandApiClassesTest.php @@ -59,10 +59,10 @@ public static function changesDataProvider() $pathToFixtures . '/new-method/source-code-before', $pathToFixtures . '/new-method/source-code-after', [ - 'Class (PATCH)', + 'Class (MINOR)', 'Test\Vcs\TestClass::testMethod | [public] Method has been added. | V015' ], - 'Patch change is detected.' + 'Minor change is detected.' ], 'api-class-removed-class' => [ $pathToFixtures . '/removed-class/source-code-before', From 5a5f85bb0ca79286f64f40245c1c57e5638e348d Mon Sep 17 00:00:00 2001 From: Rajesh Kumar Date: Tue, 10 Dec 2024 12:28:31 +0530 Subject: [PATCH 22/55] SVC false-positive: modifying system.xml file from another module --- src/Analyzer/SystemXml/Analyzer.php | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/src/Analyzer/SystemXml/Analyzer.php b/src/Analyzer/SystemXml/Analyzer.php index a670bb34..fcdfb03b 100644 --- a/src/Analyzer/SystemXml/Analyzer.php +++ b/src/Analyzer/SystemXml/Analyzer.php @@ -144,7 +144,7 @@ public function analyze($registryBefore, $registryAfter) * @param string $filePath * @return string|null */ - private function getBaseDir($filePath) + private function getBaseDir($filePath): ?string { $currentDir = dirname($filePath); while ($currentDir !== '/' && $currentDir !== false) { @@ -327,8 +327,9 @@ private function reportDuplicateNodes(string $file, array $nodes): void * * @param array $modules * @param XmlRegistry $registryBefore + * @return void */ - private function reportRemovedFiles(array $modules, XmlRegistry $registryBefore) + private function reportRemovedFiles(array $modules, XmlRegistry $registryBefore): void { foreach ($modules as $module) { $beforeFile = $registryBefore->mapping[XmlRegistry::NODES_KEY][$module]; @@ -341,8 +342,9 @@ private function reportRemovedFiles(array $modules, XmlRegistry $registryBefore) * * @param string $file * @param NodeInterface[] $nodes + * @return void */ - private function reportRemovedNodes(string $file, array $nodes) + private function reportRemovedNodes(string $file, array $nodes): void { foreach ($nodes as $node) { switch (true) { @@ -361,15 +363,14 @@ private function reportRemovedNodes(string $file, array $nodes) } } - /** - * @param string|null $baseDir - * @param string $sectionId - * @param string $groupId - * @param string $fieldId - * @param string $afterFile - * @return array - * @throws \Exception - */ + /** + * @param string|null $baseDir + * @param string $sectionId + * @param string $groupId + * @param string|null $fieldId + * @param string $afterFile + * @return array + */ private function isDuplicatedFieldInXml( ?string $baseDir, string $sectionId, From d94a2e592607e0724b90d836bf30f59c0a7a123e Mon Sep 17 00:00:00 2001 From: Rajesh Kumar Date: Tue, 17 Dec 2024 18:48:50 +0530 Subject: [PATCH 23/55] Added PHP 8.4 support --- .github/workflows/php.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/php.yml b/.github/workflows/php.yml index a545c1b3..943c0957 100644 --- a/.github/workflows/php.yml +++ b/.github/workflows/php.yml @@ -17,6 +17,7 @@ jobs: - "8.1" - "8.2" - "8.3" + - "8.4" dependencies: - "lowest" - "highest" From 6f735e3613c32abaabe9b43268392e75e855b51b Mon Sep 17 00:00:00 2001 From: Rajesh Kumar Date: Tue, 17 Dec 2024 22:00:12 +0530 Subject: [PATCH 24/55] Resolve the pr comments --- src/Analyzer/SystemXml/Analyzer.php | 46 ++++++++++++++--------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/src/Analyzer/SystemXml/Analyzer.php b/src/Analyzer/SystemXml/Analyzer.php index fcdfb03b..35a308fa 100644 --- a/src/Analyzer/SystemXml/Analyzer.php +++ b/src/Analyzer/SystemXml/Analyzer.php @@ -157,14 +157,14 @@ private function getBaseDir($filePath): ?string return null; } - /** - * Search for system.xml files in both app/code and vendor directories, excluding the provided file. - * - * @param string $magentoBaseDir The base directory of Magento. - * @param string $excludeFile The file to exclude from the search. - * @return array An array of paths to system.xml files, excluding the specified file. - */ - private function getSystemXmlFiles($magentoBaseDir, $excludeFile = null): array + /** + * Search for system.xml files in both app/code and vendor directories, excluding the provided file. + * + * @param string $magentoBaseDir The base directory of Magento. + * @param string|null $excludeFile The file to exclude from the search. + * @return array An array of paths to system.xml files, excluding the specified file. + */ + private function getSystemXmlFiles(string $magentoBaseDir, ?string $excludeFile = null): array { $systemXmlFiles = []; $directoryToSearch = [ @@ -189,13 +189,13 @@ private function getSystemXmlFiles($magentoBaseDir, $excludeFile = null): array return $systemXmlFiles; } - /** - * Method to extract section, group and field from the Node - * - * @param $nodePath - * @return array|null - */ - private function extractSectionGroupField($nodePath): ?array + /** + * Method to extract section, group and field from the Node + * + * @param string $nodePath + * @return array|null + */ + private function extractSectionGroupField(string $nodePath): ?array { $parts = explode('/', $nodePath); @@ -211,14 +211,14 @@ private function extractSectionGroupField($nodePath): ?array return [$sectionId, $groupId, $fieldId]; } - /** - * Method to get Node Data using reflection class - * - * @param $node - * @return array - * @throws \ReflectionException - */ - private function getNodeData($node): array + /** + * Method to get Node Data using reflection class + * + * @param object|string $node + * @return array + * @throws \ReflectionException + */ + private function getNodeData(object|string $node): array { $data = []; From 86777d79ab8821028d158f88b7d3b4c22dfe6b77 Mon Sep 17 00:00:00 2001 From: Rajesh Kumar Date: Tue, 17 Dec 2024 22:02:37 +0530 Subject: [PATCH 25/55] Resolve the pr comments --- src/Analyzer/SystemXml/Analyzer.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Analyzer/SystemXml/Analyzer.php b/src/Analyzer/SystemXml/Analyzer.php index 35a308fa..d1b2206c 100644 --- a/src/Analyzer/SystemXml/Analyzer.php +++ b/src/Analyzer/SystemXml/Analyzer.php @@ -144,7 +144,7 @@ public function analyze($registryBefore, $registryAfter) * @param string $filePath * @return string|null */ - private function getBaseDir($filePath): ?string + private function getBaseDir(string $filePath): ?string { $currentDir = dirname($filePath); while ($currentDir !== '/' && $currentDir !== false) { From 6b7fb151c9d918f3328933ead21d58a0d7276f3d Mon Sep 17 00:00:00 2001 From: Rajesh Kumar Date: Tue, 17 Dec 2024 22:16:17 +0530 Subject: [PATCH 26/55] 13.0.0-beta6 version --- composer.json | 2 +- composer.lock | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index e5c9c52f..15a6bd00 100644 --- a/composer.json +++ b/composer.json @@ -1,7 +1,7 @@ { "name": "magento/magento-semver", "description": "Magento Semantic Version Checker", - "version": "13.0.0-beta5", + "version": "13.0.0-beta6", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/composer.lock b/composer.lock index d97f6e3f..986418c1 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "fef25ea90a323b619f8947668fa74553", + "content-hash": "921aa30452423b597fd8a27ffbc91b25", "packages": [ { "name": "hassankhan/config", From 99b94a377c6b1ea7f184d30d92df3c955eb9d24c Mon Sep 17 00:00:00 2001 From: Rajesh Kumar Date: Thu, 16 Jan 2025 16:59:49 +0530 Subject: [PATCH 27/55] AC-13728::Update the wikimedia/less.php same as root composer.json --- composer.json | 4 ++-- composer.lock | 26 +++++++++++++------------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/composer.json b/composer.json index 15a6bd00..10a9ba70 100644 --- a/composer.json +++ b/composer.json @@ -1,7 +1,7 @@ { "name": "magento/magento-semver", "description": "Magento Semantic Version Checker", - "version": "13.0.0-beta6", + "version": "13.0.0-beta7", "license": [ "OSL-3.0", "AFL-3.0" @@ -16,7 +16,7 @@ "sabre/xml": "~2.2.3", "symfony/console": "~6.4.0", "tomzx/php-semver-checker": "^0.16.0", - "wikimedia/less.php": "^3.2" + "wikimedia/less.php": "^5.0" }, "require-dev": { "ext-dom": "*", diff --git a/composer.lock b/composer.lock index 986418c1..ebc4fad8 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "921aa30452423b597fd8a27ffbc91b25", + "content-hash": "d2e6a737d55a4cd56cd6da05beed7cd4", "packages": [ { "name": "hassankhan/config", @@ -1254,28 +1254,28 @@ }, { "name": "wikimedia/less.php", - "version": "v3.2.1", + "version": "v5.1.2", "source": { "type": "git", "url": "https://github.com/wikimedia/less.php.git", - "reference": "0d5b30ba792bdbf8991a646fc9c30561b38a5559" + "reference": "39b1fbbdd3d95c5279f231d2298f3866fa869fcd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/wikimedia/less.php/zipball/0d5b30ba792bdbf8991a646fc9c30561b38a5559", - "reference": "0d5b30ba792bdbf8991a646fc9c30561b38a5559", + "url": "https://api.github.com/repos/wikimedia/less.php/zipball/39b1fbbdd3d95c5279f231d2298f3866fa869fcd", + "reference": "39b1fbbdd3d95c5279f231d2298f3866fa869fcd", "shasum": "" }, "require": { - "php": ">=7.2.9" + "php": ">=7.4.3" }, "require-dev": { - "mediawiki/mediawiki-codesniffer": "40.0.1", - "mediawiki/mediawiki-phan-config": "0.12.0", - "mediawiki/minus-x": "1.1.1", + "mediawiki/mediawiki-codesniffer": "45.0.0", + "mediawiki/mediawiki-phan-config": "0.14.0", + "mediawiki/minus-x": "1.1.3", "php-parallel-lint/php-console-highlighter": "1.0.0", - "php-parallel-lint/php-parallel-lint": "1.3.2", - "phpunit/phpunit": "^8.5" + "php-parallel-lint/php-parallel-lint": "1.4.0", + "phpunit/phpunit": "9.6.16" }, "bin": [ "bin/lessc" @@ -1323,9 +1323,9 @@ ], "support": { "issues": "https://github.com/wikimedia/less.php/issues", - "source": "https://github.com/wikimedia/less.php/tree/v3.2.1" + "source": "https://github.com/wikimedia/less.php/tree/v5.1.2" }, - "time": "2023-02-03T06:43:41+00:00" + "time": "2024-11-13T15:44:20+00:00" } ], "packages-dev": [ From 0ef7e6e4e05421b07ed34f2f9d44bb9e9da9336b Mon Sep 17 00:00:00 2001 From: Dnyaneshwar Jambhulkar Date: Fri, 17 Jan 2025 18:54:13 +0530 Subject: [PATCH 28/55] Added support for wikimedia/less.php 5.0 --- .../Unit/Console/Command/CompareSourceCommandLessTest.php | 6 +++--- .../source-code-after/AbstractExtensibleModel.php | 2 +- .../source-code-after/TestClass.php | 2 +- .../source-code-after/TestClass.php | 2 +- src/Analyzer/AbstractCodeAnalyzer.php | 2 +- src/Analyzer/ClassLikeApiAnnotationAnalyzer.php | 2 +- src/Analyzer/Factory/AnalyzerFactory.php | 2 +- src/Analyzer/Factory/AnalyzerFactoryInterface.php | 2 +- src/Analyzer/Factory/DbSchemaAnalyzerFactory.php | 2 +- src/Analyzer/Factory/DiAnalyzerFactory.php | 2 +- src/Analyzer/Factory/EtSchemaAnalyzerFactory.php | 2 +- src/Analyzer/Factory/LayoutAnalyzerFactory.php | 2 +- src/Analyzer/Factory/LessAnalyzerFactory.php | 2 +- src/Analyzer/Factory/MftfAnalyzerFactory.php | 2 +- src/Analyzer/Factory/NonApiAnalyzerFactory.php | 2 +- src/Analyzer/Factory/SystemXmlAnalyzerFactory.php | 2 +- src/Analyzer/Factory/XsdAnalyzerFactory.php | 2 +- src/Analyzer/Less/Analyzer.php | 4 ++-- src/Scanner/ScannerRegistryFactory.php | 6 +++--- src/Visitor/AbstractApiVisitor.php | 4 ++-- 20 files changed, 26 insertions(+), 26 deletions(-) diff --git a/dev/tests/Unit/Console/Command/CompareSourceCommandLessTest.php b/dev/tests/Unit/Console/Command/CompareSourceCommandLessTest.php index 1790a97e..6c384ca3 100644 --- a/dev/tests/Unit/Console/Command/CompareSourceCommandLessTest.php +++ b/dev/tests/Unit/Console/Command/CompareSourceCommandLessTest.php @@ -98,7 +98,7 @@ public static function changesDataProvider() $pathToFixtures . '/removed-import/source-code-after', [ '/Less \(MAJOR\)/', - '/view\/frontend\/web\/css\/source\/test.less:0\s*\|\s*Import with value: \'testimport\'\s*\|\s*A less import-node was removed\s*\|\s*M402/' + '/view\/frontend\/web\/css\/source\/test.less:0\s*\|\s*Less_Tree_Import\s*\|\s*A less import-node was removed\s*\|\s*M402/' ], 'Major change is detected.', ], @@ -107,8 +107,8 @@ public static function changesDataProvider() $pathToFixtures . '/removed-imports/source-code-after', [ '/Less \(MAJOR\)/', - '/view\/frontend\/web\/css\/source\/test.less:0\s*\|\s*Import with value: \'testimport\'\s*\|\s*A less import-node was removed\s*\|\s*M402/', - '/view\/frontend\/web\/css\/source\/test.less:0\s*\|\s*Import with value: \'testimport2\'\s*\|\s*A less import-node was removed\s*\|\s*M402/' + '/view\/frontend\/web\/css\/source\/test.less:0\s*\|\s*Less_Tree_Import\s*\|\s*A less import-node was removed\s*\|\s*M402/', + '/view\/frontend\/web\/css\/source\/test.less:0\s*\|\s*Less_Tree_Import\s*\|\s*A less import-node was removed\s*\|\s*M402/' ], 'Major change is detected.', ], diff --git a/dev/tests/Unit/Console/Command/CompareSourceCommandTest/_files/api-class/new-optional-constructor-parameter-for-extendable/source-code-after/AbstractExtensibleModel.php b/dev/tests/Unit/Console/Command/CompareSourceCommandTest/_files/api-class/new-optional-constructor-parameter-for-extendable/source-code-after/AbstractExtensibleModel.php index f31f3ba9..920786e7 100644 --- a/dev/tests/Unit/Console/Command/CompareSourceCommandTest/_files/api-class/new-optional-constructor-parameter-for-extendable/source-code-after/AbstractExtensibleModel.php +++ b/dev/tests/Unit/Console/Command/CompareSourceCommandTest/_files/api-class/new-optional-constructor-parameter-for-extendable/source-code-after/AbstractExtensibleModel.php @@ -11,7 +11,7 @@ */ class AbstractExtensibleModel { - public function __construct(\Test\Vcs\TestInterface $a, \Test\Vcs\TestInterface $b = null) + public function __construct(\Test\Vcs\TestInterface $a, ?\Test\Vcs\TestInterface $b = null) { } } diff --git a/dev/tests/Unit/Console/Command/CompareSourceCommandTest/_files/api-class/new-optional-constructor-parameter/source-code-after/TestClass.php b/dev/tests/Unit/Console/Command/CompareSourceCommandTest/_files/api-class/new-optional-constructor-parameter/source-code-after/TestClass.php index f0d494eb..fbdf0168 100644 --- a/dev/tests/Unit/Console/Command/CompareSourceCommandTest/_files/api-class/new-optional-constructor-parameter/source-code-after/TestClass.php +++ b/dev/tests/Unit/Console/Command/CompareSourceCommandTest/_files/api-class/new-optional-constructor-parameter/source-code-after/TestClass.php @@ -11,7 +11,7 @@ */ class TestClass { - public function __construct(\Test\Vcs\TestInterface $a, \Test\Vcs\TestInterface $b = null) + public function __construct(\Test\Vcs\TestInterface $a, ?\Test\Vcs\TestInterface $b = null) { } } diff --git a/dev/tests/Unit/Console/Command/CompareSourceCommandTest/_files/non-api-class/new-optional-constructor-parameter/source-code-after/TestClass.php b/dev/tests/Unit/Console/Command/CompareSourceCommandTest/_files/non-api-class/new-optional-constructor-parameter/source-code-after/TestClass.php index 25696461..50537bd9 100644 --- a/dev/tests/Unit/Console/Command/CompareSourceCommandTest/_files/non-api-class/new-optional-constructor-parameter/source-code-after/TestClass.php +++ b/dev/tests/Unit/Console/Command/CompareSourceCommandTest/_files/non-api-class/new-optional-constructor-parameter/source-code-after/TestClass.php @@ -8,7 +8,7 @@ class TestClass { - public function __construct(\Test\Vcs\TestInterface $a, \Test\Vcs\TestInterface $b = null) + public function __construct(\Test\Vcs\TestInterface $a, ?\Test\Vcs\TestInterface $b = null) { } } diff --git a/src/Analyzer/AbstractCodeAnalyzer.php b/src/Analyzer/AbstractCodeAnalyzer.php index 1bf4d16a..8bcc6805 100644 --- a/src/Analyzer/AbstractCodeAnalyzer.php +++ b/src/Analyzer/AbstractCodeAnalyzer.php @@ -51,7 +51,7 @@ public function __construct( $context = null, $fileBefore = null, $fileAfter = null, - DependencyGraph $dependencyGraph = null + ?DependencyGraph $dependencyGraph = null ) { $this->context = $context; $this->fileBefore = $fileBefore; diff --git a/src/Analyzer/ClassLikeApiAnnotationAnalyzer.php b/src/Analyzer/ClassLikeApiAnnotationAnalyzer.php index 2b28661e..105b41d5 100644 --- a/src/Analyzer/ClassLikeApiAnnotationAnalyzer.php +++ b/src/Analyzer/ClassLikeApiAnnotationAnalyzer.php @@ -35,7 +35,7 @@ public function __construct( $context = null, $fileBefore = null, $fileAfter = null, - DependencyGraph $dependencyGraph = null + ?DependencyGraph $dependencyGraph = null ) { parent::__construct($context, $fileBefore, $fileAfter, $dependencyGraph); $this->nodeHelper = new Node(); diff --git a/src/Analyzer/Factory/AnalyzerFactory.php b/src/Analyzer/Factory/AnalyzerFactory.php index b7aae2d2..4ab0b5b8 100644 --- a/src/Analyzer/Factory/AnalyzerFactory.php +++ b/src/Analyzer/Factory/AnalyzerFactory.php @@ -25,7 +25,7 @@ class AnalyzerFactory implements AnalyzerFactoryInterface * @param DependencyGraph|null $dependencyGraph * @return AnalyzerInterface */ - public function create(DependencyGraph $dependencyGraph = null): AnalyzerInterface + public function create(?DependencyGraph $dependencyGraph = null): AnalyzerInterface { $analyzers = [ new ApiClassAnalyzer(null, null, null, $dependencyGraph), diff --git a/src/Analyzer/Factory/AnalyzerFactoryInterface.php b/src/Analyzer/Factory/AnalyzerFactoryInterface.php index 63dc27ea..fed7828e 100644 --- a/src/Analyzer/Factory/AnalyzerFactoryInterface.php +++ b/src/Analyzer/Factory/AnalyzerFactoryInterface.php @@ -21,5 +21,5 @@ interface AnalyzerFactoryInterface * @param DependencyGraph|null $dependencyGraph * @return AnalyzerInterface */ - public function create(DependencyGraph $dependencyGraph = null): AnalyzerInterface; + public function create(?DependencyGraph $dependencyGraph = null): AnalyzerInterface; } diff --git a/src/Analyzer/Factory/DbSchemaAnalyzerFactory.php b/src/Analyzer/Factory/DbSchemaAnalyzerFactory.php index 32eb0dbc..7910b8e6 100644 --- a/src/Analyzer/Factory/DbSchemaAnalyzerFactory.php +++ b/src/Analyzer/Factory/DbSchemaAnalyzerFactory.php @@ -30,7 +30,7 @@ class DbSchemaAnalyzerFactory implements AnalyzerFactoryInterface * @param DependencyGraph|null $dependencyGraph * @return AnalyzerInterface */ - public function create(DependencyGraph $dependencyGraph = null): AnalyzerInterface + public function create(?DependencyGraph $dependencyGraph = null): AnalyzerInterface { $report = new Report(); $analyzers = [ diff --git a/src/Analyzer/Factory/DiAnalyzerFactory.php b/src/Analyzer/Factory/DiAnalyzerFactory.php index 0260bbe3..ea9a9bf5 100644 --- a/src/Analyzer/Factory/DiAnalyzerFactory.php +++ b/src/Analyzer/Factory/DiAnalyzerFactory.php @@ -24,7 +24,7 @@ class DiAnalyzerFactory implements AnalyzerFactoryInterface * @param DependencyGraph|null $dependencyGraph * @return AnalyzerInterface */ - public function create(DependencyGraph $dependencyGraph = null): AnalyzerInterface + public function create(?DependencyGraph $dependencyGraph = null): AnalyzerInterface { $report = new DbSchemaReport(); $analyzers = [ diff --git a/src/Analyzer/Factory/EtSchemaAnalyzerFactory.php b/src/Analyzer/Factory/EtSchemaAnalyzerFactory.php index a00f3aa6..374b5d12 100644 --- a/src/Analyzer/Factory/EtSchemaAnalyzerFactory.php +++ b/src/Analyzer/Factory/EtSchemaAnalyzerFactory.php @@ -22,7 +22,7 @@ */ class EtSchemaAnalyzerFactory implements AnalyzerFactoryInterface { - public function create(DependencyGraph $dependencyGraph = null): AnalyzerInterface + public function create(?DependencyGraph $dependencyGraph = null): AnalyzerInterface { $report = new DbSchemaReport(); $analyzers = [ diff --git a/src/Analyzer/Factory/LayoutAnalyzerFactory.php b/src/Analyzer/Factory/LayoutAnalyzerFactory.php index 37078910..6ccf54df 100644 --- a/src/Analyzer/Factory/LayoutAnalyzerFactory.php +++ b/src/Analyzer/Factory/LayoutAnalyzerFactory.php @@ -24,7 +24,7 @@ class LayoutAnalyzerFactory implements AnalyzerFactoryInterface * @param DependencyGraph|null $dependencyGraph * @return AnalyzerInterface */ - public function create(DependencyGraph $dependencyGraph = null): AnalyzerInterface + public function create(?DependencyGraph $dependencyGraph = null): AnalyzerInterface { $report = new DbSchemaReport(); $analyzers = [ diff --git a/src/Analyzer/Factory/LessAnalyzerFactory.php b/src/Analyzer/Factory/LessAnalyzerFactory.php index e83600a7..3c57d713 100644 --- a/src/Analyzer/Factory/LessAnalyzerFactory.php +++ b/src/Analyzer/Factory/LessAnalyzerFactory.php @@ -24,7 +24,7 @@ class LessAnalyzerFactory implements AnalyzerFactoryInterface * @param DependencyGraph|null $dependencyGraph * @return AnalyzerInterface */ - public function create(DependencyGraph $dependencyGraph = null): AnalyzerInterface + public function create(?DependencyGraph $dependencyGraph = null): AnalyzerInterface { $report = new DbSchemaReport(); $analyzers = [ diff --git a/src/Analyzer/Factory/MftfAnalyzerFactory.php b/src/Analyzer/Factory/MftfAnalyzerFactory.php index e1fe7958..92b5f86c 100644 --- a/src/Analyzer/Factory/MftfAnalyzerFactory.php +++ b/src/Analyzer/Factory/MftfAnalyzerFactory.php @@ -30,7 +30,7 @@ class MftfAnalyzerFactory implements AnalyzerFactoryInterface * @param DependencyGraph|null $dependencyGraph * @return AnalyzerInterface */ - public function create(DependencyGraph $dependencyGraph = null): AnalyzerInterface + public function create(?DependencyGraph $dependencyGraph = null): AnalyzerInterface { $report = new MftfReport(); $analyzers = [ diff --git a/src/Analyzer/Factory/NonApiAnalyzerFactory.php b/src/Analyzer/Factory/NonApiAnalyzerFactory.php index c20dea44..32d26109 100644 --- a/src/Analyzer/Factory/NonApiAnalyzerFactory.php +++ b/src/Analyzer/Factory/NonApiAnalyzerFactory.php @@ -25,7 +25,7 @@ class NonApiAnalyzerFactory implements AnalyzerFactoryInterface * @param DependencyGraph|null $dependencyGraph * @return AnalyzerInterface */ - public function create(DependencyGraph $dependencyGraph = null): AnalyzerInterface + public function create(?DependencyGraph $dependencyGraph = null): AnalyzerInterface { $analyzers = [ new ClassAnalyzer(null, null, null, $dependencyGraph), diff --git a/src/Analyzer/Factory/SystemXmlAnalyzerFactory.php b/src/Analyzer/Factory/SystemXmlAnalyzerFactory.php index b2760610..65d7a205 100644 --- a/src/Analyzer/Factory/SystemXmlAnalyzerFactory.php +++ b/src/Analyzer/Factory/SystemXmlAnalyzerFactory.php @@ -24,7 +24,7 @@ class SystemXmlAnalyzerFactory implements AnalyzerFactoryInterface * @param DependencyGraph|null $dependencyGraph * @return AnalyzerInterface */ - public function create(DependencyGraph $dependencyGraph = null): AnalyzerInterface + public function create(?DependencyGraph $dependencyGraph = null): AnalyzerInterface { $report = new DbSchemaReport(); $analyzers = [ diff --git a/src/Analyzer/Factory/XsdAnalyzerFactory.php b/src/Analyzer/Factory/XsdAnalyzerFactory.php index f30b41a2..11bf6108 100644 --- a/src/Analyzer/Factory/XsdAnalyzerFactory.php +++ b/src/Analyzer/Factory/XsdAnalyzerFactory.php @@ -24,7 +24,7 @@ class XsdAnalyzerFactory implements AnalyzerFactoryInterface * @param DependencyGraph|null $dependencyGraph * @return AnalyzerInterface */ - public function create(DependencyGraph $dependencyGraph = null): AnalyzerInterface + public function create(?DependencyGraph $dependencyGraph = null): AnalyzerInterface { $report = new DbSchemaReport(); $analyzers = [ diff --git a/src/Analyzer/Less/Analyzer.php b/src/Analyzer/Less/Analyzer.php index 1ef3fe02..285a04b2 100644 --- a/src/Analyzer/Less/Analyzer.php +++ b/src/Analyzer/Less/Analyzer.php @@ -20,7 +20,7 @@ use PHPSemVerChecker\Report\Report; use Less_Tree; use Less_Tree_Comment; -use Less_Tree_Rule; +use Less_Tree_Declaration; use Less_Tree_Mixin_Definition; use Less_Tree_Import; @@ -152,7 +152,7 @@ private function reportRemovedNodes(string $file, array $nodes) { foreach ($nodes as $nodeName => $node) { switch (true) { - case $node instanceof Less_Tree_Rule: + case $node instanceof Less_Tree_Declaration: $this->report->add(self::CONTEXT, new VariableRemoved($file, $nodeName)); break; case $node instanceof Less_Tree_Mixin_Definition: diff --git a/src/Scanner/ScannerRegistryFactory.php b/src/Scanner/ScannerRegistryFactory.php index f05e8af3..741e4040 100644 --- a/src/Scanner/ScannerRegistryFactory.php +++ b/src/Scanner/ScannerRegistryFactory.php @@ -55,8 +55,8 @@ private function buildFullScanner() * @return Scanner */ private function buildApiScanner( - DependencyGraph $dependencyGraph = null, - DependencyGraph $dependencyGraphCompare = null + ?DependencyGraph $dependencyGraph = null, + ?DependencyGraph $dependencyGraphCompare = null ) { $registry = new Registry(); $parser = new Parser(new Emulative()); @@ -80,7 +80,7 @@ private function buildApiScanner( * @param boolean $mftf * @return array */ - public function create(DependencyGraph $dependencyGraph = null, DependencyGraph $dependencyGraphCompare = null) + public function create(?DependencyGraph $dependencyGraph = null, ?DependencyGraph $dependencyGraphCompare = null) { $moduleNameResolver = new ModuleNamespaceResolver(); diff --git a/src/Visitor/AbstractApiVisitor.php b/src/Visitor/AbstractApiVisitor.php index 41945863..8c28b865 100644 --- a/src/Visitor/AbstractApiVisitor.php +++ b/src/Visitor/AbstractApiVisitor.php @@ -40,8 +40,8 @@ abstract class AbstractApiVisitor extends NodeVisitorAbstract public function __construct( Registry $registry, NodeHelper $nodeHelper, - DependencyGraph $dependencyGraph = null, - DependencyGraph $dependencyGraphCompare = null + ?DependencyGraph $dependencyGraph = null, + ?DependencyGraph $dependencyGraphCompare = null ) { $this->dependencyGraph = $dependencyGraph; $this->dependencyGraphComapre = $dependencyGraphCompare; From a021619c5ccdf5c10872acd26d7688c5d3d1e3a4 Mon Sep 17 00:00:00 2001 From: Rajesh Kumar Date: Fri, 17 Jan 2025 23:26:29 +0530 Subject: [PATCH 29/55] AC-13728::Update the packages based lowest dependecy to support php 8.4 --- composer.json | 12 +- composer.lock | 524 +++++++++++++++++++++----------------------------- 2 files changed, 228 insertions(+), 308 deletions(-) diff --git a/composer.json b/composer.json index 10a9ba70..aee893ba 100644 --- a/composer.json +++ b/composer.json @@ -11,16 +11,18 @@ "php": "~8.1.0||~8.2.0||~8.3.0||~8.4.0", "ext-json": "*", "laminas/laminas-stdlib": "^3.18", - "nikic/php-parser": "^4.15", + "nikic/php-parser": "^4.19", "phpstan/phpdoc-parser": "^0.5.5", - "sabre/xml": "~2.2.3", - "symfony/console": "~6.4.0", + "sabre/xml": "~4.0.5", + "symfony/console": "~6.4.17", + "symfony/string": "~6.4.15", "tomzx/php-semver-checker": "^0.16.0", - "wikimedia/less.php": "^5.0" + "wikimedia/less.php": "^5.1" }, "require-dev": { "ext-dom": "*", - "phpunit/phpunit": "^10.5", + "phpunit/phpunit": "~10.5.28", + "sebastian/cli-parser": "^2.0.1", "squizlabs/php_codesniffer": "~3.6.0" }, "autoload": { diff --git a/composer.lock b/composer.lock index ebc4fad8..86ddcee3 100644 --- a/composer.lock +++ b/composer.lock @@ -4,33 +4,34 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "d2e6a737d55a4cd56cd6da05beed7cd4", + "content-hash": "480ed8ade9fa6af94e4454d3bc8866f7", "packages": [ { "name": "hassankhan/config", - "version": "3.1.0", + "version": "3.0.0", "source": { "type": "git", "url": "https://github.com/hassankhan/config.git", - "reference": "8e1c07f4fdc2b986b8a781f0dcba155af2a579b6" + "reference": "a3f02c5158d0a772d242ffd377657793c08cc0c6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/hassankhan/config/zipball/8e1c07f4fdc2b986b8a781f0dcba155af2a579b6", - "reference": "8e1c07f4fdc2b986b8a781f0dcba155af2a579b6", + "url": "https://api.github.com/repos/hassankhan/config/zipball/a3f02c5158d0a772d242ffd377657793c08cc0c6", + "reference": "a3f02c5158d0a772d242ffd377657793c08cc0c6", "shasum": "" }, "require": { - "php": ">=7.4" + "php": ">=5.5.9" }, "require-dev": { - "phpunit/phpunit": "^9.5", - "scrutinizer/ocular": "^1.9", - "squizlabs/php_codesniffer": "^3.6", - "symfony/yaml": "^5.4" + "phpunit/phpunit": "~4.8.36 || ~5.7 || ~6.5 || ~7.5 || ~8.5", + "scrutinizer/ocular": "~1.1", + "squizlabs/php_codesniffer": "~2.2", + "symfony/yaml": "~3.4", + "yoast/phpunit-polyfills": "^1.0" }, "suggest": { - "symfony/yaml": "^5.4" + "symfony/yaml": "~3.4" }, "type": "library", "autoload": { @@ -64,9 +65,9 @@ ], "support": { "issues": "https://github.com/hassankhan/config/issues", - "source": "https://github.com/hassankhan/config/tree/3.1.0" + "source": "https://github.com/hassankhan/config/tree/3.0.0" }, - "time": "2022-12-20T19:48:37+00:00" + "time": "2021-12-30T16:38:05+00:00" }, { "name": "laminas/laminas-stdlib", @@ -129,16 +130,16 @@ }, { "name": "nikic/php-parser", - "version": "v4.19.4", + "version": "v4.19.0", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "715f4d25e225bc47b293a8b997fe6ce99bf987d2" + "reference": "32cdab9a034239a8f57ae0e9a15bada4bd9747bf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/715f4d25e225bc47b293a8b997fe6ce99bf987d2", - "reference": "715f4d25e225bc47b293a8b997fe6ce99bf987d2", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/32cdab9a034239a8f57ae0e9a15bada4bd9747bf", + "reference": "32cdab9a034239a8f57ae0e9a15bada4bd9747bf", "shasum": "" }, "require": { @@ -147,7 +148,7 @@ }, "require-dev": { "ircmaxell/php-yacc": "^0.0.7", - "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0" + "phpunit/phpunit": "^6.5 || ^7.0 || ^8.0 || ^9.0" }, "bin": [ "bin/php-parse" @@ -179,22 +180,22 @@ ], "support": { "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v4.19.4" + "source": "https://github.com/nikic/PHP-Parser/tree/v4.19.0" }, - "time": "2024-09-29T15:01:53+00:00" + "time": "2024-03-16T14:49:31+00:00" }, { "name": "phpstan/phpdoc-parser", - "version": "0.5.7", + "version": "0.5.5", "source": { "type": "git", "url": "https://github.com/phpstan/phpdoc-parser.git", - "reference": "816e826ce0b7fb32098d8cb6de62511ce6021cea" + "reference": "ea0b17460ec38e20d7eb64e7ec49b5d44af5d28c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/816e826ce0b7fb32098d8cb6de62511ce6021cea", - "reference": "816e826ce0b7fb32098d8cb6de62511ce6021cea", + "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/ea0b17460ec38e20d7eb64e7ec49b5d44af5d28c", + "reference": "ea0b17460ec38e20d7eb64e7ec49b5d44af5d28c", "shasum": "" }, "require": { @@ -228,31 +229,31 @@ "description": "PHPDoc parser with support for nullable, intersection and generic types", "support": { "issues": "https://github.com/phpstan/phpdoc-parser/issues", - "source": "https://github.com/phpstan/phpdoc-parser/tree/0.5.7" + "source": "https://github.com/phpstan/phpdoc-parser/tree/0.5.5" }, - "time": "2021-09-12T11:52:00+00:00" + "time": "2021-06-11T13:24:46+00:00" }, { "name": "psr/container", - "version": "2.0.2", + "version": "1.1.0", "source": { "type": "git", "url": "https://github.com/php-fig/container.git", - "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963" + "reference": "9fc7aab7a78057a124384358ebae8a1711b6f6fc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/container/zipball/c71ecc56dfe541dbd90c5360474fbc405f8d5963", - "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963", + "url": "https://api.github.com/repos/php-fig/container/zipball/9fc7aab7a78057a124384358ebae8a1711b6f6fc", + "reference": "9fc7aab7a78057a124384358ebae8a1711b6f6fc", "shasum": "" }, "require": { - "php": ">=7.4.0" + "php": ">=7.2.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0.x-dev" + "dev-master": "1.1.x-dev" } }, "autoload": { @@ -281,34 +282,30 @@ ], "support": { "issues": "https://github.com/php-fig/container/issues", - "source": "https://github.com/php-fig/container/tree/2.0.2" + "source": "https://github.com/php-fig/container/tree/1.1.0" }, - "time": "2021-11-05T16:47:00+00:00" + "time": "2021-03-05T15:48:30+00:00" }, { "name": "sabre/uri", - "version": "2.3.4", + "version": "2.0.0", "source": { "type": "git", "url": "https://github.com/sabre-io/uri.git", - "reference": "b76524c22de90d80ca73143680a8e77b1266c291" + "reference": "ef4987fd1c88d1112d75d8527a35a9392d02e488" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sabre-io/uri/zipball/b76524c22de90d80ca73143680a8e77b1266c291", - "reference": "b76524c22de90d80ca73143680a8e77b1266c291", + "url": "https://api.github.com/repos/sabre-io/uri/zipball/ef4987fd1c88d1112d75d8527a35a9392d02e488", + "reference": "ef4987fd1c88d1112d75d8527a35a9392d02e488", "shasum": "" }, "require": { - "php": "^7.4 || ^8.0" + "php": ">=7" }, "require-dev": { - "friendsofphp/php-cs-fixer": "^3.63", - "phpstan/extension-installer": "^1.4", - "phpstan/phpstan": "^1.12", - "phpstan/phpstan-phpunit": "^1.4", - "phpstan/phpstan-strict-rules": "^1.6", - "phpunit/phpunit": "^9.6" + "phpunit/phpunit": "*", + "sabre/cs": "~1.0.0" }, "type": "library", "autoload": { @@ -343,20 +340,20 @@ "issues": "https://github.com/sabre-io/uri/issues", "source": "https://github.com/fruux/sabre-uri" }, - "time": "2024-08-27T12:18:16+00:00" + "time": "2016-10-07T02:52:31+00:00" }, { "name": "sabre/xml", - "version": "2.2.11", + "version": "4.0.5", "source": { "type": "git", "url": "https://github.com/sabre-io/xml.git", - "reference": "01a7927842abf3e10df3d9c2d9b0cc9d813a3fcc" + "reference": "c29e49fcf9ca8ca058b1e350ee9abe4205c0de89" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sabre-io/xml/zipball/01a7927842abf3e10df3d9c2d9b0cc9d813a3fcc", - "reference": "01a7927842abf3e10df3d9c2d9b0cc9d813a3fcc", + "url": "https://api.github.com/repos/sabre-io/xml/zipball/c29e49fcf9ca8ca058b1e350ee9abe4205c0de89", + "reference": "c29e49fcf9ca8ca058b1e350ee9abe4205c0de89", "shasum": "" }, "require": { @@ -364,13 +361,13 @@ "ext-xmlreader": "*", "ext-xmlwriter": "*", "lib-libxml": ">=2.6.20", - "php": "^7.1 || ^8.0", - "sabre/uri": ">=1.0,<3.0.0" + "php": "^7.4 || ^8.0", + "sabre/uri": ">=2.0,<4.0.0" }, "require-dev": { - "friendsofphp/php-cs-fixer": "~2.17.1||3.63.2", - "phpstan/phpstan": "^0.12", - "phpunit/phpunit": "^7.5 || ^8.5 || ^9.6" + "friendsofphp/php-cs-fixer": "^3.51", + "phpstan/phpstan": "^1.10", + "phpunit/phpunit": "^9.6" }, "type": "library", "autoload": { @@ -412,20 +409,20 @@ "issues": "https://github.com/sabre-io/xml/issues", "source": "https://github.com/fruux/sabre-xml" }, - "time": "2024-09-06T07:37:46+00:00" + "time": "2024-04-18T10:44:25+00:00" }, { "name": "symfony/console", - "version": "v6.4.15", + "version": "v6.4.17", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "f1fc6f47283e27336e7cebb9e8946c8de7bff9bd" + "reference": "799445db3f15768ecc382ac5699e6da0520a0a04" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/f1fc6f47283e27336e7cebb9e8946c8de7bff9bd", - "reference": "f1fc6f47283e27336e7cebb9e8946c8de7bff9bd", + "url": "https://api.github.com/repos/symfony/console/zipball/799445db3f15768ecc382ac5699e6da0520a0a04", + "reference": "799445db3f15768ecc382ac5699e6da0520a0a04", "shasum": "" }, "require": { @@ -490,7 +487,7 @@ "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v6.4.15" + "source": "https://github.com/symfony/console/tree/v6.4.17" }, "funding": [ { @@ -506,33 +503,33 @@ "type": "tidelift" } ], - "time": "2024-11-06T14:19:14+00:00" + "time": "2024-12-07T12:07:30+00:00" }, { "name": "symfony/deprecation-contracts", - "version": "v3.5.1", + "version": "v2.5.0", "source": { "type": "git", "url": "https://github.com/symfony/deprecation-contracts.git", - "reference": "74c71c939a79f7d5bf3c1ce9f5ea37ba0114c6f6" + "reference": "6f981ee24cf69ee7ce9736146d1c57c2780598a8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/74c71c939a79f7d5bf3c1ce9f5ea37ba0114c6f6", - "reference": "74c71c939a79f7d5bf3c1ce9f5ea37ba0114c6f6", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/6f981ee24cf69ee7ce9736146d1c57c2780598a8", + "reference": "6f981ee24cf69ee7ce9736146d1c57c2780598a8", "shasum": "" }, "require": { - "php": ">=8.1" + "php": ">=7.1" }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "3.5-dev" - }, "thanks": { - "name": "symfony/contracts", - "url": "https://github.com/symfony/contracts" + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, + "branch-alias": { + "dev-main": "2.5-dev" } }, "autoload": { @@ -557,7 +554,7 @@ "description": "A generic function and convention to trigger deprecation notices", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/deprecation-contracts/tree/v3.5.1" + "source": "https://github.com/symfony/deprecation-contracts/tree/v2.5.0" }, "funding": [ { @@ -573,36 +570,29 @@ "type": "tidelift" } ], - "time": "2024-09-25T14:20:29+00:00" + "time": "2021-07-12T14:48:14+00:00" }, { "name": "symfony/polyfill-ctype", - "version": "v1.31.0", + "version": "v1.8.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638" + "reference": "7cc359f1b7b80fc25ed7796be7d96adc9b354bae" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/a3cc8b044a6ea513310cbd48ef7333b384945638", - "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/7cc359f1b7b80fc25ed7796be7d96adc9b354bae", + "reference": "7cc359f1b7b80fc25ed7796be7d96adc9b354bae", "shasum": "" }, "require": { - "php": ">=7.2" - }, - "provide": { - "ext-ctype": "*" - }, - "suggest": { - "ext-ctype": "For best performance" + "php": ">=5.3.3" }, "type": "library", "extra": { - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" + "branch-alias": { + "dev-master": "1.8-dev" } }, "autoload": { @@ -618,13 +608,13 @@ "MIT" ], "authors": [ - { - "name": "Gert de Pagter", - "email": "BackEndTea@gmail.com" - }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" + }, + { + "name": "Gert de Pagter", + "email": "BackEndTea@gmail.com" } ], "description": "Symfony polyfill for ctype functions", @@ -636,49 +626,31 @@ "portable" ], "support": { - "source": "https://github.com/symfony/polyfill-ctype/tree/v1.31.0" + "source": "https://github.com/symfony/polyfill-ctype/tree/master" }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2024-09-09T11:45:10+00:00" + "time": "2018-04-30T19:57:29+00:00" }, { "name": "symfony/polyfill-intl-grapheme", - "version": "v1.31.0", + "version": "v1.0.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-grapheme.git", - "reference": "b9123926e3b7bc2f98c02ad54f6a4b02b91a8abe" + "reference": "9332d285b58a16b144b3bf0bfd3b6334d9a43006" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/b9123926e3b7bc2f98c02ad54f6a4b02b91a8abe", - "reference": "b9123926e3b7bc2f98c02ad54f6a4b02b91a8abe", + "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/9332d285b58a16b144b3bf0bfd3b6334d9a43006", + "reference": "9332d285b58a16b144b3bf0bfd3b6334d9a43006", "shasum": "" }, "require": { - "php": ">=7.2" - }, - "suggest": { - "ext-intl": "For best performance" + "php": ">=5.3.3" }, "type": "library", "extra": { - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" + "branch-alias": { + "dev-master": "1.0-dev" } }, "autoload": { @@ -714,49 +686,31 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.31.0" + "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/master" }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2024-09-09T11:45:10+00:00" + "time": "2015-11-04T20:28:58+00:00" }, { "name": "symfony/polyfill-intl-normalizer", - "version": "v1.31.0", + "version": "v1.0.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-normalizer.git", - "reference": "3833d7255cc303546435cb650316bff708a1c75c" + "reference": "b0235b9e98e224821e23018a9487764ad6dec859" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/3833d7255cc303546435cb650316bff708a1c75c", - "reference": "3833d7255cc303546435cb650316bff708a1c75c", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/b0235b9e98e224821e23018a9487764ad6dec859", + "reference": "b0235b9e98e224821e23018a9487764ad6dec859", "shasum": "" }, "require": { - "php": ">=7.2" - }, - "suggest": { - "ext-intl": "For best performance" + "php": ">=5.3.3" }, "type": "library", "extra": { - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" + "branch-alias": { + "dev-master": "1.0-dev" } }, "autoload": { @@ -795,52 +749,31 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.31.0" + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/master" }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2024-09-09T11:45:10+00:00" + "time": "2015-11-04T20:28:58+00:00" }, { "name": "symfony/polyfill-mbstring", - "version": "v1.31.0", + "version": "v1.0.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "85181ba99b2345b0ef10ce42ecac37612d9fd341" + "reference": "0b6a8940385311a24e060ec1fe35680e17c74497" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/85181ba99b2345b0ef10ce42ecac37612d9fd341", - "reference": "85181ba99b2345b0ef10ce42ecac37612d9fd341", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/0b6a8940385311a24e060ec1fe35680e17c74497", + "reference": "0b6a8940385311a24e060ec1fe35680e17c74497", "shasum": "" }, "require": { - "php": ">=7.2" - }, - "provide": { - "ext-mbstring": "*" - }, - "suggest": { - "ext-mbstring": "For best performance" + "php": ">=5.3.3" }, "type": "library", "extra": { - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" + "branch-alias": { + "dev-master": "1.0-dev" } }, "autoload": { @@ -875,63 +808,49 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.31.0" + "source": "https://github.com/symfony/polyfill-mbstring/tree/master" }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2024-09-09T11:45:10+00:00" + "time": "2015-11-04T20:28:58+00:00" }, { "name": "symfony/service-contracts", - "version": "v3.5.1", + "version": "v2.5.0", "source": { "type": "git", "url": "https://github.com/symfony/service-contracts.git", - "reference": "e53260aabf78fb3d63f8d79d69ece59f80d5eda0" + "reference": "1ab11b933cd6bc5464b08e81e2c5b07dec58b0fc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/service-contracts/zipball/e53260aabf78fb3d63f8d79d69ece59f80d5eda0", - "reference": "e53260aabf78fb3d63f8d79d69ece59f80d5eda0", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/1ab11b933cd6bc5464b08e81e2c5b07dec58b0fc", + "reference": "1ab11b933cd6bc5464b08e81e2c5b07dec58b0fc", "shasum": "" }, "require": { - "php": ">=8.1", - "psr/container": "^1.1|^2.0", - "symfony/deprecation-contracts": "^2.5|^3" + "php": ">=7.2.5", + "psr/container": "^1.1", + "symfony/deprecation-contracts": "^2.1" }, "conflict": { "ext-psr": "<1.1|>=2" }, + "suggest": { + "symfony/service-implementation": "" + }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "3.5-dev" - }, "thanks": { - "name": "symfony/contracts", - "url": "https://github.com/symfony/contracts" + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, + "branch-alias": { + "dev-main": "2.5-dev" } }, "autoload": { "psr-4": { "Symfony\\Contracts\\Service\\": "" - }, - "exclude-from-classmap": [ - "/Test/" - ] + } }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -958,7 +877,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/service-contracts/tree/v3.5.1" + "source": "https://github.com/symfony/service-contracts/tree/v2.5.0" }, "funding": [ { @@ -974,24 +893,24 @@ "type": "tidelift" } ], - "time": "2024-09-25T14:20:29+00:00" + "time": "2021-11-04T16:48:04+00:00" }, { "name": "symfony/string", - "version": "v7.2.0", + "version": "v6.4.15", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "446e0d146f991dde3e73f45f2c97a9faad773c82" + "reference": "73a5e66ea2e1677c98d4449177c5a9cf9d8b4c6f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/446e0d146f991dde3e73f45f2c97a9faad773c82", - "reference": "446e0d146f991dde3e73f45f2c97a9faad773c82", + "url": "https://api.github.com/repos/symfony/string/zipball/73a5e66ea2e1677c98d4449177c5a9cf9d8b4c6f", + "reference": "73a5e66ea2e1677c98d4449177c5a9cf9d8b4c6f", "shasum": "" }, "require": { - "php": ">=8.2", + "php": ">=8.1", "symfony/polyfill-ctype": "~1.8", "symfony/polyfill-intl-grapheme": "~1.0", "symfony/polyfill-intl-normalizer": "~1.0", @@ -1001,12 +920,11 @@ "symfony/translation-contracts": "<2.5" }, "require-dev": { - "symfony/emoji": "^7.1", - "symfony/error-handler": "^6.4|^7.0", - "symfony/http-client": "^6.4|^7.0", - "symfony/intl": "^6.4|^7.0", + "symfony/error-handler": "^5.4|^6.0|^7.0", + "symfony/http-client": "^5.4|^6.0|^7.0", + "symfony/intl": "^6.2|^7.0", "symfony/translation-contracts": "^2.5|^3.0", - "symfony/var-exporter": "^6.4|^7.0" + "symfony/var-exporter": "^5.4|^6.0|^7.0" }, "type": "library", "autoload": { @@ -1045,7 +963,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v7.2.0" + "source": "https://github.com/symfony/string/tree/v6.4.15" }, "funding": [ { @@ -1061,32 +979,34 @@ "type": "tidelift" } ], - "time": "2024-11-13T13:31:26+00:00" + "time": "2024-11-13T13:31:12+00:00" }, { "name": "symfony/yaml", - "version": "v6.4.13", + "version": "v6.0.0", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "e99b4e94d124b29ee4cf3140e1b537d2dad8cec9" + "reference": "f3064a2e0b5eabaeaf92db0a5913a77098b3b91e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/e99b4e94d124b29ee4cf3140e1b537d2dad8cec9", - "reference": "e99b4e94d124b29ee4cf3140e1b537d2dad8cec9", + "url": "https://api.github.com/repos/symfony/yaml/zipball/f3064a2e0b5eabaeaf92db0a5913a77098b3b91e", + "reference": "f3064a2e0b5eabaeaf92db0a5913a77098b3b91e", "shasum": "" }, "require": { - "php": ">=8.1", - "symfony/deprecation-contracts": "^2.5|^3", + "php": ">=8.0.2", "symfony/polyfill-ctype": "^1.8" }, "conflict": { "symfony/console": "<5.4" }, "require-dev": { - "symfony/console": "^5.4|^6.0|^7.0" + "symfony/console": "^5.4|^6.0" + }, + "suggest": { + "symfony/console": "For validating YAML files using the lint command" }, "bin": [ "Resources/bin/yaml-lint" @@ -1117,7 +1037,7 @@ "description": "Loads and dumps YAML files", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/yaml/tree/v6.4.13" + "source": "https://github.com/symfony/yaml/tree/v6.0.0" }, "funding": [ { @@ -1133,7 +1053,7 @@ "type": "tidelift" } ], - "time": "2024-09-25T14:18:03+00:00" + "time": "2021-11-28T15:34:37+00:00" }, { "name": "tomzx/finder", @@ -1254,23 +1174,23 @@ }, { "name": "wikimedia/less.php", - "version": "v5.1.2", + "version": "v5.1.0", "source": { "type": "git", "url": "https://github.com/wikimedia/less.php.git", - "reference": "39b1fbbdd3d95c5279f231d2298f3866fa869fcd" + "reference": "b66f3578a951ba666f8872cdbc2c6063787c8fdc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/wikimedia/less.php/zipball/39b1fbbdd3d95c5279f231d2298f3866fa869fcd", - "reference": "39b1fbbdd3d95c5279f231d2298f3866fa869fcd", + "url": "https://api.github.com/repos/wikimedia/less.php/zipball/b66f3578a951ba666f8872cdbc2c6063787c8fdc", + "reference": "b66f3578a951ba666f8872cdbc2c6063787c8fdc", "shasum": "" }, "require": { "php": ">=7.4.3" }, "require-dev": { - "mediawiki/mediawiki-codesniffer": "45.0.0", + "mediawiki/mediawiki-codesniffer": "43.0.0", "mediawiki/mediawiki-phan-config": "0.14.0", "mediawiki/minus-x": "1.1.3", "php-parallel-lint/php-console-highlighter": "1.0.0", @@ -1323,24 +1243,24 @@ ], "support": { "issues": "https://github.com/wikimedia/less.php/issues", - "source": "https://github.com/wikimedia/less.php/tree/v5.1.2" + "source": "https://github.com/wikimedia/less.php/tree/v5.1.0" }, - "time": "2024-11-13T15:44:20+00:00" + "time": "2024-08-06T21:12:41+00:00" } ], "packages-dev": [ { "name": "myclabs/deep-copy", - "version": "1.12.1", + "version": "1.12.0", "source": { "type": "git", "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "123267b2c49fbf30d78a7b2d333f6be754b94845" + "reference": "3a6b9a42cd8f8771bd4295d13e1423fa7f3d942c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/123267b2c49fbf30d78a7b2d333f6be754b94845", - "reference": "123267b2c49fbf30d78a7b2d333f6be754b94845", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/3a6b9a42cd8f8771bd4295d13e1423fa7f3d942c", + "reference": "3a6b9a42cd8f8771bd4295d13e1423fa7f3d942c", "shasum": "" }, "require": { @@ -1379,7 +1299,7 @@ ], "support": { "issues": "https://github.com/myclabs/DeepCopy/issues", - "source": "https://github.com/myclabs/DeepCopy/tree/1.12.1" + "source": "https://github.com/myclabs/DeepCopy/tree/1.12.0" }, "funding": [ { @@ -1387,7 +1307,7 @@ "type": "tidelift" } ], - "time": "2024-11-08T17:47:46+00:00" + "time": "2024-06-12T14:39:25+00:00" }, { "name": "phar-io/manifest", @@ -1509,32 +1429,32 @@ }, { "name": "phpunit/php-code-coverage", - "version": "10.1.16", + "version": "10.1.15", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "7e308268858ed6baedc8704a304727d20bc07c77" + "reference": "5da8b1728acd1e6ffdf2ff32ffbdfd04307f26ae" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/7e308268858ed6baedc8704a304727d20bc07c77", - "reference": "7e308268858ed6baedc8704a304727d20bc07c77", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/5da8b1728acd1e6ffdf2ff32ffbdfd04307f26ae", + "reference": "5da8b1728acd1e6ffdf2ff32ffbdfd04307f26ae", "shasum": "" }, "require": { "ext-dom": "*", "ext-libxml": "*", "ext-xmlwriter": "*", - "nikic/php-parser": "^4.19.1 || ^5.1.0", + "nikic/php-parser": "^4.18 || ^5.0", "php": ">=8.1", - "phpunit/php-file-iterator": "^4.1.0", - "phpunit/php-text-template": "^3.0.1", - "sebastian/code-unit-reverse-lookup": "^3.0.0", - "sebastian/complexity": "^3.2.0", - "sebastian/environment": "^6.1.0", - "sebastian/lines-of-code": "^2.0.2", - "sebastian/version": "^4.0.1", - "theseer/tokenizer": "^1.2.3" + "phpunit/php-file-iterator": "^4.0", + "phpunit/php-text-template": "^3.0", + "sebastian/code-unit-reverse-lookup": "^3.0", + "sebastian/complexity": "^3.0", + "sebastian/environment": "^6.0", + "sebastian/lines-of-code": "^2.0", + "sebastian/version": "^4.0", + "theseer/tokenizer": "^1.2.0" }, "require-dev": { "phpunit/phpunit": "^10.1" @@ -1546,7 +1466,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "10.1.x-dev" + "dev-main": "10.1-dev" } }, "autoload": { @@ -1575,7 +1495,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/10.1.16" + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/10.1.15" }, "funding": [ { @@ -1583,7 +1503,7 @@ "type": "github" } ], - "time": "2024-08-22T04:31:57+00:00" + "time": "2024-06-29T08:25:15+00:00" }, { "name": "phpunit/php-file-iterator", @@ -1830,16 +1750,16 @@ }, { "name": "phpunit/phpunit", - "version": "10.5.38", + "version": "10.5.28", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "a86773b9e887a67bc53efa9da9ad6e3f2498c132" + "reference": "ff7fb85cdf88131b83e721fb2a327b664dbed275" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/a86773b9e887a67bc53efa9da9ad6e3f2498c132", - "reference": "a86773b9e887a67bc53efa9da9ad6e3f2498c132", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/ff7fb85cdf88131b83e721fb2a327b664dbed275", + "reference": "ff7fb85cdf88131b83e721fb2a327b664dbed275", "shasum": "" }, "require": { @@ -1853,14 +1773,14 @@ "phar-io/manifest": "^2.0.4", "phar-io/version": "^3.2.1", "php": ">=8.1", - "phpunit/php-code-coverage": "^10.1.16", + "phpunit/php-code-coverage": "^10.1.15", "phpunit/php-file-iterator": "^4.1.0", "phpunit/php-invoker": "^4.0.0", "phpunit/php-text-template": "^3.0.1", "phpunit/php-timer": "^6.0.0", "sebastian/cli-parser": "^2.0.1", "sebastian/code-unit": "^2.0.0", - "sebastian/comparator": "^5.0.3", + "sebastian/comparator": "^5.0.1", "sebastian/diff": "^5.1.1", "sebastian/environment": "^6.1.0", "sebastian/exporter": "^5.1.2", @@ -1911,7 +1831,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", "security": "https://github.com/sebastianbergmann/phpunit/security/policy", - "source": "https://github.com/sebastianbergmann/phpunit/tree/10.5.38" + "source": "https://github.com/sebastianbergmann/phpunit/tree/10.5.28" }, "funding": [ { @@ -1927,7 +1847,7 @@ "type": "tidelift" } ], - "time": "2024-10-28T13:06:21+00:00" + "time": "2024-07-18T14:54:16+00:00" }, { "name": "sebastian/cli-parser", @@ -2099,16 +2019,16 @@ }, { "name": "sebastian/comparator", - "version": "5.0.3", + "version": "5.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "a18251eb0b7a2dcd2f7aa3d6078b18545ef0558e" + "reference": "2db5010a484d53ebf536087a70b4a5423c102372" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/a18251eb0b7a2dcd2f7aa3d6078b18545ef0558e", - "reference": "a18251eb0b7a2dcd2f7aa3d6078b18545ef0558e", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/2db5010a484d53ebf536087a70b4a5423c102372", + "reference": "2db5010a484d53ebf536087a70b4a5423c102372", "shasum": "" }, "require": { @@ -2119,7 +2039,7 @@ "sebastian/exporter": "^5.0" }, "require-dev": { - "phpunit/phpunit": "^10.5" + "phpunit/phpunit": "^10.3" }, "type": "library", "extra": { @@ -2164,7 +2084,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/comparator/issues", "security": "https://github.com/sebastianbergmann/comparator/security/policy", - "source": "https://github.com/sebastianbergmann/comparator/tree/5.0.3" + "source": "https://github.com/sebastianbergmann/comparator/tree/5.0.1" }, "funding": [ { @@ -2172,24 +2092,24 @@ "type": "github" } ], - "time": "2024-10-18T14:56:07+00:00" + "time": "2023-08-14T13:18:12+00:00" }, { "name": "sebastian/complexity", - "version": "3.2.0", + "version": "3.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/complexity.git", - "reference": "68ff824baeae169ec9f2137158ee529584553799" + "reference": "e67d240970c9dc7ea7b2123a6d520e334dd61dc6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/68ff824baeae169ec9f2137158ee529584553799", - "reference": "68ff824baeae169ec9f2137158ee529584553799", + "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/e67d240970c9dc7ea7b2123a6d520e334dd61dc6", + "reference": "e67d240970c9dc7ea7b2123a6d520e334dd61dc6", "shasum": "" }, "require": { - "nikic/php-parser": "^4.18 || ^5.0", + "nikic/php-parser": "^4.10", "php": ">=8.1" }, "require-dev": { @@ -2198,7 +2118,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "3.2-dev" + "dev-main": "3.0-dev" } }, "autoload": { @@ -2221,8 +2141,7 @@ "homepage": "https://github.com/sebastianbergmann/complexity", "support": { "issues": "https://github.com/sebastianbergmann/complexity/issues", - "security": "https://github.com/sebastianbergmann/complexity/security/policy", - "source": "https://github.com/sebastianbergmann/complexity/tree/3.2.0" + "source": "https://github.com/sebastianbergmann/complexity/tree/3.0.0" }, "funding": [ { @@ -2230,7 +2149,7 @@ "type": "github" } ], - "time": "2023-12-21T08:37:17+00:00" + "time": "2023-02-03T06:59:47+00:00" }, { "name": "sebastian/diff", @@ -2505,20 +2424,20 @@ }, { "name": "sebastian/lines-of-code", - "version": "2.0.2", + "version": "2.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/lines-of-code.git", - "reference": "856e7f6a75a84e339195d48c556f23be2ebf75d0" + "reference": "17c4d940ecafb3d15d2cf916f4108f664e28b130" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/856e7f6a75a84e339195d48c556f23be2ebf75d0", - "reference": "856e7f6a75a84e339195d48c556f23be2ebf75d0", + "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/17c4d940ecafb3d15d2cf916f4108f664e28b130", + "reference": "17c4d940ecafb3d15d2cf916f4108f664e28b130", "shasum": "" }, "require": { - "nikic/php-parser": "^4.18 || ^5.0", + "nikic/php-parser": "^4.10", "php": ">=8.1" }, "require-dev": { @@ -2550,8 +2469,7 @@ "homepage": "https://github.com/sebastianbergmann/lines-of-code", "support": { "issues": "https://github.com/sebastianbergmann/lines-of-code/issues", - "security": "https://github.com/sebastianbergmann/lines-of-code/security/policy", - "source": "https://github.com/sebastianbergmann/lines-of-code/tree/2.0.2" + "source": "https://github.com/sebastianbergmann/lines-of-code/tree/2.0.0" }, "funding": [ { @@ -2559,7 +2477,7 @@ "type": "github" } ], - "time": "2023-12-21T08:38:20+00:00" + "time": "2023-02-03T07:08:02+00:00" }, { "name": "sebastian/object-enumerator", @@ -2847,16 +2765,16 @@ }, { "name": "squizlabs/php_codesniffer", - "version": "3.6.2", + "version": "3.6.0", "source": { "type": "git", "url": "https://github.com/PHPCSStandards/PHP_CodeSniffer.git", - "reference": "5e4e71592f69da17871dba6e80dd51bce74a351a" + "reference": "ffced0d2c8fa8e6cdc4d695a743271fab6c38625" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHPCSStandards/PHP_CodeSniffer/zipball/5e4e71592f69da17871dba6e80dd51bce74a351a", - "reference": "5e4e71592f69da17871dba6e80dd51bce74a351a", + "url": "https://api.github.com/repos/PHPCSStandards/PHP_CodeSniffer/zipball/ffced0d2c8fa8e6cdc4d695a743271fab6c38625", + "reference": "ffced0d2c8fa8e6cdc4d695a743271fab6c38625", "shasum": "" }, "require": { @@ -2913,20 +2831,20 @@ "type": "open_collective" } ], - "time": "2021-12-12T21:44:58+00:00" + "time": "2021-04-09T00:54:41+00:00" }, { "name": "theseer/tokenizer", - "version": "1.2.3", + "version": "1.2.0", "source": { "type": "git", "url": "https://github.com/theseer/tokenizer.git", - "reference": "737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2" + "reference": "75a63c33a8577608444246075ea0af0d052e452a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/theseer/tokenizer/zipball/737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2", - "reference": "737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2", + "url": "https://api.github.com/repos/theseer/tokenizer/zipball/75a63c33a8577608444246075ea0af0d052e452a", + "reference": "75a63c33a8577608444246075ea0af0d052e452a", "shasum": "" }, "require": { @@ -2955,7 +2873,7 @@ "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", "support": { "issues": "https://github.com/theseer/tokenizer/issues", - "source": "https://github.com/theseer/tokenizer/tree/1.2.3" + "source": "https://github.com/theseer/tokenizer/tree/master" }, "funding": [ { @@ -2963,7 +2881,7 @@ "type": "github" } ], - "time": "2024-03-03T12:36:25+00:00" + "time": "2020-07-12T23:59:07+00:00" } ], "aliases": [], From 3a5f43f3d406f342ef7f6d9bf60e8a20751f6efa Mon Sep 17 00:00:00 2001 From: Bhavin Parmar Date: Fri, 16 May 2025 12:19:45 +0530 Subject: [PATCH 30/55] AC-14557:: False positives in the backward-incompatible changes report (SVC) --- composer.json | 2 +- composer.lock | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/composer.json b/composer.json index aee893ba..05d0279f 100644 --- a/composer.json +++ b/composer.json @@ -13,7 +13,7 @@ "laminas/laminas-stdlib": "^3.18", "nikic/php-parser": "^4.19", "phpstan/phpdoc-parser": "^0.5.5", - "sabre/xml": "~4.0.5", + "sabre/xml": "~4.0.6", "symfony/console": "~6.4.17", "symfony/string": "~6.4.15", "tomzx/php-semver-checker": "^0.16.0", diff --git a/composer.lock b/composer.lock index 86ddcee3..88c3c339 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "480ed8ade9fa6af94e4454d3bc8866f7", + "content-hash": "398f0dec67372bf5b99c5305508d6510", "packages": [ { "name": "hassankhan/config", @@ -344,16 +344,16 @@ }, { "name": "sabre/xml", - "version": "4.0.5", + "version": "4.0.6", "source": { "type": "git", "url": "https://github.com/sabre-io/xml.git", - "reference": "c29e49fcf9ca8ca058b1e350ee9abe4205c0de89" + "reference": "a89257fd188ce30e456b841b6915f27905dfdbe3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sabre-io/xml/zipball/c29e49fcf9ca8ca058b1e350ee9abe4205c0de89", - "reference": "c29e49fcf9ca8ca058b1e350ee9abe4205c0de89", + "url": "https://api.github.com/repos/sabre-io/xml/zipball/a89257fd188ce30e456b841b6915f27905dfdbe3", + "reference": "a89257fd188ce30e456b841b6915f27905dfdbe3", "shasum": "" }, "require": { @@ -365,8 +365,8 @@ "sabre/uri": ">=2.0,<4.0.0" }, "require-dev": { - "friendsofphp/php-cs-fixer": "^3.51", - "phpstan/phpstan": "^1.10", + "friendsofphp/php-cs-fixer": "^3.64", + "phpstan/phpstan": "^1.12", "phpunit/phpunit": "^9.6" }, "type": "library", @@ -409,7 +409,7 @@ "issues": "https://github.com/sabre-io/xml/issues", "source": "https://github.com/fruux/sabre-xml" }, - "time": "2024-04-18T10:44:25+00:00" + "time": "2024-09-06T08:00:55+00:00" }, { "name": "symfony/console", From 6c35f07b1c6fdf5d15ba5a83cd245ac8aa5a7a27 Mon Sep 17 00:00:00 2001 From: Bhavin Parmar Date: Fri, 16 May 2025 13:30:05 +0530 Subject: [PATCH 31/55] AC-14557:: False positives in the backward-incompatible changes report (SVC) --- src/Analyzer/ClassMethodAnalyzer.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/Analyzer/ClassMethodAnalyzer.php b/src/Analyzer/ClassMethodAnalyzer.php index c399e433..d92399e1 100644 --- a/src/Analyzer/ClassMethodAnalyzer.php +++ b/src/Analyzer/ClassMethodAnalyzer.php @@ -264,6 +264,11 @@ protected function reportChanged($report, $contextBefore, $contextAfter, $method $contextAfter, $methodAfter ); + echo "\nTemporary added code \n"; + print_r($data); + echo "\n======\n"; + print_r($data, true); + echo "\nEnd Temporary added code \n"; $report->add($this->context, $data); $signatureChanged = true; } From ec362ac67a5aea30f238cfbb8b1e2bbe1f5534d1 Mon Sep 17 00:00:00 2001 From: Bhavin Parmar Date: Fri, 16 May 2025 15:17:03 +0530 Subject: [PATCH 32/55] AC-14557:: False positives in the backward-incompatible changes report (SVC) --- src/Analyzer/ClassMethodAnalyzer.php | 52 ++++++++++++++---- ...ssMethodParameterTypingChangedNullable.php | 54 +++++++++++++++++++ 2 files changed, 95 insertions(+), 11 deletions(-) create mode 100644 src/Operation/ClassMethodParameterTypingChangedNullable.php diff --git a/src/Analyzer/ClassMethodAnalyzer.php b/src/Analyzer/ClassMethodAnalyzer.php index d92399e1..c148c31a 100644 --- a/src/Analyzer/ClassMethodAnalyzer.php +++ b/src/Analyzer/ClassMethodAnalyzer.php @@ -20,6 +20,7 @@ use Magento\SemanticVersionChecker\Operation\ClassMethodOptionalParameterAdded; use Magento\SemanticVersionChecker\Operation\ClassMethodOverwriteAdded; use Magento\SemanticVersionChecker\Operation\ClassMethodParameterTypingChanged; +use Magento\SemanticVersionChecker\Operation\ClassMethodParameterTypingChangedNullable; use Magento\SemanticVersionChecker\Operation\ClassMethodReturnTypingChanged; use Magento\SemanticVersionChecker\Operation\ExtendableClassConstructorOptionalParameterAdded; use Magento\SemanticVersionChecker\Operation\Visibility\MethodDecreased as VisibilityMethodDecreased; @@ -258,17 +259,46 @@ protected function reportChanged($report, $contextBefore, $contextAfter, $method $report->add($this->context, $data); $signatureChanged = true; } elseif ($signatureChanges['parameter_typing_changed']) { - $data = new ClassMethodParameterTypingChanged( - $this->context, - $this->fileAfter, - $contextAfter, - $methodAfter - ); - echo "\nTemporary added code \n"; - print_r($data); - echo "\n======\n"; - print_r($data, true); - echo "\nEnd Temporary added code \n"; + $paramsBefore = $methodBefore->params; + $paramsAfter = $methodAfter->params; + + $isSafeNullableChange = false; + // Check if only difference is added explicit nullable `?` prefix + foreach ($paramsBefore as $index => $paramBefore) { + $paramAfter = $paramsAfter[$index] ?? null; + if (!$paramAfter) { + continue; + } + + $beforeType = $paramBefore->type; + $afterType = $paramAfter->type; + + if ($beforeType && $afterType && + $beforeType instanceof \PhpParser\Node\Name && + $afterType instanceof \PhpParser\Node\NullableType && + $afterType->type instanceof \PhpParser\Node\Name && + $beforeType->toString() === $afterType->type->toString()) { + $isSafeNullableChange = true; + } else { + $isSafeNullableChange = false; + break; + } + } + if ($isSafeNullableChange) { + $data = new ClassMethodParameterTypingChangedNullable( + $this->context, + $this->fileAfter, + $contextAfter, + $methodAfter + ); + } else { + $data = new ClassMethodParameterTypingChanged( + $this->context, + $this->fileAfter, + $contextAfter, + $methodAfter + ); + } $report->add($this->context, $data); $signatureChanged = true; } diff --git a/src/Operation/ClassMethodParameterTypingChangedNullable.php b/src/Operation/ClassMethodParameterTypingChangedNullable.php new file mode 100644 index 00000000..e800805a --- /dev/null +++ b/src/Operation/ClassMethodParameterTypingChangedNullable.php @@ -0,0 +1,54 @@ + ['M113', 'M114', 'M115'], + 'interface' => ['M116'], + 'trait' => ['M117', 'M118', 'M119'] + ]; + + /** + * @var array + */ + private $mapping = [ + 'M113' => Level::PATCH, + 'M114' => Level::MAJOR, + 'M115' => Level::PATCH, + 'M116' => Level::MAJOR, + 'M117' => Level::MAJOR, + 'M118' => Level::MAJOR, + 'M119' => Level::MAJOR + ]; + + + /** + * @var string + */ + protected $reason = 'Method parameter typing changed.'; + + /** + * Returns level of error. + * + * @return mixed + */ + public function getLevel(): int + { + return $this->mapping[$this->getCode()]; + } +} From 0c85e29f3d1c3ca0159d1d6d44b90e5f8bd61714 Mon Sep 17 00:00:00 2001 From: Bhavin Parmar Date: Fri, 16 May 2025 16:07:56 +0530 Subject: [PATCH 33/55] AC-14557:: False positives in the backward-incompatible changes report (SVC) --- src/Analyzer/ClassMethodAnalyzer.php | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/Analyzer/ClassMethodAnalyzer.php b/src/Analyzer/ClassMethodAnalyzer.php index c148c31a..e6b72001 100644 --- a/src/Analyzer/ClassMethodAnalyzer.php +++ b/src/Analyzer/ClassMethodAnalyzer.php @@ -272,7 +272,23 @@ protected function reportChanged($report, $contextBefore, $contextAfter, $method $beforeType = $paramBefore->type; $afterType = $paramAfter->type; - + echo "\nBefore type\n"; + print_r($beforeType); + echo "\nAfter type\n"; + print_r($afterType); + echo "\nBefore Instance of Name\n"; + print_r($beforeType instanceof \PhpParser\Node\Name); + echo "\nAfter Instance of NullableType\n"; + print_r($afterType instanceof \PhpParser\Node\NullableType); + echo "\nAfter Instance of Name\n"; + echo "Beforetype is ".$beforeType->toString(). " Aftertype is ".$afterType->toString()."\n"; + + + echo "\n----------------------\n"; + echo "\nBefore Instance of NullableType\n"; + print_r($beforeType instanceof \PhpParser\Node\NullableType); + + echo "\n----------------------\n"; if ($beforeType && $afterType && $beforeType instanceof \PhpParser\Node\Name && $afterType instanceof \PhpParser\Node\NullableType && From 1b3b365462c05a02e565862e8148807d37c16b90 Mon Sep 17 00:00:00 2001 From: Bhavin Parmar Date: Fri, 16 May 2025 16:59:10 +0530 Subject: [PATCH 34/55] AC-14557:: False positives in the backward-incompatible changes report (SVC) --- src/Analyzer/ClassMethodAnalyzer.php | 72 ++++++++++++++-------------- 1 file changed, 35 insertions(+), 37 deletions(-) diff --git a/src/Analyzer/ClassMethodAnalyzer.php b/src/Analyzer/ClassMethodAnalyzer.php index e6b72001..7b305d04 100644 --- a/src/Analyzer/ClassMethodAnalyzer.php +++ b/src/Analyzer/ClassMethodAnalyzer.php @@ -259,54 +259,51 @@ protected function reportChanged($report, $contextBefore, $contextAfter, $method $report->add($this->context, $data); $signatureChanged = true; } elseif ($signatureChanges['parameter_typing_changed']) { - $paramsBefore = $methodBefore->params; - $paramsAfter = $methodAfter->params; - - $isSafeNullableChange = false; - // Check if only difference is added explicit nullable `?` prefix - foreach ($paramsBefore as $index => $paramBefore) { - $paramAfter = $paramsAfter[$index] ?? null; - if (!$paramAfter) { - continue; + // Compare each param to detect if it's only an implicit-nullable to explicit-nullable change + $isSafeNullableChange = true; + $paramCount = min(count($paramsBefore), count($paramsAfter)); + for ($i = 0; $i < $paramCount; $i++) { + $beforeParam = $paramsBefore[$i]; + $afterParam = $paramsAfter[$i]; + + $beforeType = $beforeParam->type; + $afterType = $afterParam->type; + + $beforeDefaultIsNull = isset($beforeParam->default) && $beforeParam->default->value === null; + print_r("Default value: $beforeParam->default->value\n"); + + // Case: type changed from no type but default null → ?Type + if ($beforeType === null && $afterType instanceof \PhpParser\Node\NullableType && $beforeDefaultIsNull) { + continue; // safe } - - $beforeType = $paramBefore->type; - $afterType = $paramAfter->type; - echo "\nBefore type\n"; - print_r($beforeType); - echo "\nAfter type\n"; - print_r($afterType); - echo "\nBefore Instance of Name\n"; - print_r($beforeType instanceof \PhpParser\Node\Name); - echo "\nAfter Instance of NullableType\n"; - print_r($afterType instanceof \PhpParser\Node\NullableType); - echo "\nAfter Instance of Name\n"; - echo "Beforetype is ".$beforeType->toString(). " Aftertype is ".$afterType->toString()."\n"; - - - echo "\n----------------------\n"; - echo "\nBefore Instance of NullableType\n"; - print_r($beforeType instanceof \PhpParser\Node\NullableType); - - echo "\n----------------------\n"; - if ($beforeType && $afterType && - $beforeType instanceof \PhpParser\Node\Name && + echo "\nafter type nullable\n"; + var_dump($afterType instanceof \PhpParser\Node\NullableType); + echo "\nbefore type nullable\n"; + var_dump($beforeType instanceof \PhpParser\Node\NullableType); + + // Case: type changed from Type to ?Type (explicitly nullable) + if ( + $beforeType instanceof \PhpParser\Node\Identifier && $afterType instanceof \PhpParser\Node\NullableType && - $afterType->type instanceof \PhpParser\Node\Name && - $beforeType->toString() === $afterType->type->toString()) { - $isSafeNullableChange = true; - } else { - $isSafeNullableChange = false; - break; + $afterType->type instanceof \PhpParser\Node\Identifier && + $beforeType->name === $afterType->type->name && + $beforeDefaultIsNull + ) { + continue; // safe } + + $isSafeNullableChange = false; + break; } if ($isSafeNullableChange) { + // Treat as PATCH instead of MAJOR $data = new ClassMethodParameterTypingChangedNullable( $this->context, $this->fileAfter, $contextAfter, $methodAfter ); + // $report->add($this->context, $data); } else { $data = new ClassMethodParameterTypingChanged( $this->context, @@ -314,6 +311,7 @@ protected function reportChanged($report, $contextBefore, $contextAfter, $method $contextAfter, $methodAfter ); + } $report->add($this->context, $data); $signatureChanged = true; From 3d4768d54d3dd02f407fb8a9719bf4d1165865fc Mon Sep 17 00:00:00 2001 From: Bhavin Parmar Date: Fri, 16 May 2025 18:39:35 +0530 Subject: [PATCH 35/55] AC-14557:: False positives in the backward-incompatible changes report (SVC) --- src/Analyzer/ClassMethodAnalyzer.php | 29 ++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/src/Analyzer/ClassMethodAnalyzer.php b/src/Analyzer/ClassMethodAnalyzer.php index 7b305d04..355c9c44 100644 --- a/src/Analyzer/ClassMethodAnalyzer.php +++ b/src/Analyzer/ClassMethodAnalyzer.php @@ -266,8 +266,24 @@ protected function reportChanged($report, $contextBefore, $contextAfter, $method $beforeParam = $paramsBefore[$i]; $afterParam = $paramsAfter[$i]; + // $beforeParam-> + $beforeType = $beforeParam->type; $afterType = $afterParam->type; + // $beforeParam->default-> + + $beforeNullable = $this->isNullable($beforeType); + $afterNullable = $this->isNullable($afterType); + + $beforeTypeName = $this->getTypeName($beforeType); + $afterTypeName = $this->getTypeName($afterType); + + if ($beforeNullable !== $afterNullable && $beforeTypeName === $afterTypeName) { + echo "️Nullable type change detected for parameter \${$beforeParam->var->name}:\n"; + echo "Before: " . ($beforeNullable ? '?' : '') . $beforeTypeName . "\n"; + echo "After: " . ($afterNullable ? '?' : '') . $afterTypeName . "\n"; + } + $beforeDefaultIsNull = isset($beforeParam->default) && $beforeParam->default->value === null; print_r("Default value: $beforeParam->default->value\n"); @@ -421,6 +437,19 @@ protected function reportChanged($report, $contextBefore, $contextAfter, $method } } + private function isNullable($type): bool { + return $type instanceof \PhpParser\Node\NullableType; + } + + private function getTypeName($type): ?string { + if ($type instanceof \PhpParser\Node\NullableType) { + return $type->type instanceof \PhpParser\Node\Identifier ? $type->type->name : null; + } elseif ($type instanceof \PhpParser\Node\Identifier) { + return $type->name; + } + return null; // For union types or no type + } + /** * Checks if return type declaration or annotation was changed * From 3a5091ec82ffc4e44f93bbb969a23dccee75fe9a Mon Sep 17 00:00:00 2001 From: Bhavin Parmar Date: Fri, 16 May 2025 20:43:58 +0530 Subject: [PATCH 36/55] AC-14557:: False positives in the backward-incompatible changes report (SVC) --- src/Analyzer/ClassMethodAnalyzer.php | 82 ++++------------------------ 1 file changed, 10 insertions(+), 72 deletions(-) diff --git a/src/Analyzer/ClassMethodAnalyzer.php b/src/Analyzer/ClassMethodAnalyzer.php index 355c9c44..e12fad05 100644 --- a/src/Analyzer/ClassMethodAnalyzer.php +++ b/src/Analyzer/ClassMethodAnalyzer.php @@ -20,7 +20,6 @@ use Magento\SemanticVersionChecker\Operation\ClassMethodOptionalParameterAdded; use Magento\SemanticVersionChecker\Operation\ClassMethodOverwriteAdded; use Magento\SemanticVersionChecker\Operation\ClassMethodParameterTypingChanged; -use Magento\SemanticVersionChecker\Operation\ClassMethodParameterTypingChangedNullable; use Magento\SemanticVersionChecker\Operation\ClassMethodReturnTypingChanged; use Magento\SemanticVersionChecker\Operation\ExtendableClassConstructorOptionalParameterAdded; use Magento\SemanticVersionChecker\Operation\Visibility\MethodDecreased as VisibilityMethodDecreased; @@ -259,67 +258,20 @@ protected function reportChanged($report, $contextBefore, $contextAfter, $method $report->add($this->context, $data); $signatureChanged = true; } elseif ($signatureChanges['parameter_typing_changed']) { - // Compare each param to detect if it's only an implicit-nullable to explicit-nullable change - $isSafeNullableChange = true; - $paramCount = min(count($paramsBefore), count($paramsAfter)); - for ($i = 0; $i < $paramCount; $i++) { - $beforeParam = $paramsBefore[$i]; - $afterParam = $paramsAfter[$i]; - - // $beforeParam-> - - $beforeType = $beforeParam->type; - $afterType = $afterParam->type; - // $beforeParam->default-> - - $beforeNullable = $this->isNullable($beforeType); - $afterNullable = $this->isNullable($afterType); - - $beforeTypeName = $this->getTypeName($beforeType); - $afterTypeName = $this->getTypeName($afterType); - - if ($beforeNullable !== $afterNullable && $beforeTypeName === $afterTypeName) { - echo "️Nullable type change detected for parameter \${$beforeParam->var->name}:\n"; - echo "Before: " . ($beforeNullable ? '?' : '') . $beforeTypeName . "\n"; - echo "After: " . ($afterNullable ? '?' : '') . $afterTypeName . "\n"; - } - - - $beforeDefaultIsNull = isset($beforeParam->default) && $beforeParam->default->value === null; - print_r("Default value: $beforeParam->default->value\n"); - - // Case: type changed from no type but default null → ?Type - if ($beforeType === null && $afterType instanceof \PhpParser\Node\NullableType && $beforeDefaultIsNull) { - continue; // safe - } - echo "\nafter type nullable\n"; - var_dump($afterType instanceof \PhpParser\Node\NullableType); - echo "\nbefore type nullable\n"; - var_dump($beforeType instanceof \PhpParser\Node\NullableType); - - // Case: type changed from Type to ?Type (explicitly nullable) - if ( - $beforeType instanceof \PhpParser\Node\Identifier && - $afterType instanceof \PhpParser\Node\NullableType && - $afterType->type instanceof \PhpParser\Node\Identifier && - $beforeType->name === $afterType->type->name && - $beforeDefaultIsNull - ) { - continue; // safe - } - - $isSafeNullableChange = false; - break; - } - if ($isSafeNullableChange) { - // Treat as PATCH instead of MAJOR - $data = new ClassMethodParameterTypingChangedNullable( + $paramBefore = $paramsBefore[$signatureChanges['changed_param_index']]; + $paramAfter = $paramsAfter[$signatureChanges['changed_param_index']]; + + if ( + $paramAfter->type instanceof NullableType && + !($paramBefore->type instanceof NullableType) + ) { + $data = new \Magento\SemanticVersionChecker\Operation\ClassMethodParameterTypingChangedNullable( $this->context, $this->fileAfter, $contextAfter, $methodAfter ); - // $report->add($this->context, $data); + $report->add($this->context, $data); } else { $data = new ClassMethodParameterTypingChanged( $this->context, @@ -327,9 +279,8 @@ protected function reportChanged($report, $contextBefore, $contextAfter, $method $contextAfter, $methodAfter ); - + $report->add($this->context, $data); } - $report->add($this->context, $data); $signatureChanged = true; } @@ -437,19 +388,6 @@ protected function reportChanged($report, $contextBefore, $contextAfter, $method } } - private function isNullable($type): bool { - return $type instanceof \PhpParser\Node\NullableType; - } - - private function getTypeName($type): ?string { - if ($type instanceof \PhpParser\Node\NullableType) { - return $type->type instanceof \PhpParser\Node\Identifier ? $type->type->name : null; - } elseif ($type instanceof \PhpParser\Node\Identifier) { - return $type->name; - } - return null; // For union types or no type - } - /** * Checks if return type declaration or annotation was changed * From 6289bd2cc81c04b277d25b1bf78e7679dd67cfbe Mon Sep 17 00:00:00 2001 From: Bhavin Parmar Date: Mon, 19 May 2025 15:55:33 +0530 Subject: [PATCH 37/55] AC-14557:: False positives in the backward-incompatible changes report (SVC) --- src/Analyzer/ClassMethodAnalyzer.php | 12 +++++------- src/Comparator/Signature.php | 17 +++++++++++++++-- 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/src/Analyzer/ClassMethodAnalyzer.php b/src/Analyzer/ClassMethodAnalyzer.php index e12fad05..320654ee 100644 --- a/src/Analyzer/ClassMethodAnalyzer.php +++ b/src/Analyzer/ClassMethodAnalyzer.php @@ -41,6 +41,7 @@ use PHPSemVerChecker\Operation\ClassMethodParameterTypingRemoved; use PHPSemVerChecker\Operation\ClassMethodRemoved; use PHPSemVerChecker\Report\Report; +use Magento\SemanticVersionChecker\Operation\ClassMethodParameterTypingChangedNullable; /** * Class method analyzer. @@ -258,20 +259,17 @@ protected function reportChanged($report, $contextBefore, $contextAfter, $method $report->add($this->context, $data); $signatureChanged = true; } elseif ($signatureChanges['parameter_typing_changed']) { - $paramBefore = $paramsBefore[$signatureChanges['changed_param_index']]; - $paramAfter = $paramsAfter[$signatureChanges['changed_param_index']]; if ( - $paramAfter->type instanceof NullableType && - !($paramBefore->type instanceof NullableType) + $signatureChanges['parameter_nullable_type_added'] || + $signatureChanges['parameter_nullable_type_removed'] ) { - $data = new \Magento\SemanticVersionChecker\Operation\ClassMethodParameterTypingChangedNullable( + $data = new ClassMethodParameterTypingChangedNullable( $this->context, $this->fileAfter, $contextAfter, $methodAfter ); - $report->add($this->context, $data); } else { $data = new ClassMethodParameterTypingChanged( $this->context, @@ -279,8 +277,8 @@ protected function reportChanged($report, $contextBefore, $contextAfter, $method $contextAfter, $methodAfter ); - $report->add($this->context, $data); } + $report->add($this->context, $data); $signatureChanged = true; } diff --git a/src/Comparator/Signature.php b/src/Comparator/Signature.php index 2ce20c1a..42e5c096 100644 --- a/src/Comparator/Signature.php +++ b/src/Comparator/Signature.php @@ -130,18 +130,32 @@ public static function analyze(array $parametersA, array $parametersB): array $changes = array_merge($changes, [ 'parameter_typing_added' => false, 'parameter_typing_removed' => false, - 'parameter_typing_changed' => false + 'parameter_typing_changed' => false, + 'parameter_nullable_type_added' => false, + 'parameter_nullable_type_removed' => false, + 'changed_param_index' => 0 ]); $lengthA = count($parametersA); $lengthB = count($parametersB); $iterations = min($lengthA, $lengthB); for ($i = 0; $i < $iterations; ++$i) { + + $typeBefore = $parametersA[$i]->type; + $typeAfter = $parametersB[$i]->type; // Re-implement type checking to handle type changes as a single operation instead of both add and remove if (Type::get($parametersA[$i]->type) !== Type::get($parametersB[$i]->type)) { // This section changed from parent::analyze() to handle typing changes if ($parametersA[$i]->type !== null && $parametersB[$i]->type !== null) { $changes['parameter_typing_changed'] = true; + // Custom: detect nullable added + if ($typeBefore instanceof \PhpParser\Node\NullableType && !$typeAfter instanceof \PhpParser\Node\NullableType) { + $changes['parameter_nullable_type_removed'] = true; + $changes['changed_param_index'] = $i; + } elseif (!$typeBefore instanceof \PhpParser\Node\NullableType && $typeAfter instanceof \PhpParser\Node\NullableType) { + $changes['parameter_nullable_type_added'] = true; + $changes['changed_param_index'] = $i; + } } elseif ($parametersA[$i]->type !== null) { $changes['parameter_typing_removed'] = true; } elseif ($parametersB[$i]->type !== null) { @@ -149,7 +163,6 @@ public static function analyze(array $parametersA, array $parametersB): array } } } - return $changes; } } From c727314339beb07a919afe525520317ca13e7e95 Mon Sep 17 00:00:00 2001 From: Rajesh Kumar Date: Tue, 20 May 2025 17:38:52 +0530 Subject: [PATCH 38/55] AC-14557:: False positives in the backward-incompatible changes report (SVC) --- composer.json | 2 +- composer.lock | 16 +++--- src/Analyzer/ClassMethodAnalyzer.php | 26 ++++++--- src/Comparator/Signature.php | 17 +++++- ...ssMethodParameterTypingChangedNullable.php | 54 +++++++++++++++++++ 5 files changed, 98 insertions(+), 17 deletions(-) create mode 100644 src/Operation/ClassMethodParameterTypingChangedNullable.php diff --git a/composer.json b/composer.json index aee893ba..05d0279f 100644 --- a/composer.json +++ b/composer.json @@ -13,7 +13,7 @@ "laminas/laminas-stdlib": "^3.18", "nikic/php-parser": "^4.19", "phpstan/phpdoc-parser": "^0.5.5", - "sabre/xml": "~4.0.5", + "sabre/xml": "~4.0.6", "symfony/console": "~6.4.17", "symfony/string": "~6.4.15", "tomzx/php-semver-checker": "^0.16.0", diff --git a/composer.lock b/composer.lock index 86ddcee3..88c3c339 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "480ed8ade9fa6af94e4454d3bc8866f7", + "content-hash": "398f0dec67372bf5b99c5305508d6510", "packages": [ { "name": "hassankhan/config", @@ -344,16 +344,16 @@ }, { "name": "sabre/xml", - "version": "4.0.5", + "version": "4.0.6", "source": { "type": "git", "url": "https://github.com/sabre-io/xml.git", - "reference": "c29e49fcf9ca8ca058b1e350ee9abe4205c0de89" + "reference": "a89257fd188ce30e456b841b6915f27905dfdbe3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sabre-io/xml/zipball/c29e49fcf9ca8ca058b1e350ee9abe4205c0de89", - "reference": "c29e49fcf9ca8ca058b1e350ee9abe4205c0de89", + "url": "https://api.github.com/repos/sabre-io/xml/zipball/a89257fd188ce30e456b841b6915f27905dfdbe3", + "reference": "a89257fd188ce30e456b841b6915f27905dfdbe3", "shasum": "" }, "require": { @@ -365,8 +365,8 @@ "sabre/uri": ">=2.0,<4.0.0" }, "require-dev": { - "friendsofphp/php-cs-fixer": "^3.51", - "phpstan/phpstan": "^1.10", + "friendsofphp/php-cs-fixer": "^3.64", + "phpstan/phpstan": "^1.12", "phpunit/phpunit": "^9.6" }, "type": "library", @@ -409,7 +409,7 @@ "issues": "https://github.com/sabre-io/xml/issues", "source": "https://github.com/fruux/sabre-xml" }, - "time": "2024-04-18T10:44:25+00:00" + "time": "2024-09-06T08:00:55+00:00" }, { "name": "symfony/console", diff --git a/src/Analyzer/ClassMethodAnalyzer.php b/src/Analyzer/ClassMethodAnalyzer.php index c399e433..320654ee 100644 --- a/src/Analyzer/ClassMethodAnalyzer.php +++ b/src/Analyzer/ClassMethodAnalyzer.php @@ -41,6 +41,7 @@ use PHPSemVerChecker\Operation\ClassMethodParameterTypingRemoved; use PHPSemVerChecker\Operation\ClassMethodRemoved; use PHPSemVerChecker\Report\Report; +use Magento\SemanticVersionChecker\Operation\ClassMethodParameterTypingChangedNullable; /** * Class method analyzer. @@ -258,12 +259,25 @@ protected function reportChanged($report, $contextBefore, $contextAfter, $method $report->add($this->context, $data); $signatureChanged = true; } elseif ($signatureChanges['parameter_typing_changed']) { - $data = new ClassMethodParameterTypingChanged( - $this->context, - $this->fileAfter, - $contextAfter, - $methodAfter - ); + + if ( + $signatureChanges['parameter_nullable_type_added'] || + $signatureChanges['parameter_nullable_type_removed'] + ) { + $data = new ClassMethodParameterTypingChangedNullable( + $this->context, + $this->fileAfter, + $contextAfter, + $methodAfter + ); + } else { + $data = new ClassMethodParameterTypingChanged( + $this->context, + $this->fileAfter, + $contextAfter, + $methodAfter + ); + } $report->add($this->context, $data); $signatureChanged = true; } diff --git a/src/Comparator/Signature.php b/src/Comparator/Signature.php index 2ce20c1a..42e5c096 100644 --- a/src/Comparator/Signature.php +++ b/src/Comparator/Signature.php @@ -130,18 +130,32 @@ public static function analyze(array $parametersA, array $parametersB): array $changes = array_merge($changes, [ 'parameter_typing_added' => false, 'parameter_typing_removed' => false, - 'parameter_typing_changed' => false + 'parameter_typing_changed' => false, + 'parameter_nullable_type_added' => false, + 'parameter_nullable_type_removed' => false, + 'changed_param_index' => 0 ]); $lengthA = count($parametersA); $lengthB = count($parametersB); $iterations = min($lengthA, $lengthB); for ($i = 0; $i < $iterations; ++$i) { + + $typeBefore = $parametersA[$i]->type; + $typeAfter = $parametersB[$i]->type; // Re-implement type checking to handle type changes as a single operation instead of both add and remove if (Type::get($parametersA[$i]->type) !== Type::get($parametersB[$i]->type)) { // This section changed from parent::analyze() to handle typing changes if ($parametersA[$i]->type !== null && $parametersB[$i]->type !== null) { $changes['parameter_typing_changed'] = true; + // Custom: detect nullable added + if ($typeBefore instanceof \PhpParser\Node\NullableType && !$typeAfter instanceof \PhpParser\Node\NullableType) { + $changes['parameter_nullable_type_removed'] = true; + $changes['changed_param_index'] = $i; + } elseif (!$typeBefore instanceof \PhpParser\Node\NullableType && $typeAfter instanceof \PhpParser\Node\NullableType) { + $changes['parameter_nullable_type_added'] = true; + $changes['changed_param_index'] = $i; + } } elseif ($parametersA[$i]->type !== null) { $changes['parameter_typing_removed'] = true; } elseif ($parametersB[$i]->type !== null) { @@ -149,7 +163,6 @@ public static function analyze(array $parametersA, array $parametersB): array } } } - return $changes; } } diff --git a/src/Operation/ClassMethodParameterTypingChangedNullable.php b/src/Operation/ClassMethodParameterTypingChangedNullable.php new file mode 100644 index 00000000..e800805a --- /dev/null +++ b/src/Operation/ClassMethodParameterTypingChangedNullable.php @@ -0,0 +1,54 @@ + ['M113', 'M114', 'M115'], + 'interface' => ['M116'], + 'trait' => ['M117', 'M118', 'M119'] + ]; + + /** + * @var array + */ + private $mapping = [ + 'M113' => Level::PATCH, + 'M114' => Level::MAJOR, + 'M115' => Level::PATCH, + 'M116' => Level::MAJOR, + 'M117' => Level::MAJOR, + 'M118' => Level::MAJOR, + 'M119' => Level::MAJOR + ]; + + + /** + * @var string + */ + protected $reason = 'Method parameter typing changed.'; + + /** + * Returns level of error. + * + * @return mixed + */ + public function getLevel(): int + { + return $this->mapping[$this->getCode()]; + } +} From e8310304d570e0266f7133e667f0a1353466a0de Mon Sep 17 00:00:00 2001 From: Bhavin Parmar Date: Tue, 20 May 2025 17:54:42 +0530 Subject: [PATCH 39/55] AC-14557:: False positives in the backward-incompatible changes report (SVC) --- composer.json | 2 +- composer.lock | 16 ++++++++-------- src/Analyzer/ClassMethodAnalyzer.php | 6 ++---- ...ClassMethodParameterTypingChangedNullable.php | 1 - 4 files changed, 11 insertions(+), 14 deletions(-) diff --git a/composer.json b/composer.json index 05d0279f..aee893ba 100644 --- a/composer.json +++ b/composer.json @@ -13,7 +13,7 @@ "laminas/laminas-stdlib": "^3.18", "nikic/php-parser": "^4.19", "phpstan/phpdoc-parser": "^0.5.5", - "sabre/xml": "~4.0.6", + "sabre/xml": "~4.0.5", "symfony/console": "~6.4.17", "symfony/string": "~6.4.15", "tomzx/php-semver-checker": "^0.16.0", diff --git a/composer.lock b/composer.lock index 88c3c339..86ddcee3 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "398f0dec67372bf5b99c5305508d6510", + "content-hash": "480ed8ade9fa6af94e4454d3bc8866f7", "packages": [ { "name": "hassankhan/config", @@ -344,16 +344,16 @@ }, { "name": "sabre/xml", - "version": "4.0.6", + "version": "4.0.5", "source": { "type": "git", "url": "https://github.com/sabre-io/xml.git", - "reference": "a89257fd188ce30e456b841b6915f27905dfdbe3" + "reference": "c29e49fcf9ca8ca058b1e350ee9abe4205c0de89" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sabre-io/xml/zipball/a89257fd188ce30e456b841b6915f27905dfdbe3", - "reference": "a89257fd188ce30e456b841b6915f27905dfdbe3", + "url": "https://api.github.com/repos/sabre-io/xml/zipball/c29e49fcf9ca8ca058b1e350ee9abe4205c0de89", + "reference": "c29e49fcf9ca8ca058b1e350ee9abe4205c0de89", "shasum": "" }, "require": { @@ -365,8 +365,8 @@ "sabre/uri": ">=2.0,<4.0.0" }, "require-dev": { - "friendsofphp/php-cs-fixer": "^3.64", - "phpstan/phpstan": "^1.12", + "friendsofphp/php-cs-fixer": "^3.51", + "phpstan/phpstan": "^1.10", "phpunit/phpunit": "^9.6" }, "type": "library", @@ -409,7 +409,7 @@ "issues": "https://github.com/sabre-io/xml/issues", "source": "https://github.com/fruux/sabre-xml" }, - "time": "2024-09-06T08:00:55+00:00" + "time": "2024-04-18T10:44:25+00:00" }, { "name": "symfony/console", diff --git a/src/Analyzer/ClassMethodAnalyzer.php b/src/Analyzer/ClassMethodAnalyzer.php index 320654ee..da51ac1c 100644 --- a/src/Analyzer/ClassMethodAnalyzer.php +++ b/src/Analyzer/ClassMethodAnalyzer.php @@ -260,8 +260,7 @@ protected function reportChanged($report, $contextBefore, $contextAfter, $method $signatureChanged = true; } elseif ($signatureChanges['parameter_typing_changed']) { - if ( - $signatureChanges['parameter_nullable_type_added'] || + if ($signatureChanges['parameter_nullable_type_added'] || $signatureChanges['parameter_nullable_type_removed'] ) { $data = new ClassMethodParameterTypingChangedNullable( @@ -469,8 +468,7 @@ private function isReturnsEqualByNullability(ClassMethod $before, ClassMethod $a */ private function getDocReturnDeclaration(ClassMethod $method) { - if ( - ($parsedComment = $method->getAttribute('docCommentParsed')) + if (($parsedComment = $method->getAttribute('docCommentParsed')) && isset($parsedComment['return']) ) { if ($parsedComment['return'][0] instanceof NullableType) { diff --git a/src/Operation/ClassMethodParameterTypingChangedNullable.php b/src/Operation/ClassMethodParameterTypingChangedNullable.php index e800805a..52868e26 100644 --- a/src/Operation/ClassMethodParameterTypingChangedNullable.php +++ b/src/Operation/ClassMethodParameterTypingChangedNullable.php @@ -36,7 +36,6 @@ class ClassMethodParameterTypingChangedNullable extends ClassMethodOperationUnar 'M119' => Level::MAJOR ]; - /** * @var string */ From 8bb57d4f35da101515108efbdb9a8e28004ae646 Mon Sep 17 00:00:00 2001 From: Bhavin Parmar Date: Tue, 20 May 2025 17:54:42 +0530 Subject: [PATCH 40/55] AC-14557:: False positives in the backward-incompatible changes report (SVC) --- composer.json | 2 +- composer.lock | 16 ++++++++-------- src/Analyzer/ClassMethodAnalyzer.php | 6 ++---- src/Comparator/Signature.php | 5 +---- ...ClassMethodParameterTypingChangedNullable.php | 1 - 5 files changed, 12 insertions(+), 18 deletions(-) diff --git a/composer.json b/composer.json index 05d0279f..aee893ba 100644 --- a/composer.json +++ b/composer.json @@ -13,7 +13,7 @@ "laminas/laminas-stdlib": "^3.18", "nikic/php-parser": "^4.19", "phpstan/phpdoc-parser": "^0.5.5", - "sabre/xml": "~4.0.6", + "sabre/xml": "~4.0.5", "symfony/console": "~6.4.17", "symfony/string": "~6.4.15", "tomzx/php-semver-checker": "^0.16.0", diff --git a/composer.lock b/composer.lock index 88c3c339..86ddcee3 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "398f0dec67372bf5b99c5305508d6510", + "content-hash": "480ed8ade9fa6af94e4454d3bc8866f7", "packages": [ { "name": "hassankhan/config", @@ -344,16 +344,16 @@ }, { "name": "sabre/xml", - "version": "4.0.6", + "version": "4.0.5", "source": { "type": "git", "url": "https://github.com/sabre-io/xml.git", - "reference": "a89257fd188ce30e456b841b6915f27905dfdbe3" + "reference": "c29e49fcf9ca8ca058b1e350ee9abe4205c0de89" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sabre-io/xml/zipball/a89257fd188ce30e456b841b6915f27905dfdbe3", - "reference": "a89257fd188ce30e456b841b6915f27905dfdbe3", + "url": "https://api.github.com/repos/sabre-io/xml/zipball/c29e49fcf9ca8ca058b1e350ee9abe4205c0de89", + "reference": "c29e49fcf9ca8ca058b1e350ee9abe4205c0de89", "shasum": "" }, "require": { @@ -365,8 +365,8 @@ "sabre/uri": ">=2.0,<4.0.0" }, "require-dev": { - "friendsofphp/php-cs-fixer": "^3.64", - "phpstan/phpstan": "^1.12", + "friendsofphp/php-cs-fixer": "^3.51", + "phpstan/phpstan": "^1.10", "phpunit/phpunit": "^9.6" }, "type": "library", @@ -409,7 +409,7 @@ "issues": "https://github.com/sabre-io/xml/issues", "source": "https://github.com/fruux/sabre-xml" }, - "time": "2024-09-06T08:00:55+00:00" + "time": "2024-04-18T10:44:25+00:00" }, { "name": "symfony/console", diff --git a/src/Analyzer/ClassMethodAnalyzer.php b/src/Analyzer/ClassMethodAnalyzer.php index 320654ee..da51ac1c 100644 --- a/src/Analyzer/ClassMethodAnalyzer.php +++ b/src/Analyzer/ClassMethodAnalyzer.php @@ -260,8 +260,7 @@ protected function reportChanged($report, $contextBefore, $contextAfter, $method $signatureChanged = true; } elseif ($signatureChanges['parameter_typing_changed']) { - if ( - $signatureChanges['parameter_nullable_type_added'] || + if ($signatureChanges['parameter_nullable_type_added'] || $signatureChanges['parameter_nullable_type_removed'] ) { $data = new ClassMethodParameterTypingChangedNullable( @@ -469,8 +468,7 @@ private function isReturnsEqualByNullability(ClassMethod $before, ClassMethod $a */ private function getDocReturnDeclaration(ClassMethod $method) { - if ( - ($parsedComment = $method->getAttribute('docCommentParsed')) + if (($parsedComment = $method->getAttribute('docCommentParsed')) && isset($parsedComment['return']) ) { if ($parsedComment['return'][0] instanceof NullableType) { diff --git a/src/Comparator/Signature.php b/src/Comparator/Signature.php index 42e5c096..cae33f0b 100644 --- a/src/Comparator/Signature.php +++ b/src/Comparator/Signature.php @@ -132,8 +132,7 @@ public static function analyze(array $parametersA, array $parametersB): array 'parameter_typing_removed' => false, 'parameter_typing_changed' => false, 'parameter_nullable_type_added' => false, - 'parameter_nullable_type_removed' => false, - 'changed_param_index' => 0 + 'parameter_nullable_type_removed' => false ]); $lengthA = count($parametersA); $lengthB = count($parametersB); @@ -151,10 +150,8 @@ public static function analyze(array $parametersA, array $parametersB): array // Custom: detect nullable added if ($typeBefore instanceof \PhpParser\Node\NullableType && !$typeAfter instanceof \PhpParser\Node\NullableType) { $changes['parameter_nullable_type_removed'] = true; - $changes['changed_param_index'] = $i; } elseif (!$typeBefore instanceof \PhpParser\Node\NullableType && $typeAfter instanceof \PhpParser\Node\NullableType) { $changes['parameter_nullable_type_added'] = true; - $changes['changed_param_index'] = $i; } } elseif ($parametersA[$i]->type !== null) { $changes['parameter_typing_removed'] = true; diff --git a/src/Operation/ClassMethodParameterTypingChangedNullable.php b/src/Operation/ClassMethodParameterTypingChangedNullable.php index e800805a..52868e26 100644 --- a/src/Operation/ClassMethodParameterTypingChangedNullable.php +++ b/src/Operation/ClassMethodParameterTypingChangedNullable.php @@ -36,7 +36,6 @@ class ClassMethodParameterTypingChangedNullable extends ClassMethodOperationUnar 'M119' => Level::MAJOR ]; - /** * @var string */ From 868178bbc29bcf5a2bc4f3761609030d39957215 Mon Sep 17 00:00:00 2001 From: Rajesh Kumar Date: Tue, 20 May 2025 18:13:47 +0530 Subject: [PATCH 41/55] AC-14557:: False positives in the backward-incompatible changes report (SVC) --- src/Analyzer/ClassMethodAnalyzer.php | 28 +++++++--- src/Comparator/Signature.php | 13 ++++- ...ssMethodParameterTypingChangedNullable.php | 53 +++++++++++++++++++ 3 files changed, 84 insertions(+), 10 deletions(-) create mode 100644 src/Operation/ClassMethodParameterTypingChangedNullable.php diff --git a/src/Analyzer/ClassMethodAnalyzer.php b/src/Analyzer/ClassMethodAnalyzer.php index c399e433..da51ac1c 100644 --- a/src/Analyzer/ClassMethodAnalyzer.php +++ b/src/Analyzer/ClassMethodAnalyzer.php @@ -41,6 +41,7 @@ use PHPSemVerChecker\Operation\ClassMethodParameterTypingRemoved; use PHPSemVerChecker\Operation\ClassMethodRemoved; use PHPSemVerChecker\Report\Report; +use Magento\SemanticVersionChecker\Operation\ClassMethodParameterTypingChangedNullable; /** * Class method analyzer. @@ -258,12 +259,24 @@ protected function reportChanged($report, $contextBefore, $contextAfter, $method $report->add($this->context, $data); $signatureChanged = true; } elseif ($signatureChanges['parameter_typing_changed']) { - $data = new ClassMethodParameterTypingChanged( - $this->context, - $this->fileAfter, - $contextAfter, - $methodAfter - ); + + if ($signatureChanges['parameter_nullable_type_added'] || + $signatureChanges['parameter_nullable_type_removed'] + ) { + $data = new ClassMethodParameterTypingChangedNullable( + $this->context, + $this->fileAfter, + $contextAfter, + $methodAfter + ); + } else { + $data = new ClassMethodParameterTypingChanged( + $this->context, + $this->fileAfter, + $contextAfter, + $methodAfter + ); + } $report->add($this->context, $data); $signatureChanged = true; } @@ -455,8 +468,7 @@ private function isReturnsEqualByNullability(ClassMethod $before, ClassMethod $a */ private function getDocReturnDeclaration(ClassMethod $method) { - if ( - ($parsedComment = $method->getAttribute('docCommentParsed')) + if (($parsedComment = $method->getAttribute('docCommentParsed')) && isset($parsedComment['return']) ) { if ($parsedComment['return'][0] instanceof NullableType) { diff --git a/src/Comparator/Signature.php b/src/Comparator/Signature.php index 2ce20c1a..cfa79457 100644 --- a/src/Comparator/Signature.php +++ b/src/Comparator/Signature.php @@ -130,18 +130,28 @@ public static function analyze(array $parametersA, array $parametersB): array $changes = array_merge($changes, [ 'parameter_typing_added' => false, 'parameter_typing_removed' => false, - 'parameter_typing_changed' => false + 'parameter_typing_changed' => false, + 'parameter_nullable_type_added' => false, + 'parameter_nullable_type_removed' => false ]); $lengthA = count($parametersA); $lengthB = count($parametersB); $iterations = min($lengthA, $lengthB); for ($i = 0; $i < $iterations; ++$i) { + $typeBefore = $parametersA[$i]->type; + $typeAfter = $parametersB[$i]->type; // Re-implement type checking to handle type changes as a single operation instead of both add and remove if (Type::get($parametersA[$i]->type) !== Type::get($parametersB[$i]->type)) { // This section changed from parent::analyze() to handle typing changes if ($parametersA[$i]->type !== null && $parametersB[$i]->type !== null) { $changes['parameter_typing_changed'] = true; + // Custom: detect nullable added + if ($typeBefore instanceof \PhpParser\Node\NullableType && !$typeAfter instanceof \PhpParser\Node\NullableType) { + $changes['parameter_nullable_type_removed'] = true; + } elseif (!$typeBefore instanceof \PhpParser\Node\NullableType && $typeAfter instanceof \PhpParser\Node\NullableType) { + $changes['parameter_nullable_type_added'] = true; + } } elseif ($parametersA[$i]->type !== null) { $changes['parameter_typing_removed'] = true; } elseif ($parametersB[$i]->type !== null) { @@ -149,7 +159,6 @@ public static function analyze(array $parametersA, array $parametersB): array } } } - return $changes; } } diff --git a/src/Operation/ClassMethodParameterTypingChangedNullable.php b/src/Operation/ClassMethodParameterTypingChangedNullable.php new file mode 100644 index 00000000..52868e26 --- /dev/null +++ b/src/Operation/ClassMethodParameterTypingChangedNullable.php @@ -0,0 +1,53 @@ + ['M113', 'M114', 'M115'], + 'interface' => ['M116'], + 'trait' => ['M117', 'M118', 'M119'] + ]; + + /** + * @var array + */ + private $mapping = [ + 'M113' => Level::PATCH, + 'M114' => Level::MAJOR, + 'M115' => Level::PATCH, + 'M116' => Level::MAJOR, + 'M117' => Level::MAJOR, + 'M118' => Level::MAJOR, + 'M119' => Level::MAJOR + ]; + + /** + * @var string + */ + protected $reason = 'Method parameter typing changed.'; + + /** + * Returns level of error. + * + * @return mixed + */ + public function getLevel(): int + { + return $this->mapping[$this->getCode()]; + } +} From 1247cc412789b117c8fbfc351ca113030b9424d1 Mon Sep 17 00:00:00 2001 From: Rajesh Kumar Date: Tue, 20 May 2025 18:15:12 +0530 Subject: [PATCH 42/55] AC-14557:: False positives in the backward-incompatible changes report (SVC) --- composer.json | 2 +- composer.lock | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index aee893ba..efcd9fa0 100644 --- a/composer.json +++ b/composer.json @@ -1,7 +1,7 @@ { "name": "magento/magento-semver", "description": "Magento Semantic Version Checker", - "version": "13.0.0-beta7", + "version": "13.0.0-beta8", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/composer.lock b/composer.lock index 86ddcee3..f8ecd09a 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "480ed8ade9fa6af94e4454d3bc8866f7", + "content-hash": "9c90a6e0cf0716bb5a6478500cc4b58f", "packages": [ { "name": "hassankhan/config", From 5db491256ba486e6ceccfbb5a1e6a681bb7b86de Mon Sep 17 00:00:00 2001 From: Rajesh Kumar Date: Tue, 20 May 2025 18:27:08 +0530 Subject: [PATCH 43/55] AC-14557:: False positives in the backward-incompatible changes report (SVC) --- composer.lock | 504 ++++++++++++++++----------- src/Analyzer/ClassMethodAnalyzer.php | 9 +- src/Comparator/Signature.php | 6 +- 3 files changed, 304 insertions(+), 215 deletions(-) diff --git a/composer.lock b/composer.lock index f8ecd09a..eb6884e8 100644 --- a/composer.lock +++ b/composer.lock @@ -8,30 +8,29 @@ "packages": [ { "name": "hassankhan/config", - "version": "3.0.0", + "version": "3.2.0", "source": { "type": "git", "url": "https://github.com/hassankhan/config.git", - "reference": "a3f02c5158d0a772d242ffd377657793c08cc0c6" + "reference": "cf63da451c4d226df983017932b9cef1b6d49db5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/hassankhan/config/zipball/a3f02c5158d0a772d242ffd377657793c08cc0c6", - "reference": "a3f02c5158d0a772d242ffd377657793c08cc0c6", + "url": "https://api.github.com/repos/hassankhan/config/zipball/cf63da451c4d226df983017932b9cef1b6d49db5", + "reference": "cf63da451c4d226df983017932b9cef1b6d49db5", "shasum": "" }, "require": { - "php": ">=5.5.9" + "php": ">=7.4" }, "require-dev": { - "phpunit/phpunit": "~4.8.36 || ~5.7 || ~6.5 || ~7.5 || ~8.5", - "scrutinizer/ocular": "~1.1", - "squizlabs/php_codesniffer": "~2.2", - "symfony/yaml": "~3.4", - "yoast/phpunit-polyfills": "^1.0" + "phpunit/phpunit": "^9.5", + "scrutinizer/ocular": "^1.9", + "squizlabs/php_codesniffer": "^3.6", + "symfony/yaml": "^5.4" }, "suggest": { - "symfony/yaml": "~3.4" + "symfony/yaml": "^5.4" }, "type": "library", "autoload": { @@ -65,9 +64,9 @@ ], "support": { "issues": "https://github.com/hassankhan/config/issues", - "source": "https://github.com/hassankhan/config/tree/3.0.0" + "source": "https://github.com/hassankhan/config/tree/3.2.0" }, - "time": "2021-12-30T16:38:05+00:00" + "time": "2024-12-09T16:20:44+00:00" }, { "name": "laminas/laminas-stdlib", @@ -130,16 +129,16 @@ }, { "name": "nikic/php-parser", - "version": "v4.19.0", + "version": "v4.19.4", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "32cdab9a034239a8f57ae0e9a15bada4bd9747bf" + "reference": "715f4d25e225bc47b293a8b997fe6ce99bf987d2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/32cdab9a034239a8f57ae0e9a15bada4bd9747bf", - "reference": "32cdab9a034239a8f57ae0e9a15bada4bd9747bf", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/715f4d25e225bc47b293a8b997fe6ce99bf987d2", + "reference": "715f4d25e225bc47b293a8b997fe6ce99bf987d2", "shasum": "" }, "require": { @@ -148,7 +147,7 @@ }, "require-dev": { "ircmaxell/php-yacc": "^0.0.7", - "phpunit/phpunit": "^6.5 || ^7.0 || ^8.0 || ^9.0" + "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0" }, "bin": [ "bin/php-parse" @@ -180,22 +179,22 @@ ], "support": { "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v4.19.0" + "source": "https://github.com/nikic/PHP-Parser/tree/v4.19.4" }, - "time": "2024-03-16T14:49:31+00:00" + "time": "2024-09-29T15:01:53+00:00" }, { "name": "phpstan/phpdoc-parser", - "version": "0.5.5", + "version": "0.5.7", "source": { "type": "git", "url": "https://github.com/phpstan/phpdoc-parser.git", - "reference": "ea0b17460ec38e20d7eb64e7ec49b5d44af5d28c" + "reference": "816e826ce0b7fb32098d8cb6de62511ce6021cea" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/ea0b17460ec38e20d7eb64e7ec49b5d44af5d28c", - "reference": "ea0b17460ec38e20d7eb64e7ec49b5d44af5d28c", + "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/816e826ce0b7fb32098d8cb6de62511ce6021cea", + "reference": "816e826ce0b7fb32098d8cb6de62511ce6021cea", "shasum": "" }, "require": { @@ -229,31 +228,31 @@ "description": "PHPDoc parser with support for nullable, intersection and generic types", "support": { "issues": "https://github.com/phpstan/phpdoc-parser/issues", - "source": "https://github.com/phpstan/phpdoc-parser/tree/0.5.5" + "source": "https://github.com/phpstan/phpdoc-parser/tree/0.5.7" }, - "time": "2021-06-11T13:24:46+00:00" + "time": "2021-09-12T11:52:00+00:00" }, { "name": "psr/container", - "version": "1.1.0", + "version": "2.0.2", "source": { "type": "git", "url": "https://github.com/php-fig/container.git", - "reference": "9fc7aab7a78057a124384358ebae8a1711b6f6fc" + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/container/zipball/9fc7aab7a78057a124384358ebae8a1711b6f6fc", - "reference": "9fc7aab7a78057a124384358ebae8a1711b6f6fc", + "url": "https://api.github.com/repos/php-fig/container/zipball/c71ecc56dfe541dbd90c5360474fbc405f8d5963", + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963", "shasum": "" }, "require": { - "php": ">=7.2.0" + "php": ">=7.4.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.1.x-dev" + "dev-master": "2.0.x-dev" } }, "autoload": { @@ -282,30 +281,34 @@ ], "support": { "issues": "https://github.com/php-fig/container/issues", - "source": "https://github.com/php-fig/container/tree/1.1.0" + "source": "https://github.com/php-fig/container/tree/2.0.2" }, - "time": "2021-03-05T15:48:30+00:00" + "time": "2021-11-05T16:47:00+00:00" }, { "name": "sabre/uri", - "version": "2.0.0", + "version": "3.0.2", "source": { "type": "git", "url": "https://github.com/sabre-io/uri.git", - "reference": "ef4987fd1c88d1112d75d8527a35a9392d02e488" + "reference": "38eeab6ed9eec435a2188db489d4649c56272c51" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sabre-io/uri/zipball/ef4987fd1c88d1112d75d8527a35a9392d02e488", - "reference": "ef4987fd1c88d1112d75d8527a35a9392d02e488", + "url": "https://api.github.com/repos/sabre-io/uri/zipball/38eeab6ed9eec435a2188db489d4649c56272c51", + "reference": "38eeab6ed9eec435a2188db489d4649c56272c51", "shasum": "" }, "require": { - "php": ">=7" + "php": "^7.4 || ^8.0" }, "require-dev": { - "phpunit/phpunit": "*", - "sabre/cs": "~1.0.0" + "friendsofphp/php-cs-fixer": "^3.64", + "phpstan/extension-installer": "^1.4", + "phpstan/phpstan": "^1.12", + "phpstan/phpstan-phpunit": "^1.4", + "phpstan/phpstan-strict-rules": "^1.6", + "phpunit/phpunit": "^9.6" }, "type": "library", "autoload": { @@ -340,20 +343,20 @@ "issues": "https://github.com/sabre-io/uri/issues", "source": "https://github.com/fruux/sabre-uri" }, - "time": "2016-10-07T02:52:31+00:00" + "time": "2024-09-04T15:30:08+00:00" }, { "name": "sabre/xml", - "version": "4.0.5", + "version": "4.0.6", "source": { "type": "git", "url": "https://github.com/sabre-io/xml.git", - "reference": "c29e49fcf9ca8ca058b1e350ee9abe4205c0de89" + "reference": "a89257fd188ce30e456b841b6915f27905dfdbe3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sabre-io/xml/zipball/c29e49fcf9ca8ca058b1e350ee9abe4205c0de89", - "reference": "c29e49fcf9ca8ca058b1e350ee9abe4205c0de89", + "url": "https://api.github.com/repos/sabre-io/xml/zipball/a89257fd188ce30e456b841b6915f27905dfdbe3", + "reference": "a89257fd188ce30e456b841b6915f27905dfdbe3", "shasum": "" }, "require": { @@ -365,8 +368,8 @@ "sabre/uri": ">=2.0,<4.0.0" }, "require-dev": { - "friendsofphp/php-cs-fixer": "^3.51", - "phpstan/phpstan": "^1.10", + "friendsofphp/php-cs-fixer": "^3.64", + "phpstan/phpstan": "^1.12", "phpunit/phpunit": "^9.6" }, "type": "library", @@ -409,20 +412,20 @@ "issues": "https://github.com/sabre-io/xml/issues", "source": "https://github.com/fruux/sabre-xml" }, - "time": "2024-04-18T10:44:25+00:00" + "time": "2024-09-06T08:00:55+00:00" }, { "name": "symfony/console", - "version": "v6.4.17", + "version": "v6.4.21", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "799445db3f15768ecc382ac5699e6da0520a0a04" + "reference": "a3011c7b7adb58d89f6c0d822abb641d7a5f9719" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/799445db3f15768ecc382ac5699e6da0520a0a04", - "reference": "799445db3f15768ecc382ac5699e6da0520a0a04", + "url": "https://api.github.com/repos/symfony/console/zipball/a3011c7b7adb58d89f6c0d822abb641d7a5f9719", + "reference": "a3011c7b7adb58d89f6c0d822abb641d7a5f9719", "shasum": "" }, "require": { @@ -487,7 +490,7 @@ "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v6.4.17" + "source": "https://github.com/symfony/console/tree/v6.4.21" }, "funding": [ { @@ -503,24 +506,24 @@ "type": "tidelift" } ], - "time": "2024-12-07T12:07:30+00:00" + "time": "2025-04-07T15:42:41+00:00" }, { "name": "symfony/deprecation-contracts", - "version": "v2.5.0", + "version": "v3.5.1", "source": { "type": "git", "url": "https://github.com/symfony/deprecation-contracts.git", - "reference": "6f981ee24cf69ee7ce9736146d1c57c2780598a8" + "reference": "74c71c939a79f7d5bf3c1ce9f5ea37ba0114c6f6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/6f981ee24cf69ee7ce9736146d1c57c2780598a8", - "reference": "6f981ee24cf69ee7ce9736146d1c57c2780598a8", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/74c71c939a79f7d5bf3c1ce9f5ea37ba0114c6f6", + "reference": "74c71c939a79f7d5bf3c1ce9f5ea37ba0114c6f6", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=8.1" }, "type": "library", "extra": { @@ -529,7 +532,7 @@ "name": "symfony/contracts" }, "branch-alias": { - "dev-main": "2.5-dev" + "dev-main": "3.5-dev" } }, "autoload": { @@ -554,7 +557,7 @@ "description": "A generic function and convention to trigger deprecation notices", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/deprecation-contracts/tree/v2.5.0" + "source": "https://github.com/symfony/deprecation-contracts/tree/v3.5.1" }, "funding": [ { @@ -570,29 +573,36 @@ "type": "tidelift" } ], - "time": "2021-07-12T14:48:14+00:00" + "time": "2024-09-25T14:20:29+00:00" }, { "name": "symfony/polyfill-ctype", - "version": "v1.8.0", + "version": "v1.32.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "7cc359f1b7b80fc25ed7796be7d96adc9b354bae" + "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/7cc359f1b7b80fc25ed7796be7d96adc9b354bae", - "reference": "7cc359f1b7b80fc25ed7796be7d96adc9b354bae", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/a3cc8b044a6ea513310cbd48ef7333b384945638", + "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": ">=7.2" + }, + "provide": { + "ext-ctype": "*" + }, + "suggest": { + "ext-ctype": "For best performance" }, "type": "library", "extra": { - "branch-alias": { - "dev-master": "1.8-dev" + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "autoload": { @@ -608,13 +618,13 @@ "MIT" ], "authors": [ - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - }, { "name": "Gert de Pagter", "email": "BackEndTea@gmail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], "description": "Symfony polyfill for ctype functions", @@ -626,31 +636,49 @@ "portable" ], "support": { - "source": "https://github.com/symfony/polyfill-ctype/tree/master" + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.32.0" }, - "time": "2018-04-30T19:57:29+00:00" + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-09T11:45:10+00:00" }, { "name": "symfony/polyfill-intl-grapheme", - "version": "v1.0.0", + "version": "v1.32.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-grapheme.git", - "reference": "9332d285b58a16b144b3bf0bfd3b6334d9a43006" + "reference": "b9123926e3b7bc2f98c02ad54f6a4b02b91a8abe" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/9332d285b58a16b144b3bf0bfd3b6334d9a43006", - "reference": "9332d285b58a16b144b3bf0bfd3b6334d9a43006", + "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/b9123926e3b7bc2f98c02ad54f6a4b02b91a8abe", + "reference": "b9123926e3b7bc2f98c02ad54f6a4b02b91a8abe", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": ">=7.2" + }, + "suggest": { + "ext-intl": "For best performance" }, "type": "library", "extra": { - "branch-alias": { - "dev-master": "1.0-dev" + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "autoload": { @@ -686,31 +714,49 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/master" + "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.32.0" }, - "time": "2015-11-04T20:28:58+00:00" + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-09T11:45:10+00:00" }, { "name": "symfony/polyfill-intl-normalizer", - "version": "v1.0.0", + "version": "v1.32.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-normalizer.git", - "reference": "b0235b9e98e224821e23018a9487764ad6dec859" + "reference": "3833d7255cc303546435cb650316bff708a1c75c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/b0235b9e98e224821e23018a9487764ad6dec859", - "reference": "b0235b9e98e224821e23018a9487764ad6dec859", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/3833d7255cc303546435cb650316bff708a1c75c", + "reference": "3833d7255cc303546435cb650316bff708a1c75c", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": ">=7.2" + }, + "suggest": { + "ext-intl": "For best performance" }, "type": "library", "extra": { - "branch-alias": { - "dev-master": "1.0-dev" + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "autoload": { @@ -749,31 +795,53 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/master" + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.32.0" }, - "time": "2015-11-04T20:28:58+00:00" + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-09T11:45:10+00:00" }, { "name": "symfony/polyfill-mbstring", - "version": "v1.0.0", + "version": "v1.32.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "0b6a8940385311a24e060ec1fe35680e17c74497" + "reference": "6d857f4d76bd4b343eac26d6b539585d2bc56493" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/0b6a8940385311a24e060ec1fe35680e17c74497", - "reference": "0b6a8940385311a24e060ec1fe35680e17c74497", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/6d857f4d76bd4b343eac26d6b539585d2bc56493", + "reference": "6d857f4d76bd4b343eac26d6b539585d2bc56493", "shasum": "" }, "require": { - "php": ">=5.3.3" + "ext-iconv": "*", + "php": ">=7.2" + }, + "provide": { + "ext-mbstring": "*" + }, + "suggest": { + "ext-mbstring": "For best performance" }, "type": "library", "extra": { - "branch-alias": { - "dev-master": "1.0-dev" + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "autoload": { @@ -808,35 +876,46 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-mbstring/tree/master" + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.32.0" }, - "time": "2015-11-04T20:28:58+00:00" + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-12-23T08:48:59+00:00" }, { "name": "symfony/service-contracts", - "version": "v2.5.0", + "version": "v3.5.1", "source": { "type": "git", "url": "https://github.com/symfony/service-contracts.git", - "reference": "1ab11b933cd6bc5464b08e81e2c5b07dec58b0fc" + "reference": "e53260aabf78fb3d63f8d79d69ece59f80d5eda0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/service-contracts/zipball/1ab11b933cd6bc5464b08e81e2c5b07dec58b0fc", - "reference": "1ab11b933cd6bc5464b08e81e2c5b07dec58b0fc", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/e53260aabf78fb3d63f8d79d69ece59f80d5eda0", + "reference": "e53260aabf78fb3d63f8d79d69ece59f80d5eda0", "shasum": "" }, "require": { - "php": ">=7.2.5", - "psr/container": "^1.1", - "symfony/deprecation-contracts": "^2.1" + "php": ">=8.1", + "psr/container": "^1.1|^2.0", + "symfony/deprecation-contracts": "^2.5|^3" }, "conflict": { "ext-psr": "<1.1|>=2" }, - "suggest": { - "symfony/service-implementation": "" - }, "type": "library", "extra": { "thanks": { @@ -844,13 +923,16 @@ "name": "symfony/contracts" }, "branch-alias": { - "dev-main": "2.5-dev" + "dev-main": "3.5-dev" } }, "autoload": { "psr-4": { "Symfony\\Contracts\\Service\\": "" - } + }, + "exclude-from-classmap": [ + "/Test/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -877,7 +959,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/service-contracts/tree/v2.5.0" + "source": "https://github.com/symfony/service-contracts/tree/v3.5.1" }, "funding": [ { @@ -893,20 +975,20 @@ "type": "tidelift" } ], - "time": "2021-11-04T16:48:04+00:00" + "time": "2024-09-25T14:20:29+00:00" }, { "name": "symfony/string", - "version": "v6.4.15", + "version": "v6.4.21", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "73a5e66ea2e1677c98d4449177c5a9cf9d8b4c6f" + "reference": "73e2c6966a5aef1d4892873ed5322245295370c6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/73a5e66ea2e1677c98d4449177c5a9cf9d8b4c6f", - "reference": "73a5e66ea2e1677c98d4449177c5a9cf9d8b4c6f", + "url": "https://api.github.com/repos/symfony/string/zipball/73e2c6966a5aef1d4892873ed5322245295370c6", + "reference": "73e2c6966a5aef1d4892873ed5322245295370c6", "shasum": "" }, "require": { @@ -963,7 +1045,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v6.4.15" + "source": "https://github.com/symfony/string/tree/v6.4.21" }, "funding": [ { @@ -979,34 +1061,32 @@ "type": "tidelift" } ], - "time": "2024-11-13T13:31:12+00:00" + "time": "2025-04-18T15:23:29+00:00" }, { "name": "symfony/yaml", - "version": "v6.0.0", + "version": "v6.4.21", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "f3064a2e0b5eabaeaf92db0a5913a77098b3b91e" + "reference": "f01987f45676778b474468aa266fe2eda1f2bc7e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/f3064a2e0b5eabaeaf92db0a5913a77098b3b91e", - "reference": "f3064a2e0b5eabaeaf92db0a5913a77098b3b91e", + "url": "https://api.github.com/repos/symfony/yaml/zipball/f01987f45676778b474468aa266fe2eda1f2bc7e", + "reference": "f01987f45676778b474468aa266fe2eda1f2bc7e", "shasum": "" }, "require": { - "php": ">=8.0.2", + "php": ">=8.1", + "symfony/deprecation-contracts": "^2.5|^3", "symfony/polyfill-ctype": "^1.8" }, "conflict": { "symfony/console": "<5.4" }, "require-dev": { - "symfony/console": "^5.4|^6.0" - }, - "suggest": { - "symfony/console": "For validating YAML files using the lint command" + "symfony/console": "^5.4|^6.0|^7.0" }, "bin": [ "Resources/bin/yaml-lint" @@ -1037,7 +1117,7 @@ "description": "Loads and dumps YAML files", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/yaml/tree/v6.0.0" + "source": "https://github.com/symfony/yaml/tree/v6.4.21" }, "funding": [ { @@ -1053,7 +1133,7 @@ "type": "tidelift" } ], - "time": "2021-11-28T15:34:37+00:00" + "time": "2025-04-04T09:48:44+00:00" }, { "name": "tomzx/finder", @@ -1174,28 +1254,28 @@ }, { "name": "wikimedia/less.php", - "version": "v5.1.0", + "version": "v5.3.1", "source": { "type": "git", "url": "https://github.com/wikimedia/less.php.git", - "reference": "b66f3578a951ba666f8872cdbc2c6063787c8fdc" + "reference": "fb0ed6296bb69cad225dd49b7e93765aab9ae88b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/wikimedia/less.php/zipball/b66f3578a951ba666f8872cdbc2c6063787c8fdc", - "reference": "b66f3578a951ba666f8872cdbc2c6063787c8fdc", + "url": "https://api.github.com/repos/wikimedia/less.php/zipball/fb0ed6296bb69cad225dd49b7e93765aab9ae88b", + "reference": "fb0ed6296bb69cad225dd49b7e93765aab9ae88b", "shasum": "" }, "require": { "php": ">=7.4.3" }, "require-dev": { - "mediawiki/mediawiki-codesniffer": "43.0.0", - "mediawiki/mediawiki-phan-config": "0.14.0", + "mediawiki/mediawiki-codesniffer": "46.0.0", + "mediawiki/mediawiki-phan-config": "0.15.1", "mediawiki/minus-x": "1.1.3", "php-parallel-lint/php-console-highlighter": "1.0.0", "php-parallel-lint/php-parallel-lint": "1.4.0", - "phpunit/phpunit": "9.6.16" + "phpunit/phpunit": "9.6.21" }, "bin": [ "bin/lessc" @@ -1243,24 +1323,24 @@ ], "support": { "issues": "https://github.com/wikimedia/less.php/issues", - "source": "https://github.com/wikimedia/less.php/tree/v5.1.0" + "source": "https://github.com/wikimedia/less.php/tree/v5.3.1" }, - "time": "2024-08-06T21:12:41+00:00" + "time": "2025-04-16T22:21:45+00:00" } ], "packages-dev": [ { "name": "myclabs/deep-copy", - "version": "1.12.0", + "version": "1.13.1", "source": { "type": "git", "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "3a6b9a42cd8f8771bd4295d13e1423fa7f3d942c" + "reference": "1720ddd719e16cf0db4eb1c6eca108031636d46c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/3a6b9a42cd8f8771bd4295d13e1423fa7f3d942c", - "reference": "3a6b9a42cd8f8771bd4295d13e1423fa7f3d942c", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/1720ddd719e16cf0db4eb1c6eca108031636d46c", + "reference": "1720ddd719e16cf0db4eb1c6eca108031636d46c", "shasum": "" }, "require": { @@ -1299,7 +1379,7 @@ ], "support": { "issues": "https://github.com/myclabs/DeepCopy/issues", - "source": "https://github.com/myclabs/DeepCopy/tree/1.12.0" + "source": "https://github.com/myclabs/DeepCopy/tree/1.13.1" }, "funding": [ { @@ -1307,7 +1387,7 @@ "type": "tidelift" } ], - "time": "2024-06-12T14:39:25+00:00" + "time": "2025-04-29T12:36:36+00:00" }, { "name": "phar-io/manifest", @@ -1429,32 +1509,32 @@ }, { "name": "phpunit/php-code-coverage", - "version": "10.1.15", + "version": "10.1.16", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "5da8b1728acd1e6ffdf2ff32ffbdfd04307f26ae" + "reference": "7e308268858ed6baedc8704a304727d20bc07c77" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/5da8b1728acd1e6ffdf2ff32ffbdfd04307f26ae", - "reference": "5da8b1728acd1e6ffdf2ff32ffbdfd04307f26ae", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/7e308268858ed6baedc8704a304727d20bc07c77", + "reference": "7e308268858ed6baedc8704a304727d20bc07c77", "shasum": "" }, "require": { "ext-dom": "*", "ext-libxml": "*", "ext-xmlwriter": "*", - "nikic/php-parser": "^4.18 || ^5.0", + "nikic/php-parser": "^4.19.1 || ^5.1.0", "php": ">=8.1", - "phpunit/php-file-iterator": "^4.0", - "phpunit/php-text-template": "^3.0", - "sebastian/code-unit-reverse-lookup": "^3.0", - "sebastian/complexity": "^3.0", - "sebastian/environment": "^6.0", - "sebastian/lines-of-code": "^2.0", - "sebastian/version": "^4.0", - "theseer/tokenizer": "^1.2.0" + "phpunit/php-file-iterator": "^4.1.0", + "phpunit/php-text-template": "^3.0.1", + "sebastian/code-unit-reverse-lookup": "^3.0.0", + "sebastian/complexity": "^3.2.0", + "sebastian/environment": "^6.1.0", + "sebastian/lines-of-code": "^2.0.2", + "sebastian/version": "^4.0.1", + "theseer/tokenizer": "^1.2.3" }, "require-dev": { "phpunit/phpunit": "^10.1" @@ -1466,7 +1546,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "10.1-dev" + "dev-main": "10.1.x-dev" } }, "autoload": { @@ -1495,7 +1575,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/10.1.15" + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/10.1.16" }, "funding": [ { @@ -1503,7 +1583,7 @@ "type": "github" } ], - "time": "2024-06-29T08:25:15+00:00" + "time": "2024-08-22T04:31:57+00:00" }, { "name": "phpunit/php-file-iterator", @@ -1750,16 +1830,16 @@ }, { "name": "phpunit/phpunit", - "version": "10.5.28", + "version": "10.5.46", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "ff7fb85cdf88131b83e721fb2a327b664dbed275" + "reference": "8080be387a5be380dda48c6f41cee4a13aadab3d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/ff7fb85cdf88131b83e721fb2a327b664dbed275", - "reference": "ff7fb85cdf88131b83e721fb2a327b664dbed275", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/8080be387a5be380dda48c6f41cee4a13aadab3d", + "reference": "8080be387a5be380dda48c6f41cee4a13aadab3d", "shasum": "" }, "require": { @@ -1769,18 +1849,18 @@ "ext-mbstring": "*", "ext-xml": "*", "ext-xmlwriter": "*", - "myclabs/deep-copy": "^1.12.0", + "myclabs/deep-copy": "^1.13.1", "phar-io/manifest": "^2.0.4", "phar-io/version": "^3.2.1", "php": ">=8.1", - "phpunit/php-code-coverage": "^10.1.15", + "phpunit/php-code-coverage": "^10.1.16", "phpunit/php-file-iterator": "^4.1.0", "phpunit/php-invoker": "^4.0.0", "phpunit/php-text-template": "^3.0.1", "phpunit/php-timer": "^6.0.0", "sebastian/cli-parser": "^2.0.1", "sebastian/code-unit": "^2.0.0", - "sebastian/comparator": "^5.0.1", + "sebastian/comparator": "^5.0.3", "sebastian/diff": "^5.1.1", "sebastian/environment": "^6.1.0", "sebastian/exporter": "^5.1.2", @@ -1831,7 +1911,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", "security": "https://github.com/sebastianbergmann/phpunit/security/policy", - "source": "https://github.com/sebastianbergmann/phpunit/tree/10.5.28" + "source": "https://github.com/sebastianbergmann/phpunit/tree/10.5.46" }, "funding": [ { @@ -1842,12 +1922,20 @@ "url": "https://github.com/sebastianbergmann", "type": "github" }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, { "url": "https://tidelift.com/funding/github/packagist/phpunit/phpunit", "type": "tidelift" } ], - "time": "2024-07-18T14:54:16+00:00" + "time": "2025-05-02T06:46:24+00:00" }, { "name": "sebastian/cli-parser", @@ -2019,16 +2107,16 @@ }, { "name": "sebastian/comparator", - "version": "5.0.1", + "version": "5.0.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "2db5010a484d53ebf536087a70b4a5423c102372" + "reference": "a18251eb0b7a2dcd2f7aa3d6078b18545ef0558e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/2db5010a484d53ebf536087a70b4a5423c102372", - "reference": "2db5010a484d53ebf536087a70b4a5423c102372", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/a18251eb0b7a2dcd2f7aa3d6078b18545ef0558e", + "reference": "a18251eb0b7a2dcd2f7aa3d6078b18545ef0558e", "shasum": "" }, "require": { @@ -2039,7 +2127,7 @@ "sebastian/exporter": "^5.0" }, "require-dev": { - "phpunit/phpunit": "^10.3" + "phpunit/phpunit": "^10.5" }, "type": "library", "extra": { @@ -2084,7 +2172,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/comparator/issues", "security": "https://github.com/sebastianbergmann/comparator/security/policy", - "source": "https://github.com/sebastianbergmann/comparator/tree/5.0.1" + "source": "https://github.com/sebastianbergmann/comparator/tree/5.0.3" }, "funding": [ { @@ -2092,24 +2180,24 @@ "type": "github" } ], - "time": "2023-08-14T13:18:12+00:00" + "time": "2024-10-18T14:56:07+00:00" }, { "name": "sebastian/complexity", - "version": "3.0.0", + "version": "3.2.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/complexity.git", - "reference": "e67d240970c9dc7ea7b2123a6d520e334dd61dc6" + "reference": "68ff824baeae169ec9f2137158ee529584553799" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/e67d240970c9dc7ea7b2123a6d520e334dd61dc6", - "reference": "e67d240970c9dc7ea7b2123a6d520e334dd61dc6", + "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/68ff824baeae169ec9f2137158ee529584553799", + "reference": "68ff824baeae169ec9f2137158ee529584553799", "shasum": "" }, "require": { - "nikic/php-parser": "^4.10", + "nikic/php-parser": "^4.18 || ^5.0", "php": ">=8.1" }, "require-dev": { @@ -2118,7 +2206,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "3.0-dev" + "dev-main": "3.2-dev" } }, "autoload": { @@ -2141,7 +2229,8 @@ "homepage": "https://github.com/sebastianbergmann/complexity", "support": { "issues": "https://github.com/sebastianbergmann/complexity/issues", - "source": "https://github.com/sebastianbergmann/complexity/tree/3.0.0" + "security": "https://github.com/sebastianbergmann/complexity/security/policy", + "source": "https://github.com/sebastianbergmann/complexity/tree/3.2.0" }, "funding": [ { @@ -2149,7 +2238,7 @@ "type": "github" } ], - "time": "2023-02-03T06:59:47+00:00" + "time": "2023-12-21T08:37:17+00:00" }, { "name": "sebastian/diff", @@ -2424,20 +2513,20 @@ }, { "name": "sebastian/lines-of-code", - "version": "2.0.0", + "version": "2.0.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/lines-of-code.git", - "reference": "17c4d940ecafb3d15d2cf916f4108f664e28b130" + "reference": "856e7f6a75a84e339195d48c556f23be2ebf75d0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/17c4d940ecafb3d15d2cf916f4108f664e28b130", - "reference": "17c4d940ecafb3d15d2cf916f4108f664e28b130", + "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/856e7f6a75a84e339195d48c556f23be2ebf75d0", + "reference": "856e7f6a75a84e339195d48c556f23be2ebf75d0", "shasum": "" }, "require": { - "nikic/php-parser": "^4.10", + "nikic/php-parser": "^4.18 || ^5.0", "php": ">=8.1" }, "require-dev": { @@ -2469,7 +2558,8 @@ "homepage": "https://github.com/sebastianbergmann/lines-of-code", "support": { "issues": "https://github.com/sebastianbergmann/lines-of-code/issues", - "source": "https://github.com/sebastianbergmann/lines-of-code/tree/2.0.0" + "security": "https://github.com/sebastianbergmann/lines-of-code/security/policy", + "source": "https://github.com/sebastianbergmann/lines-of-code/tree/2.0.2" }, "funding": [ { @@ -2477,7 +2567,7 @@ "type": "github" } ], - "time": "2023-02-03T07:08:02+00:00" + "time": "2023-12-21T08:38:20+00:00" }, { "name": "sebastian/object-enumerator", @@ -2765,16 +2855,16 @@ }, { "name": "squizlabs/php_codesniffer", - "version": "3.6.0", + "version": "3.6.2", "source": { "type": "git", "url": "https://github.com/PHPCSStandards/PHP_CodeSniffer.git", - "reference": "ffced0d2c8fa8e6cdc4d695a743271fab6c38625" + "reference": "5e4e71592f69da17871dba6e80dd51bce74a351a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHPCSStandards/PHP_CodeSniffer/zipball/ffced0d2c8fa8e6cdc4d695a743271fab6c38625", - "reference": "ffced0d2c8fa8e6cdc4d695a743271fab6c38625", + "url": "https://api.github.com/repos/PHPCSStandards/PHP_CodeSniffer/zipball/5e4e71592f69da17871dba6e80dd51bce74a351a", + "reference": "5e4e71592f69da17871dba6e80dd51bce74a351a", "shasum": "" }, "require": { @@ -2831,20 +2921,20 @@ "type": "open_collective" } ], - "time": "2021-04-09T00:54:41+00:00" + "time": "2021-12-12T21:44:58+00:00" }, { "name": "theseer/tokenizer", - "version": "1.2.0", + "version": "1.2.3", "source": { "type": "git", "url": "https://github.com/theseer/tokenizer.git", - "reference": "75a63c33a8577608444246075ea0af0d052e452a" + "reference": "737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/theseer/tokenizer/zipball/75a63c33a8577608444246075ea0af0d052e452a", - "reference": "75a63c33a8577608444246075ea0af0d052e452a", + "url": "https://api.github.com/repos/theseer/tokenizer/zipball/737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2", + "reference": "737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2", "shasum": "" }, "require": { @@ -2873,7 +2963,7 @@ "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", "support": { "issues": "https://github.com/theseer/tokenizer/issues", - "source": "https://github.com/theseer/tokenizer/tree/master" + "source": "https://github.com/theseer/tokenizer/tree/1.2.3" }, "funding": [ { @@ -2881,7 +2971,7 @@ "type": "github" } ], - "time": "2020-07-12T23:59:07+00:00" + "time": "2024-03-03T12:36:25+00:00" } ], "aliases": [], diff --git a/src/Analyzer/ClassMethodAnalyzer.php b/src/Analyzer/ClassMethodAnalyzer.php index da51ac1c..4e04c6d4 100644 --- a/src/Analyzer/ClassMethodAnalyzer.php +++ b/src/Analyzer/ClassMethodAnalyzer.php @@ -259,10 +259,8 @@ protected function reportChanged($report, $contextBefore, $contextAfter, $method $report->add($this->context, $data); $signatureChanged = true; } elseif ($signatureChanges['parameter_typing_changed']) { - - if ($signatureChanges['parameter_nullable_type_added'] || - $signatureChanges['parameter_nullable_type_removed'] - ) { + if ($signatureChanges['parameter_nullable_type_added'] + || $signatureChanges['parameter_nullable_type_removed']) { $data = new ClassMethodParameterTypingChangedNullable( $this->context, $this->fileAfter, @@ -469,8 +467,7 @@ private function isReturnsEqualByNullability(ClassMethod $before, ClassMethod $a private function getDocReturnDeclaration(ClassMethod $method) { if (($parsedComment = $method->getAttribute('docCommentParsed')) - && isset($parsedComment['return']) - ) { + && isset($parsedComment['return'])) { if ($parsedComment['return'][0] instanceof NullableType) { $result = '?' . $parsedComment['return'][0]->type; } else { diff --git a/src/Comparator/Signature.php b/src/Comparator/Signature.php index cfa79457..b4c829e1 100644 --- a/src/Comparator/Signature.php +++ b/src/Comparator/Signature.php @@ -147,9 +147,11 @@ public static function analyze(array $parametersA, array $parametersB): array if ($parametersA[$i]->type !== null && $parametersB[$i]->type !== null) { $changes['parameter_typing_changed'] = true; // Custom: detect nullable added - if ($typeBefore instanceof \PhpParser\Node\NullableType && !$typeAfter instanceof \PhpParser\Node\NullableType) { + if ($typeBefore instanceof \PhpParser\Node\NullableType + && !$typeAfter instanceof \PhpParser\Node\NullableType) { $changes['parameter_nullable_type_removed'] = true; - } elseif (!$typeBefore instanceof \PhpParser\Node\NullableType && $typeAfter instanceof \PhpParser\Node\NullableType) { + } elseif (!$typeBefore instanceof \PhpParser\Node\NullableType + && $typeAfter instanceof \PhpParser\Node\NullableType) { $changes['parameter_nullable_type_added'] = true; } } elseif ($parametersA[$i]->type !== null) { From 637304a6693b1185b239aa0e4d6f602939741a62 Mon Sep 17 00:00:00 2001 From: Rajesh Kumar Date: Tue, 20 May 2025 18:34:51 +0530 Subject: [PATCH 44/55] AC-14557:: False positives in the backward-incompatible changes report (SVC) --- src/Analyzer/ClassMethodAnalyzer.php | 12 ++++++++---- src/Comparator/Signature.php | 12 ++++++++---- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/src/Analyzer/ClassMethodAnalyzer.php b/src/Analyzer/ClassMethodAnalyzer.php index 4e04c6d4..bca5078d 100644 --- a/src/Analyzer/ClassMethodAnalyzer.php +++ b/src/Analyzer/ClassMethodAnalyzer.php @@ -259,8 +259,10 @@ protected function reportChanged($report, $contextBefore, $contextAfter, $method $report->add($this->context, $data); $signatureChanged = true; } elseif ($signatureChanges['parameter_typing_changed']) { - if ($signatureChanges['parameter_nullable_type_added'] - || $signatureChanges['parameter_nullable_type_removed']) { + if ( + $signatureChanges['parameter_nullable_type_added'] + || $signatureChanges['parameter_nullable_type_removed'] + ) { $data = new ClassMethodParameterTypingChangedNullable( $this->context, $this->fileAfter, @@ -466,8 +468,10 @@ private function isReturnsEqualByNullability(ClassMethod $before, ClassMethod $a */ private function getDocReturnDeclaration(ClassMethod $method) { - if (($parsedComment = $method->getAttribute('docCommentParsed')) - && isset($parsedComment['return'])) { + if ( + ($parsedComment = $method->getAttribute('docCommentParsed')) + && isset($parsedComment['return']) + ) { if ($parsedComment['return'][0] instanceof NullableType) { $result = '?' . $parsedComment['return'][0]->type; } else { diff --git a/src/Comparator/Signature.php b/src/Comparator/Signature.php index b4c829e1..b6c6ae71 100644 --- a/src/Comparator/Signature.php +++ b/src/Comparator/Signature.php @@ -147,11 +147,15 @@ public static function analyze(array $parametersA, array $parametersB): array if ($parametersA[$i]->type !== null && $parametersB[$i]->type !== null) { $changes['parameter_typing_changed'] = true; // Custom: detect nullable added - if ($typeBefore instanceof \PhpParser\Node\NullableType - && !$typeAfter instanceof \PhpParser\Node\NullableType) { + if ( + $typeBefore instanceof \PhpParser\Node\NullableType + && !$typeAfter instanceof \PhpParser\Node\NullableType + ) { $changes['parameter_nullable_type_removed'] = true; - } elseif (!$typeBefore instanceof \PhpParser\Node\NullableType - && $typeAfter instanceof \PhpParser\Node\NullableType) { + } elseif ( + !$typeBefore instanceof \PhpParser\Node\NullableType + && $typeAfter instanceof \PhpParser\Node\NullableType + ) { $changes['parameter_nullable_type_added'] = true; } } elseif ($parametersA[$i]->type !== null) { From 824170bd750e52a46fb50e8b17eee538b0a8b0d4 Mon Sep 17 00:00:00 2001 From: Bhavin Parmar Date: Fri, 23 May 2025 22:37:34 +0530 Subject: [PATCH 45/55] AC-14557:: False positives in the backward-incompatible changes report (SVC) --- src/Analyzer/ClassMethodAnalyzer.php | 8 ++------ src/Comparator/Signature.php | 8 +------- 2 files changed, 3 insertions(+), 13 deletions(-) diff --git a/src/Analyzer/ClassMethodAnalyzer.php b/src/Analyzer/ClassMethodAnalyzer.php index bca5078d..eac3ba16 100644 --- a/src/Analyzer/ClassMethodAnalyzer.php +++ b/src/Analyzer/ClassMethodAnalyzer.php @@ -259,10 +259,7 @@ protected function reportChanged($report, $contextBefore, $contextAfter, $method $report->add($this->context, $data); $signatureChanged = true; } elseif ($signatureChanges['parameter_typing_changed']) { - if ( - $signatureChanges['parameter_nullable_type_added'] - || $signatureChanges['parameter_nullable_type_removed'] - ) { + if ($signatureChanges['parameter_nullable_type_added']) { $data = new ClassMethodParameterTypingChangedNullable( $this->context, $this->fileAfter, @@ -468,8 +465,7 @@ private function isReturnsEqualByNullability(ClassMethod $before, ClassMethod $a */ private function getDocReturnDeclaration(ClassMethod $method) { - if ( - ($parsedComment = $method->getAttribute('docCommentParsed')) + if (($parsedComment = $method->getAttribute('docCommentParsed')) && isset($parsedComment['return']) ) { if ($parsedComment['return'][0] instanceof NullableType) { diff --git a/src/Comparator/Signature.php b/src/Comparator/Signature.php index b6c6ae71..961e0525 100644 --- a/src/Comparator/Signature.php +++ b/src/Comparator/Signature.php @@ -147,14 +147,8 @@ public static function analyze(array $parametersA, array $parametersB): array if ($parametersA[$i]->type !== null && $parametersB[$i]->type !== null) { $changes['parameter_typing_changed'] = true; // Custom: detect nullable added - if ( - $typeBefore instanceof \PhpParser\Node\NullableType + if ($typeBefore instanceof \PhpParser\Node\NullableType && !$typeAfter instanceof \PhpParser\Node\NullableType - ) { - $changes['parameter_nullable_type_removed'] = true; - } elseif ( - !$typeBefore instanceof \PhpParser\Node\NullableType - && $typeAfter instanceof \PhpParser\Node\NullableType ) { $changes['parameter_nullable_type_added'] = true; } From 2a417cba11c3f5169fbd96d15a00c672fdcf246c Mon Sep 17 00:00:00 2001 From: Bhavin Parmar Date: Mon, 26 May 2025 10:23:02 +0530 Subject: [PATCH 46/55] AC-14557:: False positives in the backward-incompatible changes report (SVC) --- src/Analyzer/ClassMethodAnalyzer.php | 3 ++- src/Comparator/Signature.php | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Analyzer/ClassMethodAnalyzer.php b/src/Analyzer/ClassMethodAnalyzer.php index eac3ba16..de81f503 100644 --- a/src/Analyzer/ClassMethodAnalyzer.php +++ b/src/Analyzer/ClassMethodAnalyzer.php @@ -465,7 +465,8 @@ private function isReturnsEqualByNullability(ClassMethod $before, ClassMethod $a */ private function getDocReturnDeclaration(ClassMethod $method) { - if (($parsedComment = $method->getAttribute('docCommentParsed')) + if ( + ($parsedComment = $method->getAttribute('docCommentParsed')) && isset($parsedComment['return']) ) { if ($parsedComment['return'][0] instanceof NullableType) { diff --git a/src/Comparator/Signature.php b/src/Comparator/Signature.php index 961e0525..1807cee9 100644 --- a/src/Comparator/Signature.php +++ b/src/Comparator/Signature.php @@ -147,7 +147,8 @@ public static function analyze(array $parametersA, array $parametersB): array if ($parametersA[$i]->type !== null && $parametersB[$i]->type !== null) { $changes['parameter_typing_changed'] = true; // Custom: detect nullable added - if ($typeBefore instanceof \PhpParser\Node\NullableType + if ( + $typeBefore instanceof \PhpParser\Node\NullableType && !$typeAfter instanceof \PhpParser\Node\NullableType ) { $changes['parameter_nullable_type_added'] = true; From 0054175de765799efff2f059a2a1cea41714a762 Mon Sep 17 00:00:00 2001 From: Bhavin Parmar Date: Mon, 1 Sep 2025 14:48:58 +0530 Subject: [PATCH 47/55] AC-15344:: Add change level to breaking change table report in SVC --- src/Analyzer/ClassMethodAnalyzer.php | 6 ++--- src/Comparator/Signature.php | 7 ++++-- src/Reporter/BreakingChangeTableReporter.php | 26 ++++++++++++++++++-- 3 files changed, 32 insertions(+), 7 deletions(-) diff --git a/src/Analyzer/ClassMethodAnalyzer.php b/src/Analyzer/ClassMethodAnalyzer.php index de81f503..04eb12cf 100644 --- a/src/Analyzer/ClassMethodAnalyzer.php +++ b/src/Analyzer/ClassMethodAnalyzer.php @@ -259,7 +259,8 @@ protected function reportChanged($report, $contextBefore, $contextAfter, $method $report->add($this->context, $data); $signatureChanged = true; } elseif ($signatureChanges['parameter_typing_changed']) { - if ($signatureChanges['parameter_nullable_type_added']) { + if ($signatureChanges['parameter_nullable_type_added'] + || $signatureChanges['parameter_nullable_type_removed']) { $data = new ClassMethodParameterTypingChangedNullable( $this->context, $this->fileAfter, @@ -465,8 +466,7 @@ private function isReturnsEqualByNullability(ClassMethod $before, ClassMethod $a */ private function getDocReturnDeclaration(ClassMethod $method) { - if ( - ($parsedComment = $method->getAttribute('docCommentParsed')) + if (($parsedComment = $method->getAttribute('docCommentParsed')) && isset($parsedComment['return']) ) { if ($parsedComment['return'][0] instanceof NullableType) { diff --git a/src/Comparator/Signature.php b/src/Comparator/Signature.php index 1807cee9..b05bb9d0 100644 --- a/src/Comparator/Signature.php +++ b/src/Comparator/Signature.php @@ -147,11 +147,14 @@ public static function analyze(array $parametersA, array $parametersB): array if ($parametersA[$i]->type !== null && $parametersB[$i]->type !== null) { $changes['parameter_typing_changed'] = true; // Custom: detect nullable added - if ( - $typeBefore instanceof \PhpParser\Node\NullableType + if ($typeBefore instanceof \PhpParser\Node\NullableType && !$typeAfter instanceof \PhpParser\Node\NullableType ) { $changes['parameter_nullable_type_added'] = true; + } elseif (!$typeBefore instanceof \PhpParser\Node\NullableType + && $typeAfter instanceof \PhpParser\Node\NullableType + ) { + $changes['parameter_nullable_type_removed'] = true; } } elseif ($parametersA[$i]->type !== null) { $changes['parameter_typing_removed'] = true; diff --git a/src/Reporter/BreakingChangeTableReporter.php b/src/Reporter/BreakingChangeTableReporter.php index 3ae55e7f..04884665 100644 --- a/src/Reporter/BreakingChangeTableReporter.php +++ b/src/Reporter/BreakingChangeTableReporter.php @@ -16,6 +16,7 @@ class BreakingChangeTableReporter extends TableReporter private $breakChangeLevels = [ Level::MAJOR, Level::MINOR, + Level::PATCH, ]; /** @@ -96,7 +97,7 @@ private function outputChangeReport(OutputInterface $output, Report $report, $co protected function outputTable(OutputInterface $output, Report $report, $context) { $table = new HtmlTableRenderer($output); - $table->setHeaders(['What changed', 'How it changed']); + $table->setHeaders(['Change Level', 'What Changed', 'How It Changed']); $rows = []; foreach (Level::asList('desc') as $level) { if (!in_array($level, $this->breakChangeLevels)) { @@ -105,15 +106,36 @@ protected function outputTable(OutputInterface $output, Report $report, $context $reportForLevel = $report[$context][$level]; /** @var \PHPSemVerChecker\Operation\Operation $operation */ foreach ($reportForLevel as $operation) { + $levelLabel = $this->getLevelLabel($level); $target = $operation->getTarget(); $reason = $operation->getReason(); - $rows[] = [$target, $reason]; + $rows[] = [$levelLabel, $target, $reason]; } } $table->setRows($rows); $table->render(); } + /** + * Get a human-readable label for the change level + * + * @param int $level + * @return string + */ + private function getLevelLabel(int $level): string + { + switch ($level) { + case Level::MAJOR: + return 'MAJOR (Breaking)'; + case Level::MINOR: + return 'MINOR (Non-breaking)'; + case Level::PATCH: + return 'PATCH'; + default: + return 'UNKNOWN'; + } + } + /** * Generate the HTML header line for a report section * From 1d153ff3725f15d18aa168c9ab4263c3114f0463 Mon Sep 17 00:00:00 2001 From: Bhavin Parmar Date: Fri, 5 Sep 2025 15:18:01 +0530 Subject: [PATCH 48/55] AC-15344:: Add change level to breaking change table report in SVC --- src/Reporter/BreakingChangeTableReporter.php | 127 +++++++++++++++++++ 1 file changed, 127 insertions(+) diff --git a/src/Reporter/BreakingChangeTableReporter.php b/src/Reporter/BreakingChangeTableReporter.php index 04884665..79f0f801 100644 --- a/src/Reporter/BreakingChangeTableReporter.php +++ b/src/Reporter/BreakingChangeTableReporter.php @@ -106,6 +106,11 @@ protected function outputTable(OutputInterface $output, Report $report, $context $reportForLevel = $report[$context][$level]; /** @var \PHPSemVerChecker\Operation\Operation $operation */ foreach ($reportForLevel as $operation) { + // Skip private method/property changes as they shouldn't be in breaking change reports + if ($this->isPrivateChange($operation)) { + continue; + } + $levelLabel = $this->getLevelLabel($level); $target = $operation->getTarget(); $reason = $operation->getReason(); @@ -136,6 +141,128 @@ private function getLevelLabel(int $level): string } } + /** + * Check if the operation represents a private method or property change + * + * Private changes are filtered out as they don't affect the public API contract. + * + * @param \PHPSemVerChecker\Operation\Operation $operation + * @return bool + */ + private function isPrivateChange($operation): bool + { + $target = $operation->getTarget(); + $reason = $operation->getReason(); + $operationClass = get_class($operation); + + // For visibility operations, check if they involve private visibility + if ($operation instanceof \Magento\SemanticVersionChecker\Operation\VisibilityOperation) { + try { + // Use reflection to access protected properties + $reflection = new \ReflectionClass($operation); + + if ($reflection->hasProperty('memberBefore')) { + $memberBeforeProperty = $reflection->getProperty('memberBefore'); + $memberBeforeProperty->setAccessible(true); + $memberBefore = $memberBeforeProperty->getValue($operation); + + if ($memberBefore && method_exists('\PHPSemVerChecker\Operation\Visibility', 'getForContext')) { + $visibilityBefore = \PHPSemVerChecker\Operation\Visibility::getForContext($memberBefore); + // 1 = public, 2 = protected, 3 = private + if ($visibilityBefore === 3) { + return true; + } + } + } + + if ($reflection->hasProperty('memberAfter')) { + $memberAfterProperty = $reflection->getProperty('memberAfter'); + $memberAfterProperty->setAccessible(true); + $memberAfter = $memberAfterProperty->getValue($operation); + + if ($memberAfter && method_exists('\PHPSemVerChecker\Operation\Visibility', 'getForContext')) { + $visibilityAfter = \PHPSemVerChecker\Operation\Visibility::getForContext($memberAfter); + // 1 = public, 2 = protected, 3 = private + if ($visibilityAfter === 3) { + return true; + } + } + } + } catch (\Exception $e) { + // Fall back to string matching if reflection fails + } + } + + // Check if the reason explicitly mentions private visibility + if (preg_match('/\[private\]/', $reason)) { + return true; + } + + // Check if the target or reason indicates a private method/property + $privateIndicators = [ + 'private method', + 'private property', + 'Private method', + 'Private property', + '::private', + ' private ', + 'private function', + 'private static', + 'visibility has been changed to lower lever from private', + 'visibility has been changed to higher lever from private', + 'visibility has been changed from private', + 'visibility has been changed to private', + 'Method visibility has been changed from public to private', + 'Method visibility has been changed from protected to private', + 'Property visibility has been changed from public to private', + 'Property visibility has been changed from protected to private', + ]; + + foreach ($privateIndicators as $indicator) { + if (stripos($target, $indicator) !== false || stripos($reason, $indicator) !== false) { + return true; + } + } + + // Check for visibility operations that involve private members + if (strpos($operationClass, 'Visibility') !== false) { + // For visibility operations, check if it involves changing from/to private + if (stripos($reason, 'private') !== false) { + return true; + } + } + + // Check for specific operation classes that handle private changes + $privateOperationClasses = [ + 'PrivateMethod', + 'PrivateProperty', + 'Private', + ]; + + foreach ($privateOperationClasses as $privateClass) { + if (stripos($operationClass, $privateClass) !== false) { + return true; + } + } + + // Check if the target contains patterns that suggest private members + // Pattern: ClassName::privateMethodName or ClassName::$privateProperty + if (preg_match('/::([a-z_][a-zA-Z0-9_]*|\$[a-z_][a-zA-Z0-9_]*)/', $target, $matches)) { + $memberName = $matches[1]; + // If member name starts with underscore (common private naming convention) + if (strpos($memberName, '_') === 0) { + return true; + } + } + + // Check for common private method patterns in the target + if (preg_match('/::(_[a-zA-Z0-9_]+|[a-z][a-zA-Z0-9]*Private[a-zA-Z0-9]*)\(/', $target)) { + return true; + } + + return false; + } + /** * Generate the HTML header line for a report section * From bb9f70b4ba332df8da74ce29aa44122fd0d5598b Mon Sep 17 00:00:00 2001 From: Bhavin Parmar Date: Tue, 9 Sep 2025 13:06:21 +0530 Subject: [PATCH 49/55] AC-15344:: Add change level to breaking change table report in SVC --- composer.json | 2 +- src/Analyzer/ClassMethodAnalyzer.php | 9 ++++++--- src/Comparator/Signature.php | 6 ++++-- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/composer.json b/composer.json index efcd9fa0..8633d49d 100644 --- a/composer.json +++ b/composer.json @@ -1,7 +1,7 @@ { "name": "magento/magento-semver", "description": "Magento Semantic Version Checker", - "version": "13.0.0-beta8", + "version": "13.0.0-beta9", "license": [ "OSL-3.0", "AFL-3.0" diff --git a/src/Analyzer/ClassMethodAnalyzer.php b/src/Analyzer/ClassMethodAnalyzer.php index 04eb12cf..bca5078d 100644 --- a/src/Analyzer/ClassMethodAnalyzer.php +++ b/src/Analyzer/ClassMethodAnalyzer.php @@ -259,8 +259,10 @@ protected function reportChanged($report, $contextBefore, $contextAfter, $method $report->add($this->context, $data); $signatureChanged = true; } elseif ($signatureChanges['parameter_typing_changed']) { - if ($signatureChanges['parameter_nullable_type_added'] - || $signatureChanges['parameter_nullable_type_removed']) { + if ( + $signatureChanges['parameter_nullable_type_added'] + || $signatureChanges['parameter_nullable_type_removed'] + ) { $data = new ClassMethodParameterTypingChangedNullable( $this->context, $this->fileAfter, @@ -466,7 +468,8 @@ private function isReturnsEqualByNullability(ClassMethod $before, ClassMethod $a */ private function getDocReturnDeclaration(ClassMethod $method) { - if (($parsedComment = $method->getAttribute('docCommentParsed')) + if ( + ($parsedComment = $method->getAttribute('docCommentParsed')) && isset($parsedComment['return']) ) { if ($parsedComment['return'][0] instanceof NullableType) { diff --git a/src/Comparator/Signature.php b/src/Comparator/Signature.php index b05bb9d0..7c31b480 100644 --- a/src/Comparator/Signature.php +++ b/src/Comparator/Signature.php @@ -147,11 +147,13 @@ public static function analyze(array $parametersA, array $parametersB): array if ($parametersA[$i]->type !== null && $parametersB[$i]->type !== null) { $changes['parameter_typing_changed'] = true; // Custom: detect nullable added - if ($typeBefore instanceof \PhpParser\Node\NullableType + if ( + $typeBefore instanceof \PhpParser\Node\NullableType && !$typeAfter instanceof \PhpParser\Node\NullableType ) { $changes['parameter_nullable_type_added'] = true; - } elseif (!$typeBefore instanceof \PhpParser\Node\NullableType + } elseif ( + !$typeBefore instanceof \PhpParser\Node\NullableType && $typeAfter instanceof \PhpParser\Node\NullableType ) { $changes['parameter_nullable_type_removed'] = true; From 9c24ef19f7eb310df7084c804db0e41e4ded1d53 Mon Sep 17 00:00:00 2001 From: Bhavin Parmar Date: Tue, 9 Sep 2025 13:17:15 +0530 Subject: [PATCH 50/55] AC-15344:: Add change level to breaking change table report in SVC --- composer.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.lock b/composer.lock index eb6884e8..908ebe88 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "9c90a6e0cf0716bb5a6478500cc4b58f", + "content-hash": "28d690718f848ccaff782df0d832640a", "packages": [ { "name": "hassankhan/config", From 746278575b27bfcea8ec55ee445f0d95a113eb30 Mon Sep 17 00:00:00 2001 From: Bhavin Parmar Date: Tue, 9 Sep 2025 16:12:17 +0530 Subject: [PATCH 51/55] AC-15344:: Add change level to breaking change table report in SVC --- src/Reporter/BreakingChangeTableReporter.php | 107 +------------------ 1 file changed, 3 insertions(+), 104 deletions(-) diff --git a/src/Reporter/BreakingChangeTableReporter.php b/src/Reporter/BreakingChangeTableReporter.php index 79f0f801..23deb1be 100644 --- a/src/Reporter/BreakingChangeTableReporter.php +++ b/src/Reporter/BreakingChangeTableReporter.php @@ -153,110 +153,9 @@ private function isPrivateChange($operation): bool { $target = $operation->getTarget(); $reason = $operation->getReason(); - $operationClass = get_class($operation); - - // For visibility operations, check if they involve private visibility - if ($operation instanceof \Magento\SemanticVersionChecker\Operation\VisibilityOperation) { - try { - // Use reflection to access protected properties - $reflection = new \ReflectionClass($operation); - - if ($reflection->hasProperty('memberBefore')) { - $memberBeforeProperty = $reflection->getProperty('memberBefore'); - $memberBeforeProperty->setAccessible(true); - $memberBefore = $memberBeforeProperty->getValue($operation); - - if ($memberBefore && method_exists('\PHPSemVerChecker\Operation\Visibility', 'getForContext')) { - $visibilityBefore = \PHPSemVerChecker\Operation\Visibility::getForContext($memberBefore); - // 1 = public, 2 = protected, 3 = private - if ($visibilityBefore === 3) { - return true; - } - } - } - - if ($reflection->hasProperty('memberAfter')) { - $memberAfterProperty = $reflection->getProperty('memberAfter'); - $memberAfterProperty->setAccessible(true); - $memberAfter = $memberAfterProperty->getValue($operation); - - if ($memberAfter && method_exists('\PHPSemVerChecker\Operation\Visibility', 'getForContext')) { - $visibilityAfter = \PHPSemVerChecker\Operation\Visibility::getForContext($memberAfter); - // 1 = public, 2 = protected, 3 = private - if ($visibilityAfter === 3) { - return true; - } - } - } - } catch (\Exception $e) { - // Fall back to string matching if reflection fails - } - } - - // Check if the reason explicitly mentions private visibility - if (preg_match('/\[private\]/', $reason)) { - return true; - } - - // Check if the target or reason indicates a private method/property - $privateIndicators = [ - 'private method', - 'private property', - 'Private method', - 'Private property', - '::private', - ' private ', - 'private function', - 'private static', - 'visibility has been changed to lower lever from private', - 'visibility has been changed to higher lever from private', - 'visibility has been changed from private', - 'visibility has been changed to private', - 'Method visibility has been changed from public to private', - 'Method visibility has been changed from protected to private', - 'Property visibility has been changed from public to private', - 'Property visibility has been changed from protected to private', - ]; - - foreach ($privateIndicators as $indicator) { - if (stripos($target, $indicator) !== false || stripos($reason, $indicator) !== false) { - return true; - } - } - - // Check for visibility operations that involve private members - if (strpos($operationClass, 'Visibility') !== false) { - // For visibility operations, check if it involves changing from/to private - if (stripos($reason, 'private') !== false) { - return true; - } - } - - // Check for specific operation classes that handle private changes - $privateOperationClasses = [ - 'PrivateMethod', - 'PrivateProperty', - 'Private', - ]; - - foreach ($privateOperationClasses as $privateClass) { - if (stripos($operationClass, $privateClass) !== false) { - return true; - } - } - - // Check if the target contains patterns that suggest private members - // Pattern: ClassName::privateMethodName or ClassName::$privateProperty - if (preg_match('/::([a-z_][a-zA-Z0-9_]*|\$[a-z_][a-zA-Z0-9_]*)/', $target, $matches)) { - $memberName = $matches[1]; - // If member name starts with underscore (common private naming convention) - if (strpos($memberName, '_') === 0) { - return true; - } - } - - // Check for common private method patterns in the target - if (preg_match('/::(_[a-zA-Z0-9_]+|[a-z][a-zA-Z0-9]*Private[a-zA-Z0-9]*)\(/', $target)) { + + // Simple string check for 'private' keyword (covers all cases) + if (stripos($target, 'private') !== false || stripos($reason, 'private') !== false) { return true; } From 3c29c2ef3013606842dd5034242d850abeafc9ca Mon Sep 17 00:00:00 2001 From: Bhavin Parmar Date: Tue, 9 Sep 2025 18:02:06 +0530 Subject: [PATCH 52/55] AC-15344:: Add change level to breaking change table report in SVC --- src/Reporter/BreakingChangeTableReporter.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Reporter/BreakingChangeTableReporter.php b/src/Reporter/BreakingChangeTableReporter.php index 23deb1be..3e6eb243 100644 --- a/src/Reporter/BreakingChangeTableReporter.php +++ b/src/Reporter/BreakingChangeTableReporter.php @@ -107,7 +107,7 @@ protected function outputTable(OutputInterface $output, Report $report, $context /** @var \PHPSemVerChecker\Operation\Operation $operation */ foreach ($reportForLevel as $operation) { // Skip private method/property changes as they shouldn't be in breaking change reports - if ($this->isPrivateChange($operation)) { + if ($this->isPrivateMemberChange($operation)) { continue; } @@ -149,7 +149,7 @@ private function getLevelLabel(int $level): string * @param \PHPSemVerChecker\Operation\Operation $operation * @return bool */ - private function isPrivateChange($operation): bool + private function isPrivateMemberChange($operation): bool { $target = $operation->getTarget(); $reason = $operation->getReason(); From 6e82f832fd96b62e2eab539817d42376aaa52cdb Mon Sep 17 00:00:00 2001 From: Bhavin Parmar Date: Wed, 10 Sep 2025 13:17:12 +0530 Subject: [PATCH 53/55] AC-15344:: Add change level to breaking change table report in SVC --- src/Reporter/BreakingChangeTableReporter.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Reporter/BreakingChangeTableReporter.php b/src/Reporter/BreakingChangeTableReporter.php index 3e6eb243..aac7782e 100644 --- a/src/Reporter/BreakingChangeTableReporter.php +++ b/src/Reporter/BreakingChangeTableReporter.php @@ -149,7 +149,7 @@ private function getLevelLabel(int $level): string * @param \PHPSemVerChecker\Operation\Operation $operation * @return bool */ - private function isPrivateMemberChange($operation): bool + private function isPrivateMemberChange(\PHPSemVerChecker\Operation\Operation $operation): bool { $target = $operation->getTarget(); $reason = $operation->getReason(); From e386f841a18786c0e9496adb3f8d2fd5f5aac574 Mon Sep 17 00:00:00 2001 From: Bhavin Parmar Date: Wed, 10 Sep 2025 17:19:38 +0530 Subject: [PATCH 54/55] AC-15344:: Add change level to breaking change table report in SVC --- src/Comparator/Signature.php | 12 ++++++------ src/Reporter/BreakingChangeTableReporter.php | 7 ++++--- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/src/Comparator/Signature.php b/src/Comparator/Signature.php index 7c31b480..4d14960e 100644 --- a/src/Comparator/Signature.php +++ b/src/Comparator/Signature.php @@ -10,6 +10,7 @@ namespace Magento\SemanticVersionChecker\Comparator; use PHPSemVerChecker\Comparator\Node; +use PhpParser\Node\NullableType; class Signature extends \PHPSemVerChecker\Comparator\Signature { @@ -47,6 +48,7 @@ public static function isOptionalParams(array $params) /** * Checks type hinting to determine if each parameter is non-Scalar. + * * It assumes proper PHP code style is followed, meaning only non-Scalar parameters have type hinting. * * @param array $params Array of PhpParser\Node\Param objects @@ -147,14 +149,12 @@ public static function analyze(array $parametersA, array $parametersB): array if ($parametersA[$i]->type !== null && $parametersB[$i]->type !== null) { $changes['parameter_typing_changed'] = true; // Custom: detect nullable added - if ( - $typeBefore instanceof \PhpParser\Node\NullableType - && !$typeAfter instanceof \PhpParser\Node\NullableType + if ($typeBefore instanceof NullableType + && !$typeAfter instanceof NullableType ) { $changes['parameter_nullable_type_added'] = true; - } elseif ( - !$typeBefore instanceof \PhpParser\Node\NullableType - && $typeAfter instanceof \PhpParser\Node\NullableType + } elseif (!$typeBefore instanceof NullableType + && $typeAfter instanceof NullableType ) { $changes['parameter_nullable_type_removed'] = true; } diff --git a/src/Reporter/BreakingChangeTableReporter.php b/src/Reporter/BreakingChangeTableReporter.php index aac7782e..8d7286f3 100644 --- a/src/Reporter/BreakingChangeTableReporter.php +++ b/src/Reporter/BreakingChangeTableReporter.php @@ -10,6 +10,7 @@ use PHPSemVerChecker\Report\Report; use PHPSemVerChecker\SemanticVersioning\Level; use Symfony\Component\Console\Output\OutputInterface; +use PHPSemVerChecker\Operation\Operation; class BreakingChangeTableReporter extends TableReporter { @@ -104,7 +105,7 @@ protected function outputTable(OutputInterface $output, Report $report, $context continue; } $reportForLevel = $report[$context][$level]; - /** @var \PHPSemVerChecker\Operation\Operation $operation */ + /** @var Operation $operation */ foreach ($reportForLevel as $operation) { // Skip private method/property changes as they shouldn't be in breaking change reports if ($this->isPrivateMemberChange($operation)) { @@ -146,10 +147,10 @@ private function getLevelLabel(int $level): string * * Private changes are filtered out as they don't affect the public API contract. * - * @param \PHPSemVerChecker\Operation\Operation $operation + * @param Operation $operation * @return bool */ - private function isPrivateMemberChange(\PHPSemVerChecker\Operation\Operation $operation): bool + private function isPrivateMemberChange(Operation $operation): bool { $target = $operation->getTarget(); $reason = $operation->getReason(); From cd4e15fd3c382f681793e6cd4c5f77a51155a68d Mon Sep 17 00:00:00 2001 From: Bhavin Parmar Date: Wed, 10 Sep 2025 17:24:30 +0530 Subject: [PATCH 55/55] AC-15344:: Add change level to breaking change table report in SVC --- src/Comparator/Signature.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Comparator/Signature.php b/src/Comparator/Signature.php index 4d14960e..bbcf4e33 100644 --- a/src/Comparator/Signature.php +++ b/src/Comparator/Signature.php @@ -149,11 +149,13 @@ public static function analyze(array $parametersA, array $parametersB): array if ($parametersA[$i]->type !== null && $parametersB[$i]->type !== null) { $changes['parameter_typing_changed'] = true; // Custom: detect nullable added - if ($typeBefore instanceof NullableType + if ( + $typeBefore instanceof NullableType && !$typeAfter instanceof NullableType ) { $changes['parameter_nullable_type_added'] = true; - } elseif (!$typeBefore instanceof NullableType + } elseif ( + !$typeBefore instanceof NullableType && $typeAfter instanceof NullableType ) { $changes['parameter_nullable_type_removed'] = true;