module os_release import os import strings // options contains list of default os-release, initrd-release, extension-release options. pub const options = ['NAME', 'ID', 'ID_LIKE', 'PRETTY_NAME', 'CPE_NAME', 'VARIANT', 'VARIANT_ID', 'VERSION', 'VERSION_ID', 'VERSION_CODENAME', 'BUILD_ID', 'IMAGE_ID', 'IMAGE_VERSION', 'RELEASE_TYPE', 'HOME_URL', 'DOCUMENTATION_URL', 'SUPPORT_URL', 'BUG_REPORT_URL', 'PRIVACY_POLICY_URL', 'SUPPORT_END', 'LOGO', 'ANSI_COLOR', 'VENDOR_NAME', 'VENDOR_URL', 'EXPERIMENT', 'EXPERIMENT_URL', 'DEFAULT_HOSTNAME', 'ARCHITECTURE', 'SYSEXT_LEVEL', 'CONFEXT_LEVEL', 'SYSEXT_SCOPE', 'CONFEXT_SCOPE', 'PORTABLE_PREFIXES']! // os_release reads `/etc/os-release` and `/usr/lib/os-release` files and returns parsed // os-release data. Empty map will be returned if files does not exits or reading issues // caused. The resulting map will contain only options that is present in actual os-release // file. pub fn os_release() map[string]string { mut ret := map[string]string{} for file in ['/etc/os-release', '/usr/lib/os-release'] { ret = parse_file(file) or { continue } } return ret } // parse_file reads the `file` and returns map of os-release key-value pairs. pub fn parse_file(file string) !map[string]string { return parse(os.read_file(file)!) } // parse parses the `content` string and returns map of os-release key-value pairs. // Example: // ``` // assert os_release.parse('PRETTY_NAME="Debian GNU/Linux 13 (trixie)"') == {'PRETTY_NAME': 'Debian GNU/Linux 13 (trixie)'} // ``` pub fn parse(content string) map[string]string { mut ret := map[string]string{} for raw_line in content.split_into_lines() { line := raw_line.trim_space() if line.is_blank() || line.starts_with('#') { continue } key, value := line.split_once('=') or { continue } if key == '' { continue } ret = { ...ret key: unescape(value) } } return ret } fn unescape(s string) string { mut ret := strings.new_builder(128) for i := 0; i < s.len; i++ { if (i == 0 || i == s.len - 1) && s[i] in [`"`, `'`] { continue // trim leading and trailing quotes } if s[i] == `\\` && i + 1 < s.len { ret.write_byte(s[i + 1]) i++ } else { ret.write_byte(s[i]) } } return ret.str() }