88from configparser import UNNAMED_SECTION , ConfigParser
99from os import PathLike , environ
1010from pathlib import Path
11- from typing import List , Optional , Self
11+ from typing import Any , Dict , List , Optional , Self
1212
1313from ..constants import (
1414 ARCHS ,
1515 GL_BUG_REPORT_URL ,
1616 GL_DISTRIBUTION_NAME ,
1717 GL_HOME_URL ,
18+ GL_PLATFORM_FRANKENSTEIN ,
1819 GL_RELEASE_ID ,
1920 GL_SUPPORT_URL ,
2021)
@@ -59,14 +60,21 @@ def __init__(
5960 self ._feature_flags_cached : Optional [List [str ]] = None
6061 self ._feature_platforms_cached : Optional [List [str ]] = None
6162 self ._feature_set_cached : Optional [str ] = None
63+ self ._features_cached : Optional [Dict [str , Any ]] = None
64+ self ._platform_cached : Optional [str ] = None
6265 self ._platform_variant_cached : Optional [str ] = None
6366 self ._flavor = ""
6467 self ._version = None
6568
69+ self ._flag_frankenstein = bool (environ .get ("GL_ALLOW_FRANKENSTEIN" , False ))
70+
6671 self ._flag_multiple_platforms = bool (
67- environ .get ("GL_ALLOW_FRANKENSTEIN " , False )
72+ environ .get ("GL_ALLOW_MULTIPLE_PLATFORMS " , False )
6873 )
6974
75+ if self ._flag_frankenstein :
76+ self ._flag_multiple_platforms = True
77+
7078 commit_id_or_hash = None
7179
7280 if version is not None :
@@ -213,6 +221,20 @@ def flavor(self) -> str:
213221
214222 return self ._flavor
215223
224+ @property
225+ def features (self ) -> Dict [str , Any ]:
226+ """
227+ Returns the features for the cname parsed.
228+
229+ :return: (dict) Features of the cname
230+ :since: 0.10.14
231+ """
232+
233+ if self ._features_cached is None :
234+ self ._features_cached = Parser ().filter_as_dict (self .flavor )
235+
236+ return self ._features_cached
237+
216238 @property
217239 def feature_set (self ) -> str :
218240 """
@@ -239,7 +261,7 @@ def feature_set_element(self) -> str:
239261 if self ._feature_elements_cached is not None :
240262 return "," .join (self ._feature_elements_cached )
241263
242- return "," .join (Parser (). filter_as_dict ( self .flavor ) ["element" ])
264+ return "," .join (self .features ["element" ])
243265
244266 @property
245267 def feature_set_flag (self ) -> str :
@@ -253,7 +275,7 @@ def feature_set_flag(self) -> str:
253275 if self ._feature_flags_cached is not None :
254276 return "," .join (self ._feature_flags_cached )
255277
256- return "," .join (Parser (). filter_as_dict ( self .flavor ) ["flag" ])
278+ return "," .join (self .features ["flag" ])
257279
258280 @property
259281 def feature_set_platform (self ) -> str :
@@ -265,7 +287,7 @@ def feature_set_platform(self) -> str:
265287 """
266288
267289 if self ._feature_platforms_cached is None :
268- platforms = Parser (). filter_as_dict ( self .flavor ) ["platform" ]
290+ platforms = self .features ["platform" ]
269291 else :
270292 platforms = self ._feature_platforms_cached
271293
@@ -274,7 +296,7 @@ def feature_set_platform(self) -> str:
274296
275297 assert len (platforms ) < 2
276298 "Only one platform is supported"
277- return platforms [0 ]
299+ return platforms [0 ] # type: ignore[no-any-return]
278300
279301 @property
280302 def feature_set_list (self ) -> List [str ]:
@@ -293,19 +315,25 @@ def feature_set_list(self) -> List[str]:
293315 @property
294316 def platform (self ) -> str :
295317 """
296- Returns the feature set of type " platform" for the cname parsed.
318+ Returns the platform for the cname parsed.
297319
298- :return: (str) Feature set platforms
320+ :return: (str) Platform
299321 :since: 0.7.0
300322 """
301323
302- if self ._feature_platforms_cached is None :
303- platforms = Parser (). filter_as_dict ( self .flavor )[ "platform" ]
304- else :
324+ if self ._platform_cached is not None :
325+ platforms = [ self ._platform_cached ]
326+ elif self . _feature_platforms_cached is not None :
305327 platforms = self ._feature_platforms_cached
328+ else :
329+ platforms = self .features ["platform" ]
330+
331+ if self ._flag_frankenstein and len (platforms ) > 1 :
332+ return GL_PLATFORM_FRANKENSTEIN
306333
307334 if not self ._flag_multiple_platforms :
308335 assert len (platforms ) < 2
336+ "Only one platform is supported"
309337
310338 return platforms [0 ]
311339
@@ -345,18 +373,8 @@ def release_metadata_string(self) -> str:
345373 :since: 1.0.0
346374 """
347375
348- features = Parser ().filter_as_dict (self .flavor )
349-
350- if not self ._flag_multiple_platforms :
351- assert len (features ["platform" ]) < 2
352- "Only one platform is supported"
353-
354376 commit_hash = self .commit_hash
355377 commit_id = self .commit_id
356- elements = "," .join (features ["element" ])
357- flags = "," .join (features ["flag" ])
358- platform = features ["platform" ][0 ]
359- platforms = "," .join (features ["platform" ])
360378 platform_variant = self .platform_variant
361379 version = self .version
362380
@@ -387,10 +405,10 @@ def release_metadata_string(self) -> str:
387405BUG_REPORT_URL="{ GL_BUG_REPORT_URL } "
388406GARDENLINUX_CNAME="{ self .cname } "
389407GARDENLINUX_FEATURES="{ self .feature_set } "
390- GARDENLINUX_FEATURES_PLATFORMS="{ platforms } "
391- GARDENLINUX_FEATURES_ELEMENTS="{ elements } "
392- GARDENLINUX_FEATURES_FLAGS="{ flags } "
393- GARDENLINUX_PLATFORM="{ platform } "
408+ GARDENLINUX_FEATURES_PLATFORMS="{ self . feature_set_platform } "
409+ GARDENLINUX_FEATURES_ELEMENTS="{ self . feature_set_element } "
410+ GARDENLINUX_FEATURES_FLAGS="{ self . feature_set_flag } "
411+ GARDENLINUX_PLATFORM="{ self . platform } "
394412GARDENLINUX_PLATFORM_VARIANT="{ platform_variant } "
395413GARDENLINUX_VERSION="{ version } "
396414GARDENLINUX_COMMIT_ID="{ commit_id } "
@@ -456,6 +474,7 @@ def _copy_from_cname_object(self, cname_object: Self) -> None:
456474 self ._feature_elements_cached = cname_object .feature_set_element .split ("," )
457475 self ._feature_flags_cached = cname_object .feature_set_flag .split ("," )
458476 self ._feature_platforms_cached = cname_object .feature_set_platform .split ("," )
477+ self ._platform_cached = cname_object .platform
459478 self ._platform_variant_cached = cname_object .platform_variant
460479 self ._version = cname_object .version
461480
@@ -477,6 +496,10 @@ def load_from_release_file(self, release_file: PathLike[str] | str) -> None:
477496 and self ._commit_id != cname_object .commit_id
478497 )
479498 or (self ._version is not None and self ._version != cname_object .version )
499+ or (
500+ not self ._flag_frankenstein
501+ and cname_object .platform not in cname_object .feature_set_platform
502+ )
480503 ):
481504 raise RuntimeError (
482505 f"Release metadata file given is invalid: { release_file } failed consistency check - { self .cname } != { cname_object .cname } "
@@ -531,9 +554,7 @@ def new_from_release_file(release_file: PathLike[str] | str) -> "CName":
531554 "GARDENLINUX_CNAME" ,
532555 "GARDENLINUX_COMMIT_ID_LONG" ,
533556 "GARDENLINUX_FEATURES" ,
534- "GARDENLINUX_FEATURES_ELEMENTS" ,
535- "GARDENLINUX_FEATURES_FLAGS" ,
536- "GARDENLINUX_FEATURES_PLATFORMS" ,
557+ "GARDENLINUX_PLATFORM" ,
537558 "GARDENLINUX_VERSION" ,
538559 ):
539560 if not release_config .has_option (UNNAMED_SECTION , release_field ):
@@ -559,23 +580,30 @@ def new_from_release_file(release_file: PathLike[str] | str) -> "CName":
559580 UNNAMED_SECTION , "GARDENLINUX_FEATURES"
560581 ).strip ("\" '" )
561582
562- cname_object ._feature_elements_cached = (
563- release_config .get (UNNAMED_SECTION , "GARDENLINUX_FEATURES_ELEMENTS" )
564- .strip ("\" '" )
565- .split ("," )
566- )
583+ if release_config .has_option (UNNAMED_SECTION , "GARDENLINUX_FEATURES_ELEMENTS" ):
584+ cname_object ._feature_elements_cached = (
585+ release_config .get (UNNAMED_SECTION , "GARDENLINUX_FEATURES_ELEMENTS" )
586+ .strip ("\" '" )
587+ .split ("," )
588+ )
567589
568- cname_object ._feature_flags_cached = (
569- release_config .get (UNNAMED_SECTION , "GARDENLINUX_FEATURES_FLAGS" )
570- .strip ("\" '" )
571- .split ("," )
572- )
590+ if release_config .has_option (UNNAMED_SECTION , "GARDENLINUX_FEATURES_FLAGS" ):
591+ cname_object ._feature_flags_cached = (
592+ release_config .get (UNNAMED_SECTION , "GARDENLINUX_FEATURES_FLAGS" )
593+ .strip ("\" '" )
594+ .split ("," )
595+ )
573596
574- cname_object ._feature_platforms_cached = (
575- release_config .get (UNNAMED_SECTION , "GARDENLINUX_FEATURES_PLATFORMS" )
576- .strip ("\" '" )
577- .split ("," )
578- )
597+ if release_config .has_option (UNNAMED_SECTION , "GARDENLINUX_FEATURES_PLATFORMS" ):
598+ cname_object ._feature_platforms_cached = (
599+ release_config .get (UNNAMED_SECTION , "GARDENLINUX_FEATURES_PLATFORMS" )
600+ .strip ("\" '" )
601+ .split ("," )
602+ )
603+
604+ cname_object ._platform_cached = release_config .get (
605+ UNNAMED_SECTION , "GARDENLINUX_PLATFORM"
606+ ).strip ("\" '" )
579607
580608 if release_config .has_option (UNNAMED_SECTION , "GARDENLINUX_PLATFORM_VARIANT" ):
581609 cname_object ._platform_variant_cached = release_config .get (
0 commit comments