Skip to content

Commit ffc943f

Browse files
committed
Updated validation method structure.
1 parent e5efcca commit ffc943f

File tree

1 file changed

+51
-38
lines changed

1 file changed

+51
-38
lines changed

web/modules/custom/sdc_validator/src/Commands/ValidateComponentCommand.php

Lines changed: 51 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,17 @@
44

55
namespace Drupal\sdc_validator\Commands;
66

7+
use Consolidation\AnnotatedCommand\CommandResult;
78
use Drupal\Core\Plugin\Component;
89
use Drupal\Core\Render\Component\Exception\InvalidComponentException;
910
use Drupal\Core\Template\ComponentNodeVisitor;
1011
use Drupal\Core\Template\TwigEnvironment;
1112
use Drupal\Core\Theme\Component\ComponentValidator;
1213
use Drupal\Core\Theme\ComponentPluginManager;
1314
use Drush\Commands\DrushCommands;
15+
use Psy\Command\Command;
1416
use Symfony\Component\Yaml\Yaml;
1517
use Twig\Error\Error;
16-
use Twig\Node\Node;
1718

1819
/**
1920
* Validates SDC component definitions using Drupal core's ComponentValidator.
@@ -51,8 +52,10 @@ public function __construct(protected ComponentPluginManager $componentPluginMan
5152
* @command sdc_validator:validate
5253
* @usage drush sdc_validator:validate '<path to components>'
5354
* @usage drush sdc_validator:validate 'web/themes/custom/civictheme/components'
55+
*
56+
* @SuppressWarnings(PHPMD.StaticAccess)
5457
*/
55-
public function validateComponentDefinitions(string $components_path): void {
58+
public function validateComponentDefinitions(string $components_path): CommandResult {
5659
if (!is_dir($components_path)) {
5760
throw new \Exception('❌ Components directory not found: ' . $components_path);
5861
}
@@ -86,36 +89,8 @@ public function validateComponentDefinitions(string $components_path): void {
8689
$component_name = basename((string) $component_file, '.component.yml');
8790
$component_id = $component_base_identifier . ':' . $component_name;
8891
$component = $this->componentPluginManager->find($component_id);
89-
$template_path = $component->getTemplatePath();
90-
if ($template_path === NULL) {
91-
throw new \Exception(sprintf('❌ %s does not have a template.', $component_id));
92-
}
93-
$source = $this->twig->getLoader()->getSourceContext($template_path);
94-
try {
95-
// Need to load as a component.
96-
$node_tree = $this->twig->parse($this->twig->tokenize($source));
97-
}
98-
catch (Error $error) {
99-
throw new \Exception("❌ Error parsing twig file: " . $error->getMessage(), $error->getCode(), $error);
100-
}
101-
$this->validateSlots($component, $node_tree->getNode('blocks'));
102-
$definition = Yaml::parseFile($component_file);
103-
// Merge with additional required keys.
104-
$definition = array_merge(
105-
$definition,
106-
[
107-
'machineName' => $component_name,
108-
'extension_type' => 'theme',
109-
'id' => 'civictheme:' . $component_name,
110-
'library' => ['css' => ['component' => ['foo.css' => []]]],
111-
'path' => '',
112-
'provider' => 'civictheme',
113-
'template' => $component_name . '.twig',
114-
'group' => 'civictheme-group',
115-
'description' => 'CivicTheme component',
116-
]
117-
);
118-
$this->validateComponentFile($definition);
92+
$this->validateSlots($component);
93+
$this->validateComponentFile($component_file, $component_id);
11994
$valid_count++;
12095
}
12196
catch (\Exception $e) {
@@ -135,20 +110,39 @@ public function validateComponentDefinitions(string $components_path): void {
135110
foreach ($errors as $error) {
136111
$this->output()->writeln(sprintf("❌ %s - %s", $error['file'], $error['error']));
137112
}
138-
throw new \Exception("Component validation failed.");
113+
return CommandResult::dataWithExitCode('Component validation failed.', Command::FAILURE);
139114
}
140-
$this->output()->writeln("✨ All components are valid");
115+
return CommandResult::dataWithExitCode('✨ All components are valid', Command::SUCCESS);
141116
}
142117

143118
/**
144119
* Validates a single component definition file.
145120
*
146-
* @param array $definition
147-
* The component definition.
121+
* @param string $component_file
122+
* Path to the file.
123+
* @param string $component_id
124+
* The component id.
148125
*
149126
* @throws \Drupal\Core\Render\Component\Exception\InvalidComponentException
150127
*/
151-
public function validateComponentFile(array $definition): void {
128+
public function validateComponentFile(string $component_file, string $component_id): void {
129+
[, $component_name] = explode(':', $component_id);
130+
$definition = Yaml::parseFile($component_file);
131+
// Merge with additional required keys.
132+
$definition = array_merge(
133+
$definition,
134+
[
135+
'machineName' => $component_name,
136+
'extension_type' => 'theme',
137+
'id' => $component_id,
138+
'library' => ['css' => ['component' => ['foo.css' => []]]],
139+
'path' => '',
140+
'provider' => 'civictheme',
141+
'template' => $component_name . '.twig',
142+
'group' => 'civictheme-group',
143+
'description' => 'CivicTheme component',
144+
]
145+
);
152146
$this->componentValidator->validateDefinition($definition, TRUE);
153147
}
154148

@@ -163,12 +157,31 @@ public function validateComponentFile(array $definition): void {
163157
* undeclared slots. This cheap validation lets us validate during runtime
164158
* even in production.
165159
*
160+
* @param \Drupal\Core\Plugin\Component $component
161+
* The component to validate the slots against.
162+
*
166163
* @throws \Drupal\Core\Render\Component\Exception\InvalidComponentException
164+
* When the twig doesn't parse or template does not exist.
165+
* @throws \Exception
167166
* When the slots don't pass validation.
168167
*
169168
* @see \Drupal\Core\Template\ComponentNodeVisitor::validateSlots
170169
*/
171-
protected function validateSlots(Component $component, Node $node): void {
170+
protected function validateSlots(Component $component): void {
171+
$template_path = $component->getTemplatePath();
172+
if ($template_path === NULL) {
173+
throw new \Exception(sprintf('❌ %s does not have a template.', $component->getI));
174+
}
175+
$source = $this->twig->getLoader()->getSourceContext($template_path);
176+
try {
177+
// Need to load as a component.
178+
$node_tree = $this->twig->parse($this->twig->tokenize($source));
179+
$node = $node_tree->getNode('blocks');
180+
}
181+
catch (Error $error) {
182+
throw new \Exception("❌ Error parsing twig file: " . $error->getMessage(), $error->getCode(), $error);
183+
}
184+
172185
$metadata = $component->metadata;
173186
if (!$metadata->mandatorySchemas) {
174187
return;

0 commit comments

Comments
 (0)