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
|
|
}
|