88from configparser import UNNAMED_SECTION , ConfigParser
99from os import PathLike , environ
1010from pathlib import Path
11- from typing import List , Optional
11+ from typing import Any , List , Optional
1212
1313from ..constants import (
1414 ARCHS ,
@@ -74,7 +74,7 @@ def __init__(
7474 cname ,
7575 )
7676
77- assert re_match , f"Not a valid GardenLinux canonical name { cname } "
77+ assert re_match , f"Not a valid Garden Linux canonical name { cname } "
7878
7979 if re_match .lastindex == 1 :
8080 self ._flavor = re_match [1 ]
@@ -106,7 +106,7 @@ def __init__(
106106 if commit_id_or_hash is not None :
107107 self ._commit_id = commit_id_or_hash [:8 ]
108108
109- if len (commit_id_or_hash ) == 40 : # sha1 hex
109+ if len (commit_id_or_hash ) == 40 or commit_id_or_hash == "local" : # sha1 hex
110110 self ._commit_hash = commit_id_or_hash
111111
112112 @property
@@ -150,7 +150,7 @@ def commit_hash(self) -> str:
150150
151151 if self ._commit_hash is None :
152152 raise RuntimeError (
153- "GardenLinux canonical name given does not contain the commit hash"
153+ "Garden Linux canonical name given does not contain the commit hash"
154154 )
155155
156156 return self ._commit_hash
@@ -391,6 +391,25 @@ def version_epoch(self) -> Optional[int]:
391391
392392 return epoch
393393
394+ def _copy_from_cname_object (self , cname_object : Any ) -> None :
395+ """
396+ Copies values from a given Garden Linux canonical name instance.
397+
398+ :param cname_object: Garden Linux canonical name instance
399+
400+ :since: 1.0.0
401+ """
402+
403+ self ._arch = cname_object .arch
404+ self ._commit_hash = cname_object .commit_hash
405+ self ._commit_id = cname_object .commit_id
406+ self ._feature_set_cached = cname_object .feature_set
407+ self ._feature_elements_cached = cname_object .feature_set_element .split ("," )
408+ self ._feature_flags_cached = cname_object .feature_flag .split ("," )
409+ self ._feature_platforms_cached = cname_object .feature_set_platform .split ("," )
410+ self ._platform_variant_cached = cname_object .platform_variant
411+ self ._version = cname_object .version
412+
394413 def load_from_release_file (self , release_file : PathLike [str ] | str ) -> None :
395414 """
396415 Loads and parses a release metadata file.
@@ -400,6 +419,54 @@ def load_from_release_file(self, release_file: PathLike[str] | str) -> None:
400419 :since: 1.0.0
401420 """
402421
422+ cname_object = CName .new_from_release_file (release_file )
423+
424+ if (
425+ cname_object .flavor != self .flavor
426+ or (
427+ self ._commit_id is not None
428+ and self ._commit_id != cname_object .commit_id
429+ )
430+ or (self ._version is not None and self ._version != cname_object .version )
431+ ):
432+ raise RuntimeError (
433+ f"Release metadata file given is invalid: { release_file } failed consistency check - { self .cname } != { cname_object .cname } "
434+ )
435+
436+ self ._copy_from_cname_object (cname_object )
437+
438+ def save_to_release_file (
439+ self , release_file : PathLike [str ] | str , overwrite : Optional [bool ] = False
440+ ) -> None :
441+ """
442+ Saves the release metadata file.
443+
444+ :param release_file: Release metadata file
445+
446+ :since: 1.0.0
447+ """
448+
449+ if not isinstance (release_file , PathLike ):
450+ release_file = Path (release_file )
451+
452+ if not overwrite and release_file .exists (): # type: ignore[attr-defined]
453+ raise RuntimeError (
454+ f"Refused to overwrite existing release metadata file: { release_file } "
455+ )
456+
457+ with release_file .open ("w" ) as fp : # type: ignore[attr-defined]
458+ fp .write (self .release_metadata_string )
459+
460+ @staticmethod
461+ def new_from_release_file (release_file : PathLike [str ] | str ) -> None :
462+ """
463+ Loads and parses a release metadata file.
464+
465+ :param release_file: Release metadata file
466+
467+ :since: 0.10.10
468+ """
469+
403470 if not isinstance (release_file , PathLike ):
404471 release_file = Path (release_file )
405472
@@ -424,14 +491,6 @@ def load_from_release_file(self, release_file: PathLike[str] | str) -> None:
424491 f"Release metadata file given is invalid: { release_file } misses { release_field } "
425492 )
426493
427- loaded_cname_instance = CName (
428- release_config .get (UNNAMED_SECTION , "GARDENLINUX_CNAME" ).strip ("\" '" )
429- )
430-
431- commit_id = release_config .get (UNNAMED_SECTION , "GARDENLINUX_COMMIT_ID" ).strip (
432- "\" '"
433- )
434-
435494 commit_hash = release_config .get (
436495 UNNAMED_SECTION , "GARDENLINUX_COMMIT_ID_LONG"
437496 ).strip ("\" '" )
@@ -440,68 +499,37 @@ def load_from_release_file(self, release_file: PathLike[str] | str) -> None:
440499 "\" '"
441500 )
442501
443- if (
444- loaded_cname_instance .flavor != self .flavor
445- or loaded_cname_instance .commit_id != commit_id
446- or (self ._commit_id is not None and self ._commit_id != commit_id )
447- or loaded_cname_instance .version != version
448- or (self ._version is not None and self ._version != version )
449- ):
450- raise RuntimeError (
451- f"Release metadata file given is invalid: { release_file } failed consistency check - { self .cname } != { loaded_cname_instance .cname } "
452- )
453-
454- self ._arch = loaded_cname_instance .arch
455- self ._flavor = loaded_cname_instance .flavor
456- self ._commit_hash = commit_hash
457- self ._commit_id = commit_id
458- self ._version = version
502+ cname_object = CName (
503+ release_config .get (UNNAMED_SECTION , "GARDENLINUX_CNAME" ).strip ("\" '" ),
504+ commit_hash = commit_hash ,
505+ version = version ,
506+ )
459507
460- self ._feature_set_cached = release_config .get (
508+ cname_object ._feature_set_cached = release_config .get (
461509 UNNAMED_SECTION , "GARDENLINUX_FEATURES"
462510 ).strip ("\" '" )
463511
464- self ._feature_elements_cached = (
512+ cname_object ._feature_elements_cached = (
465513 release_config .get (UNNAMED_SECTION , "GARDENLINUX_FEATURES_ELEMENTS" )
466514 .strip ("\" '" )
467515 .split ("," )
468516 )
469517
470- self ._feature_flags_cached = (
518+ cname_object ._feature_flags_cached = (
471519 release_config .get (UNNAMED_SECTION , "GARDENLINUX_FEATURES_FLAGS" )
472520 .strip ("\" '" )
473521 .split ("," )
474522 )
475523
476- self ._feature_platforms_cached = (
524+ cname_object ._feature_platforms_cached = (
477525 release_config .get (UNNAMED_SECTION , "GARDENLINUX_FEATURES_PLATFORMS" )
478526 .strip ("\" '" )
479527 .split ("," )
480528 )
481529
482530 if release_config .has_option (UNNAMED_SECTION , "GARDENLINUX_PLATFORM_VARIANT" ):
483- self ._platform_variant_cached = release_config .get (
531+ cname_object ._platform_variant_cached = release_config .get (
484532 UNNAMED_SECTION , "GARDENLINUX_PLATFORM_VARIANT"
485533 ).strip ("\" '" )
486534
487- def save_to_release_file (
488- self , release_file : PathLike [str ] | str , overwrite : Optional [bool ] = False
489- ) -> None :
490- """
491- Saves the release metadata file.
492-
493- :param release_file: Release metadata file
494-
495- :since: 1.0.0
496- """
497-
498- if not isinstance (release_file , PathLike ):
499- release_file = Path (release_file )
500-
501- if not overwrite and release_file .exists (): # type: ignore[attr-defined]
502- raise RuntimeError (
503- f"Refused to overwrite existing release metadata file: { release_file } "
504- )
505-
506- with release_file .open ("w" ) as fp : # type: ignore[attr-defined]
507- fp .write (self .release_metadata_string )
535+ return cname_object
0 commit comments