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 }