Arch Linux helpers and parsers
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 

156 lines
3.7 KiB

package archlinux
import (
"bufio"
"encoding/base64"
"encoding/hex"
"fmt"
"io"
"net/url"
"strconv"
"strings"
"time"
)
// ReadPackageDesc reads a package description from a desc file
func ReadPackageDesc(r io.Reader) (*Package, error) {
pkg := new(Package)
if n, ok := r.(namer); ok {
pkg.Filename = n.Name()
}
if err := pkg.readPackageDesc(r); err != nil {
return nil, err
}
if pkg.Name == "" {
return nil, ErrNoPackageName
}
if pkg.Version == "" {
return nil, ErrNoPackageVersion
}
if pkg.Release == "" {
return nil, ErrNoPackageRelease
}
return pkg, nil
}
func (pkg *Package) readPackageDesc(r io.Reader) (err error) {
var (
s = bufio.NewScanner(r)
line string
lines []string
section string
)
for s.Scan() {
if err = s.Err(); err != nil {
if err == io.EOF {
err = nil
}
break
}
line = s.Text()
if len(line) == 0 {
switch section {
case "FILENAME":
pkg.Filename = lines[0]
case "NAME":
pkg.Name = lines[0]
case "BASE":
pkg.Base = lines[0]
case "VERSION":
i := strings.LastIndexByte(lines[0], '-')
if i == -1 {
return fmt.Errorf("archlinux: invalid version %q", lines[0])
}
pkg.Version, pkg.Release = lines[0][:i], lines[0][i+1:]
case "DESC":
pkg.Description = strings.TrimSpace(strings.Join(lines, "\n"))
case "ARCH":
pkg.Arch = make([]string, len(lines))
copy(pkg.Arch, lines)
case "LICENSE":
pkg.License = make([]string, len(lines))
copy(pkg.License, lines)
case "GROUPS":
pkg.Groups = make([]string, len(lines))
copy(pkg.Groups, lines)
case "CSIZE":
if pkg.CompressedSize, err = strconv.ParseInt(lines[0], 10, 64); err != nil {
return
}
case "ISIZE":
if pkg.Size, err = strconv.ParseInt(lines[0], 10, 64); err != nil {
return
}
case "MD5SUM":
if pkg.MD5, err = hex.DecodeString(lines[0]); err != nil {
return
}
case "SHA1SUM":
if pkg.SHA1, err = hex.DecodeString(lines[0]); err != nil {
return
}
case "SHA256SUM":
if pkg.SHA256, err = hex.DecodeString(lines[0]); err != nil {
return
}
case "SHA384SUM":
if pkg.SHA384, err = hex.DecodeString(lines[0]); err != nil {
return
}
case "SHA512SUM":
if pkg.SHA512, err = hex.DecodeString(lines[0]); err != nil {
return
}
case "PGPSIG":
if pkg.PGPSignature, err = base64.StdEncoding.DecodeString(lines[0]); err != nil {
return
}
case "URL":
if pkg.URL, err = url.Parse(lines[0]); err != nil {
return
}
case "DEPENDS":
pkg.Depends = make([]string, len(lines))
copy(pkg.Depends, lines)
case "OPTDEPENDS":
pkg.OptionalDepends = make([]string, len(lines))
copy(pkg.OptionalDepends, lines)
case "MAKEDEPENDS":
pkg.MakeDepends = make([]string, len(lines))
copy(pkg.MakeDepends, lines)
case "CHECKDEPENDS":
pkg.CheckDepends = make([]string, len(lines))
copy(pkg.CheckDepends, lines)
case "PROVIDES":
pkg.Provides = make([]string, len(lines))
copy(pkg.Provides, lines)
case "CONFLICTS":
pkg.Conflicts = make([]string, len(lines))
copy(pkg.Conflicts, lines)
case "REPLACES":
pkg.Replaces = make([]string, len(lines))
copy(pkg.Replaces, lines)
case "BUILDDATE":
var i int64
if i, err = strconv.ParseInt(lines[0], 10, 64); err != nil {
return
}
pkg.BuildDate = time.Unix(i, 0)
case "PACKAGER":
pkg.Packager = lines[0]
case "FILES":
pkg.Files = make([]string, len(lines))
copy(lines, pkg.Files)
default:
return fmt.Errorf("archlinux: unsupported desc section %q", section)
}
} else if line[0] == '%' && line[len(line)-1] == '%' {
section = line[1 : len(line)-1]
lines = lines[:0]
} else {
lines = append(lines, line)
}
}
return
}