Skip to content

Instantly share code, notes, and snippets.

@ebfe
Created May 24, 2017 12:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ebfe/c3099f74b95de2d52f84a7d96fd68715 to your computer and use it in GitHub Desktop.
Save ebfe/c3099f74b95de2d52f84a7d96fd68715 to your computer and use it in GitHub Desktop.
package main
import (
"archive/tar"
"bytes"
"compress/gzip"
"encoding/json"
"errors"
"fmt"
"io"
"io/ioutil"
"os"
plist "github.com/DHowett/go-plist"
)
type RepoData struct {
Meta MetaData
Packages Index
}
type MetaData struct {
PubKey []byte `plist:"public-key"`
PubKeySize int `plist:"public-key-size"`
SignatureBy string `plist:"signature-by"`
SignatureType string `plist:"signature-type"`
}
type Index map[string]Package
type Package struct {
Alternatives map[string][]string `plist:"alternatives"`
Arch string `plist:"architecture"`
BuildDate string `plist:"build-date"`
BuildOptions string `plist:"build-options"`
ConfFiles []string `plist:"conf_files"`
Conflicts []string `plist:"conflicts"`
Sha256 string `plist:"filename-sha256"`
Size uint64 `plist:"filename-size"`
Homepage string `plist:"homepage"`
InstallMsg []byte `plist:"install-msg"`
InstalledSize uint64 `plist:"installed_size"`
License string `plist:"license"`
Maintainer string `plist:"maintainer"`
Pkgver string `plist:"pkgver"`
Preserve bool `plist:"preserve"`
Provides []string `plist:"provides"`
Replaces []string `plist:"replaces"`
Reverts []string `plist:"reverts"`
Depends []string `plist:"run_depends"`
ShlibProvides []string `plist:"shlib-provides"`
ShlibRequires []string `plist:"shlib-requires"`
ShortDesc string `plist:"short_desc"`
SourceRevision string `plist:"source-revisions"`
}
func parseRepodata(r io.Reader) (*MetaData, Index, error) {
var meta *MetaData
var index Index
var haveIndex = false
zr, err := gzip.NewReader(r)
if err != nil {
return nil, nil, err
}
ar := tar.NewReader(zr)
for {
hdr, err := ar.Next()
if err != nil {
if err == io.EOF {
break
}
return nil, nil, err
}
if hdr.Name == "index-meta.plist" {
meta, err = parseMetaData(ar)
if err != nil {
return nil, nil, err
}
}
if hdr.Name == "index.plist" {
index, err = parseIndex(ar)
if err != nil {
return nil, nil, err
}
haveIndex = true
}
}
if !haveIndex {
return nil, nil, errors.New("xbps: missing index.plist in repodata")
}
return meta, index, nil
}
func parseIndex(r io.Reader) (Index, error) {
var index Index
buf, err := ioutil.ReadAll(r)
if err != nil {
return nil, err
}
_, err = plist.Unmarshal(buf, &index)
if err != nil {
return nil, err
}
return index, nil
}
func parseMetaData(r io.Reader) (*MetaData, error) {
var md MetaData
buf, err := ioutil.ReadAll(r)
if err != nil {
return nil, err
}
// dummy index-meta.plist in local repos....
if bytes.Equal([]byte("DEADBEEF"), buf) {
return nil, nil
}
_, err = plist.Unmarshal(buf, &md)
if err != nil {
return nil, err
}
return &md, err
}
func main() {
_, pkgs, err := parseRepodata(os.Stdin)
if err != nil {
fmt.Fprintf(os.Stderr, "err: %q\n", err)
os.Exit(1)
}
e := json.NewEncoder(os.Stdout)
e.SetIndent("", "\t")
if err = e.Encode(pkgs); err != nil {
fmt.Fprintf(os.Stderr, "err: %q\n", err)
os.Exit(1)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment