24
24
class CognitiveMetricsCommand extends Command
25
25
{
26
26
// Option names for exporting metrics in different formats and loading a configuration file.
27
- private const OPTION_EXPORT_JSON = 'export-json ' ;
28
- private const OPTION_EXPORT_CSV = 'export-csv ' ;
29
- private const OPTION_EXPORT_HTML = 'export-html ' ;
30
27
private const OPTION_CONFIG_FILE = 'config ' ;
28
+ private const OPTION_BASELINE = 'baseline ' ;
29
+ private const OPTION_REPORT_TYPE = 'report-type ' ;
30
+ private const OPTION_REPORT_FILE = 'report-file ' ;
31
31
32
32
// Argument name for the path to the PHP files or directories.
33
33
private const ARGUMENT_PATH = 'path ' ;
@@ -52,10 +52,10 @@ protected function configure(): void
52
52
{
53
53
$ this
54
54
->addArgument (self ::ARGUMENT_PATH , InputArgument::REQUIRED , 'Path to PHP files or directories to parse. ' )
55
- ->addOption (self ::OPTION_EXPORT_CSV , null , InputArgument::OPTIONAL , 'Writes metrics to a CSV file ' , null )
56
- ->addOption (self ::OPTION_EXPORT_JSON , null , InputArgument::OPTIONAL , 'Writes metrics to a JSON file ' , null )
57
- ->addOption (self ::OPTION_EXPORT_HTML , null , InputArgument::OPTIONAL , 'Writes metrics to an HTML file ' , null )
58
- ->addOption (self ::OPTION_CONFIG_FILE , null , InputArgument::OPTIONAL , 'Path to a configuration file ' , null );
55
+ ->addOption (self ::OPTION_CONFIG_FILE , ' c ' , InputArgument::OPTIONAL , 'Path to a configuration file ' , null )
56
+ ->addOption (self ::OPTION_BASELINE , ' b ' , InputArgument::OPTIONAL , 'Baseline file to get the delta. ' , null )
57
+ ->addOption (self ::OPTION_REPORT_TYPE , ' r ' , InputArgument::OPTIONAL , 'Type of report to generate (json, csv, html). ' , null , [ ' json ' , ' csv ' , ' html ' ] )
58
+ ->addOption (self ::OPTION_REPORT_FILE , ' f ' , InputArgument::OPTIONAL , 'File to write the report to. ' );
59
59
}
60
60
61
61
/**
@@ -76,18 +76,62 @@ protected function execute(InputInterface $input, OutputInterface $output): int
76
76
return Command::FAILURE ;
77
77
}
78
78
79
+ // Load baseline if the option is provided.
80
+ $ baseline = $ this ->handleBaseLine ($ input );
81
+
79
82
// Generate metrics for the provided path.
80
83
$ metricsCollection = $ this ->metricsFacade ->getCognitiveMetrics ($ path );
81
84
82
- // Render the metrics to the console.
83
- $ this ->metricTextRenderer ->render ($ metricsCollection , $ output );
84
-
85
85
// Handle different export options.
86
- $ this ->handleExportOptions ($ input , $ metricsCollection );
86
+ if (!$ this ->handleExportOptions ($ input , $ output , $ metricsCollection )) {
87
+ return Command::FAILURE ;
88
+ }
89
+
90
+ // Render the metrics to the console.
91
+ $ this ->metricTextRenderer ->render ($ metricsCollection , $ baseline , $ output );
87
92
88
93
return Command::SUCCESS ;
89
94
}
90
95
96
+ /**
97
+ * Handles the baseline option and loads the baseline file if provided.
98
+ *
99
+ * @param InputInterface $input
100
+ * @return array<int, array<string, mixed>>
101
+ * @throws Exception
102
+ */
103
+ private function handleBaseLine (InputInterface $ input ): array
104
+ {
105
+ $ baseline = [];
106
+ $ baselineFile = $ input ->getOption (self ::OPTION_BASELINE );
107
+ if ($ baselineFile ) {
108
+ $ baseline = $ this ->loadBaseline ($ baselineFile );
109
+ }
110
+
111
+ return $ baseline ;
112
+ }
113
+
114
+ /**
115
+ * Loads the baseline file and returns the data as an array.
116
+ *
117
+ * @param string $baselineFile
118
+ * @return array<int, array<string, mixed>> $baseline
119
+ * @throws \JsonException
120
+ */
121
+ private function loadBaseline (string $ baselineFile ): array
122
+ {
123
+ if (!file_exists ($ baselineFile )) {
124
+ throw new Exception ('Baseline file does not exist. ' );
125
+ }
126
+
127
+ $ baseline = file_get_contents ($ baselineFile );
128
+ if ($ baseline === false ) {
129
+ throw new Exception ('Failed to read baseline file. ' );
130
+ }
131
+
132
+ return json_decode ($ baseline , true , 512 , JSON_THROW_ON_ERROR );
133
+ }
134
+
91
135
/**
92
136
* Loads configuration and handles errors.
93
137
*
@@ -110,22 +154,41 @@ private function loadConfiguration(string $configFile, OutputInterface $output):
110
154
* Handles exporting metrics to different formats based on user input.
111
155
*
112
156
* @param InputInterface $input
157
+ * @param OutputInterface $output
113
158
* @param CognitiveMetricsCollection $metricsCollection
114
- * @return void
159
+ * @return bool
115
160
*/
116
- private function handleExportOptions (InputInterface $ input , CognitiveMetricsCollection $ metricsCollection ): void
161
+ private function handleExportOptions (InputInterface $ input , OutputInterface $ output , CognitiveMetricsCollection $ metricsCollection ): bool
117
162
{
118
- $ options = [
119
- self ::OPTION_EXPORT_CSV => 'metricsCollectionToCsv ' ,
120
- self ::OPTION_EXPORT_JSON => 'metricsCollectionToJson ' ,
121
- self ::OPTION_EXPORT_HTML => 'metricsCollectionToHtml ' ,
122
- ];
123
-
124
- foreach ($ options as $ option => $ method ) {
125
- $ file = $ input ->getOption ($ option );
126
- if ($ file ) {
127
- $ this ->metricsFacade ->$ method ($ metricsCollection , $ file );
128
- }
163
+ $ reportType = $ input ->getOption (self ::OPTION_REPORT_TYPE );
164
+ $ reportFile = $ input ->getOption (self ::OPTION_REPORT_FILE );
165
+
166
+ // If both options are missing, return success
167
+ if ($ reportType === null && $ reportFile === null ) {
168
+ return true ;
129
169
}
170
+
171
+ // If one of the options is provided but the other is missing, return false
172
+ if (($ reportType !== null && $ reportFile === null ) || ($ reportType === null && $ reportFile !== null )) {
173
+ $ output ->writeln ('<error>Both report type and file must be provided.</error> ' );
174
+ return false ;
175
+ }
176
+
177
+ // Validate the report type option
178
+ if (!in_array ($ reportType , ['json ' , 'csv ' , 'html ' ])) {
179
+ $ message = sprintf ('Invalid report type `%s` provided. Only `json`, `csv`, and `html` are accepted. ' , $ reportType );
180
+ $ output ->writeln ('<error> ' . $ message . '</error> ' );
181
+ return false ;
182
+ }
183
+
184
+ // Proceed with export based on the report type
185
+ match ($ reportType ) {
186
+ 'json ' => $ this ->metricsFacade ->metricsCollectionToJson ($ metricsCollection , $ reportFile ),
187
+ 'csv ' => $ this ->metricsFacade ->metricsCollectionToCsv ($ metricsCollection , $ reportFile ),
188
+ 'html ' => $ this ->metricsFacade ->metricsCollectionToHtml ($ metricsCollection , $ reportFile ),
189
+ default => null ,
190
+ };
191
+
192
+ return true ;
130
193
}
131
194
}
0 commit comments