@@ -44,6 +44,13 @@ class ConfigValidator
4444 'path ' => ConfigType::LIST_ARRAY , // @
4545 'env ' => ConfigType::ASSOC_ARRAY , // @
4646 'append-env ' => ConfigType::ASSOC_ARRAY , // @
47+
48+ // tool type fields (nested under 'tool' key)
49+ 'tool ' => ConfigType::ASSOC_ARRAY ,
50+ 'provides ' => ConfigType::LIST_ARRAY ,
51+ 'binary-subdir ' => ConfigType::STRING ,
52+ 'install-root ' => ConfigType::STRING ,
53+ 'min-version ' => ConfigType::STRING ,
4754 ];
4855
4956 public const array PACKAGE_FIELDS = [
@@ -67,6 +74,9 @@ class ConfigValidator
6774 'path ' => false , // @
6875 'env ' => false , // @
6976 'append-env ' => false , // @
77+
78+ // tool fields (nested object)
79+ 'tool ' => false ,
7080 ];
7181
7282 public const array SUFFIX_ALLOWED_FIELDS = [
@@ -78,6 +88,7 @@ class ConfigValidator
7888 'path ' ,
7989 'env ' ,
8090 'append-env ' ,
91+ 'tools ' ,
8192 ];
8293
8394 public const array PHP_EXTENSION_FIELDS = [
@@ -92,6 +103,13 @@ class ConfigValidator
92103 'os ' => false ,
93104 ];
94105
106+ public const array TOOL_FIELDS = [
107+ 'provides ' => true ,
108+ 'binary-subdir ' => false ,
109+ 'install-root ' => false ,
110+ 'min-version ' => false ,
111+ ];
112+
95113 public const array ARTIFACT_TYPE_FIELDS = [ // [required_fields, optional_fields]
96114 'filelist ' => [['url ' , 'regex ' ], ['extract ' ]],
97115 'git ' => [['url ' ], ['extract ' , 'submodules ' , 'rev ' , 'regex ' ]],
@@ -220,8 +238,8 @@ public static function validateAndLintPackages(string $config_file_name, mixed &
220238 $ fields = self ::SUFFIX_ALLOWED_FIELDS ;
221239 self ::validateSuffixAllowedFields ($ name , $ pkg , $ fields , $ suffixes );
222240
223- // check if "library|target" package has artifact field for target and library types
224- if (in_array ($ pkg ['type ' ], ['target ' , 'library ' ]) && !isset ($ pkg ['artifact ' ])) {
241+ // check if "library|target|tool " package has artifact field
242+ if (in_array ($ pkg ['type ' ], ['target ' , 'library ' , ' tool ' ]) && !isset ($ pkg ['artifact ' ])) {
225243 throw new ValidationException ("Package [ {$ name }] in {$ config_file_name } of type ' {$ pkg ['type ' ]}' must have an 'artifact' field " );
226244 }
227245
@@ -235,6 +253,11 @@ public static function validateAndLintPackages(string $config_file_name, mixed &
235253 self ::validatePhpExtensionFields ($ name , $ pkg );
236254 }
237255
256+ // check if "tool" package has tool specific fields and validate inside
257+ if ($ pkg ['type ' ] === 'tool ' ) {
258+ self ::validateToolFields ($ name , $ pkg );
259+ }
260+
238261 // check for unknown fields
239262 self ::validateNoInvalidFields ('package ' , $ name , $ pkg , array_keys (self ::PACKAGE_FIELD_TYPES ));
240263 }
@@ -397,6 +420,29 @@ private static function validatePhpExtensionFields(int|string $name, mixed $pkg)
397420 self ::validateNoInvalidFields ('php-extension ' , $ name , $ pkg ['php-extension ' ], array_keys (self ::PHP_EXTENSION_FIELDS ));
398421 }
399422
423+ /**
424+ * Validate tool specific fields for tool package type.
425+ */
426+ private static function validateToolFields (int |string $ name , mixed $ pkg ): void
427+ {
428+ if (!isset ($ pkg ['tool ' ])) {
429+ throw new ValidationException ("Package {$ name } of type 'tool' must have a 'tool' field " );
430+ }
431+ if (!is_assoc_array ($ pkg ['tool ' ])) {
432+ throw new ValidationException ("Package {$ name } [tool] must be an object " );
433+ }
434+ foreach (self ::TOOL_FIELDS as $ field => $ required ) {
435+ if ($ required && !isset ($ pkg ['tool ' ][$ field ])) {
436+ throw new ValidationException ("Package {$ name } [tool] must have required field [ {$ field }] " );
437+ }
438+ if (isset ($ pkg ['tool ' ][$ field ])) {
439+ self ::validatePackageFieldType ($ field , $ pkg ['tool ' ][$ field ], $ name );
440+ }
441+ }
442+ // check for unknown fields in tool
443+ self ::validateNoInvalidFields ('tool ' , $ name , $ pkg ['tool ' ], array_keys (self ::TOOL_FIELDS ));
444+ }
445+
400446 private static function validateNoInvalidFields (string $ config_type , int |string $ item_name , mixed $ item_content , array $ allowed_fields ): void
401447 {
402448 foreach ($ item_content as $ k => $ v ) {
0 commit comments