This commit is contained in:
ge
2025-12-09 11:46:57 +03:00
commit d51a419552
8 changed files with 179 additions and 0 deletions

69
os_release.v Normal file
View File

@@ -0,0 +1,69 @@
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()
}