Skip to content

Commit ae39283

Browse files
authored
Merge pull request #64 from magento-gl/AC-15344
AC-15344:: Add change level to breaking change table report in SVC
2 parents 4c476cb + cd4e15f commit ae39283

File tree

5 files changed

+67
-8
lines changed

5 files changed

+67
-8
lines changed

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "magento/magento-semver",
33
"description": "Magento Semantic Version Checker",
4-
"version": "13.0.0-beta8",
4+
"version": "13.0.0-beta9",
55
"license": [
66
"OSL-3.0",
77
"AFL-3.0"

composer.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/Analyzer/ClassMethodAnalyzer.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,10 @@ protected function reportChanged($report, $contextBefore, $contextAfter, $method
259259
$report->add($this->context, $data);
260260
$signatureChanged = true;
261261
} elseif ($signatureChanges['parameter_typing_changed']) {
262-
if ($signatureChanges['parameter_nullable_type_added']) {
262+
if (
263+
$signatureChanges['parameter_nullable_type_added']
264+
|| $signatureChanges['parameter_nullable_type_removed']
265+
) {
263266
$data = new ClassMethodParameterTypingChangedNullable(
264267
$this->context,
265268
$this->fileAfter,

src/Comparator/Signature.php

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
namespace Magento\SemanticVersionChecker\Comparator;
1111

1212
use PHPSemVerChecker\Comparator\Node;
13+
use PhpParser\Node\NullableType;
1314

1415
class Signature extends \PHPSemVerChecker\Comparator\Signature
1516
{
@@ -47,6 +48,7 @@ public static function isOptionalParams(array $params)
4748

4849
/**
4950
* Checks type hinting to determine if each parameter is non-Scalar.
51+
*
5052
* It assumes proper PHP code style is followed, meaning only non-Scalar parameters have type hinting.
5153
*
5254
* @param array $params Array of PhpParser\Node\Param objects
@@ -148,10 +150,15 @@ public static function analyze(array $parametersA, array $parametersB): array
148150
$changes['parameter_typing_changed'] = true;
149151
// Custom: detect nullable added
150152
if (
151-
$typeBefore instanceof \PhpParser\Node\NullableType
152-
&& !$typeAfter instanceof \PhpParser\Node\NullableType
153+
$typeBefore instanceof NullableType
154+
&& !$typeAfter instanceof NullableType
153155
) {
154156
$changes['parameter_nullable_type_added'] = true;
157+
} elseif (
158+
!$typeBefore instanceof NullableType
159+
&& $typeAfter instanceof NullableType
160+
) {
161+
$changes['parameter_nullable_type_removed'] = true;
155162
}
156163
} elseif ($parametersA[$i]->type !== null) {
157164
$changes['parameter_typing_removed'] = true;

src/Reporter/BreakingChangeTableReporter.php

Lines changed: 52 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,14 @@
1010
use PHPSemVerChecker\Report\Report;
1111
use PHPSemVerChecker\SemanticVersioning\Level;
1212
use Symfony\Component\Console\Output\OutputInterface;
13+
use PHPSemVerChecker\Operation\Operation;
1314

1415
class BreakingChangeTableReporter extends TableReporter
1516
{
1617
private $breakChangeLevels = [
1718
Level::MAJOR,
1819
Level::MINOR,
20+
Level::PATCH,
1921
];
2022

2123
/**
@@ -96,24 +98,71 @@ private function outputChangeReport(OutputInterface $output, Report $report, $co
9698
protected function outputTable(OutputInterface $output, Report $report, $context)
9799
{
98100
$table = new HtmlTableRenderer($output);
99-
$table->setHeaders(['What changed', 'How it changed']);
101+
$table->setHeaders(['<strong>Change Level</strong>', '<strong>What Changed</strong>', '<strong>How It Changed</strong>']);
100102
$rows = [];
101103
foreach (Level::asList('desc') as $level) {
102104
if (!in_array($level, $this->breakChangeLevels)) {
103105
continue;
104106
}
105107
$reportForLevel = $report[$context][$level];
106-
/** @var \PHPSemVerChecker\Operation\Operation $operation */
108+
/** @var Operation $operation */
107109
foreach ($reportForLevel as $operation) {
110+
// Skip private method/property changes as they shouldn't be in breaking change reports
111+
if ($this->isPrivateMemberChange($operation)) {
112+
continue;
113+
}
114+
115+
$levelLabel = $this->getLevelLabel($level);
108116
$target = $operation->getTarget();
109117
$reason = $operation->getReason();
110-
$rows[] = [$target, $reason];
118+
$rows[] = [$levelLabel, $target, $reason];
111119
}
112120
}
113121
$table->setRows($rows);
114122
$table->render();
115123
}
116124

125+
/**
126+
* Get a human-readable label for the change level
127+
*
128+
* @param int $level
129+
* @return string
130+
*/
131+
private function getLevelLabel(int $level): string
132+
{
133+
switch ($level) {
134+
case Level::MAJOR:
135+
return '<span style="color: #d73a49; font-weight: bold;">MAJOR (Breaking)</span>';
136+
case Level::MINOR:
137+
return '<span style="color: #f6a434; font-weight: bold;">MINOR (Non-breaking)</span>';
138+
case Level::PATCH:
139+
return '<span style="color: #28a745; font-weight: bold;">PATCH</span>';
140+
default:
141+
return 'UNKNOWN';
142+
}
143+
}
144+
145+
/**
146+
* Check if the operation represents a private method or property change
147+
*
148+
* Private changes are filtered out as they don't affect the public API contract.
149+
*
150+
* @param Operation $operation
151+
* @return bool
152+
*/
153+
private function isPrivateMemberChange(Operation $operation): bool
154+
{
155+
$target = $operation->getTarget();
156+
$reason = $operation->getReason();
157+
158+
// Simple string check for 'private' keyword (covers all cases)
159+
if (stripos($target, 'private') !== false || stripos($reason, 'private') !== false) {
160+
return true;
161+
}
162+
163+
return false;
164+
}
165+
117166
/**
118167
* Generate the HTML header line for a report section
119168
*

0 commit comments

Comments
 (0)