44Canonical name (cname)
55"""
66
7- from typing import Optional
7+ from configparser import ConfigParser , UNNAMED_SECTION
8+ from pathlib import Path
9+ from typing import List , Optional
10+ from os import PathLike
811import re
912
1013from ..constants import ARCHS
@@ -82,6 +85,7 @@ def arch(self) -> Optional[str]:
8285 Returns the architecture for the cname parsed.
8386
8487 :return: (str) CName architecture
88+ :since: 0.7.0
8589 """
8690
8791 return self ._arch
@@ -92,6 +96,7 @@ def cname(self) -> str:
9296 Returns the cname parsed.
9397
9498 :return: (str) CName
99+ :since: 0.7.0
95100 """
96101
97102 cname = self ._flavor
@@ -110,6 +115,7 @@ def commit_id(self) -> Optional[str]:
110115 Returns the commit ID if part of the cname parsed.
111116
112117 :return: (str) Commit ID
118+ :since: 0.7.0
113119 """
114120
115121 return self ._commit_id
@@ -120,6 +126,7 @@ def flavor(self) -> str:
120126 Returns the flavor for the cname parsed.
121127
122128 :return: (str) Flavor
129+ :since: 0.7.0
123130 """
124131
125132 return self ._flavor
@@ -130,8 +137,12 @@ def feature_set(self) -> str:
130137 Returns the feature set for the cname parsed.
131138
132139 :return: (str) Feature set of the cname
140+ :since: 0.7.0
133141 """
134142
143+ if self ._feature_set_cached is not None :
144+ return self ._feature_set_cached
145+
135146 return Parser ().filter_as_string (self .flavor )
136147
137148 @property
@@ -140,16 +151,35 @@ def platform(self) -> str:
140151 Returns the platform for the cname parsed.
141152
142153 :return: (str) Flavor
154+ :since: 0.7.0
143155 """
144156
145- return re .split ("[_-]" , self ._flavor , maxsplit = 1 )[0 ]
157+ if self ._platforms_cached is not None :
158+ return "," .join (self ._platforms_cached )
159+
160+ return "," .join (Parser ().filter_as_dict (self .flavor )["platform" ])
161+
162+ @property
163+ def platforms (self ) -> List [str ]:
164+ """
165+ Returns the platforms for the cname parsed.
166+
167+ :return: (str) Flavor
168+ :since: 0.9.1
169+ """
170+
171+ if self ._platforms_cached is not None :
172+ return self ._platforms_cached
173+
174+ return Parser ().filter_as_dict (self .flavor )["platform" ]
146175
147176 @property
148177 def version (self ) -> Optional [str ]:
149178 """
150179 Returns the version if part of the cname parsed.
151180
152181 :return: (str) Version
182+ :since: 0.7.0
153183 """
154184
155185 return self ._version
@@ -160,9 +190,117 @@ def version_and_commit_id(self) -> Optional[str]:
160190 Returns the version and commit ID if part of the cname parsed.
161191
162192 :return: (str) Version and commit ID
193+ :since: 0.7.0
163194 """
164195
165196 if self ._commit_id is None :
166197 return None
167198
168199 return f"{ self ._version } -{ self ._commit_id } "
200+
201+ def load_from_metadata_file (self , metadata_file : PathLike | str ) -> None :
202+ """
203+ Loads and parses a metadata file.
204+
205+ :param metadata_file: Metadata file containing information about the CName instance.
206+
207+ :since: 0.9.1
208+ """
209+
210+ if not isinstance (metadata_file , PathLike ):
211+ metadata_file = Path (metadata_file )
212+
213+ if not metadata_file .exists ():
214+ raise RuntimeError (f"Metadata file given is invalid: { metadata_file } " )
215+
216+ metadata_config = ConfigParser (allow_unnamed_section = True )
217+ metadata_config .read (metadata_file )
218+
219+ for metadata_field in (
220+ "GARDENLINUX_CNAME" ,
221+ "GARDENLINUX_FEATURES" ,
222+ "GARDENLINUX_FEATURES_PLATFORMS" ,
223+ "GARDENLINUX_VERSION" ,
224+ ):
225+ if not metadata_config .has_option (UNNAMED_SECTION , metadata_field ):
226+ raise RuntimeError (
227+ f"Metadata file given is invalid: { metadata_file } misses { metadata_field } "
228+ )
229+
230+ loaded_cname_instance = CName (
231+ metadata_config .get (UNNAMED_SECTION , "GARDENLINUX_CNAME" )
232+ )
233+
234+ commit_id = metadata_config .get (UNNAMED_SECTION , "GARDENLINUX_COMMIT_ID" )
235+ version = metadata_config .get (UNNAMED_SECTION , "GARDENLINUX_VERSION" )
236+
237+ if (
238+ loaded_cname_instance .flavor != self .flavor
239+ or loaded_cname_instance .commit_id != commit_id
240+ or (self ._commit_id is not None and self ._commit_id != commit_id )
241+ or loaded_cname_instance .version != version
242+ or (self ._version is not None and self ._version != version )
243+ ):
244+ raise RuntimeError (
245+ f"Metadata file given is invalid: { metadata_file } failed consistency check - { self .cname } != { loaded_cname_instance .cname } "
246+ )
247+
248+ self ._arch = loaded_cname_instance .arch
249+ self ._flavor = loaded_cname_instance .flavor
250+ self ._commit_id = commit_id
251+ self ._version = version
252+
253+ self ._feature_set_cached = metadata_config .get (
254+ UNNAMED_SECTION , "GARDENLINUX_FEATURES"
255+ )
256+
257+ self ._platforms_cached = metadata_config .get (
258+ UNNAMED_SECTION , "GARDENLINUX_FEATURES_PLATFORMS"
259+ ).split ("," )
260+
261+ def save_to_metadata_file (
262+ self , metadata_file : PathLike | str , overwrite : Optional [bool ] = False
263+ ) -> None :
264+ """
265+ Saves the metadata file.
266+
267+ :param metadata_file: Metadata file containing information about the CName instance.
268+
269+ :since: 0.9.1
270+ """
271+
272+ if not isinstance (metadata_file , PathLike ):
273+ metadata_file = Path (metadata_file )
274+
275+ if not overwrite and metadata_file .exists ():
276+ raise RuntimeError (
277+ f"Refused to overwrite existing metadata file: { metadata_file } "
278+ )
279+
280+ features = Parser ().filter_as_dict (self .flavor )
281+
282+ elements = "," .join (features ["element" ])
283+ flags = "," .join (features ["flag" ])
284+ platforms = "," .join (features ["platform" ])
285+
286+ metadata = f"""
287+ ID=gardenlinux
288+ NAME="Garden Linux"
289+ PRETTY_NAME="Garden Linux { self .version } "
290+ IMAGE_VERSION={ self .version }
291+ VARIANT_ID="{ self .flavor } -{ self .arch } "
292+ HOME_URL="https://gardenlinux.io"
293+ SUPPORT_URL="https://github.com/gardenlinux/gardenlinux"
294+ BUG_REPORT_URL="https://github.com/gardenlinux/gardenlinux/issues"
295+ GARDENLINUX_CNAME="{ self .cname } "
296+ GARDENLINUX_FEATURES="{ self .feature_set } "
297+ GARDENLINUX_FEATURES_PLATFORMS="{ platforms } "
298+ GARDENLINUX_FEATURES_ELEMENTS="{ elements } "
299+ GARDENLINUX_FEATURES_FLAGS="{ flags } "
300+ GARDENLINUX_VERSION="{ self .version } "
301+ GARDENLINUX_COMMIT_ID="{ self .commit_id } "
302+ GARDENLINUX_COMMIT_ID_LONG=$BUILDER_COMMIT
303+ """ .strip ()
304+
305+ with metadata_file .open ("w" ) as fp :
306+ fp .write (metadata )
0 commit comments