feat(arch/binary): .PKGINFO parser
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <[email protected]>
This commit is contained in:
@@ -0,0 +1,74 @@
|
||||
package binary
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// PKGInfo is the parsed content of an ALPM .PKGINFO file, the metadata
|
||||
// member at the root of an Arch .pkg.tar.zst package.
|
||||
type PKGInfo struct {
|
||||
Name, Version, Desc, URL, Arch string
|
||||
Depends, OptDepends, Provides, Conflicts, Replaces []string
|
||||
}
|
||||
|
||||
// Parse parses ALPM .PKGINFO content: lines of "key = value", full-line
|
||||
// `#` comments and blank lines ignored. Multi-value keys (depend,
|
||||
// optdepend, provides, conflicts, replaces, license) accumulate across
|
||||
// lines; single-value keys (pkgname, pkgver, pkgdesc, url, arch, pkgbase)
|
||||
// take the last occurrence. pkgver is the FULL version, already in
|
||||
// epoch+pkgrel form (e.g. "1.0-1" or "1:1.0.0-1"), and is passed through
|
||||
// verbatim. Unknown keys are ignored. Malformed lines (no '=') are
|
||||
// reported through warn and skipped, not fatal.
|
||||
//
|
||||
// Parse returns an error if pkgname is missing: a .PKGINFO without a name
|
||||
// is invalid for conversion.
|
||||
func Parse(src string, warn func(string)) (*PKGInfo, error) {
|
||||
info := &PKGInfo{}
|
||||
haveName := false
|
||||
for _, line := range strings.Split(src, "\n") {
|
||||
line = strings.TrimSpace(line)
|
||||
if line == "" || strings.HasPrefix(line, "#") {
|
||||
continue
|
||||
}
|
||||
eq := strings.Index(line, "=")
|
||||
if eq < 0 {
|
||||
if warn != nil {
|
||||
warn("malformed .PKGINFO line (no '='): " + line)
|
||||
}
|
||||
continue
|
||||
}
|
||||
key := strings.TrimSpace(line[:eq])
|
||||
value := strings.TrimSpace(line[eq+1:])
|
||||
switch key {
|
||||
case "pkgname":
|
||||
info.Name = value
|
||||
haveName = true
|
||||
case "pkgver":
|
||||
info.Version = value
|
||||
case "pkgdesc":
|
||||
info.Desc = value
|
||||
case "url":
|
||||
info.URL = value
|
||||
case "arch":
|
||||
info.Arch = value
|
||||
case "depend":
|
||||
info.Depends = append(info.Depends, value)
|
||||
case "optdepend":
|
||||
info.OptDepends = append(info.OptDepends, value)
|
||||
case "provides":
|
||||
info.Provides = append(info.Provides, value)
|
||||
case "conflicts":
|
||||
info.Conflicts = append(info.Conflicts, value)
|
||||
case "replaces":
|
||||
info.Replaces = append(info.Replaces, value)
|
||||
default:
|
||||
// pkgbase, license, builddate, packager, size, xdata and any
|
||||
// unknown keys are not represented in PKGInfo; ignore them.
|
||||
}
|
||||
}
|
||||
if !haveName {
|
||||
return nil, errors.New("pkginfo: missing pkgname")
|
||||
}
|
||||
return info, nil
|
||||
}
|
||||
Reference in New Issue
Block a user