debian-forge-composer/internal/rpmmd/repository.go
Jacob Kozol 11eb0b5226 rpmmd: sort fetched package list
When dnf-json dumps the packages from the repos passed to it, it does
not sort the packages. In order to properly list and search the
packages, the package list is now sorted before being returned by the
FetchPackageList function.
2019-11-13 14:24:58 +01:00

120 lines
2.4 KiB
Go

package rpmmd
import (
"encoding/json"
"os"
"os/exec"
"sort"
"time"
)
type RepoConfig struct {
Id string `json:"id"`
Name string `json:"name"`
BaseURL string `json:"baseurl,omitempty"`
Metalink string `json:"metalink,omitempty"`
MirrorList string `json:"mirrorlist,omitempty"`
}
type PackageList []Package
type Package struct {
Name string
Summary string
Description string
URL string
Epoch uint
Version string
Release string
Arch string
BuildTime time.Time
License string
}
type PackageSpec struct {
Name string `json:"name"`
Epoch uint `json:"epoch"`
Version string `json:"version,omitempty"`
Release string `json:"release,omitempty"`
Arch string `json:"arch,omitempty"`
}
func runDNF(command string, arguments interface{}, result interface{}) error {
var call = struct {
Command string `json:"command"`
Arguments interface{} `json:"arguments,omitempty"`
}{
command,
arguments,
}
cmd := exec.Command("python3", "dnf-json")
stdin, err := cmd.StdinPipe()
if err != nil {
return err
}
cmd.Stderr = os.Stderr
stdout, err := cmd.StdoutPipe()
if err != nil {
return err
}
err = cmd.Start()
if err != nil {
return err
}
err = json.NewEncoder(stdin).Encode(call)
if err != nil {
return err
}
stdin.Close()
err = json.NewDecoder(stdout).Decode(result)
if err != nil {
return err
}
return cmd.Wait()
}
func FetchPackageList(repos []RepoConfig) (PackageList, error) {
var arguments = struct {
Repos []RepoConfig `json:"repos"`
}{repos}
var packages PackageList
err := runDNF("dump", arguments, &packages)
sort.Slice(packages, func(i, j int) bool {
return packages[i].Name < packages[j].Name
})
return packages, err
}
func Depsolve(specs []string, repos []RepoConfig) ([]PackageSpec, error) {
var arguments = struct {
PackageSpecs []string `json:"package-specs"`
Repos []RepoConfig `json:"repos"`
}{specs, repos}
var dependencies []PackageSpec
err := runDNF("depsolve", arguments, &dependencies)
return dependencies, err
}
func (packages PackageList) Search(name string) (int, int) {
first := sort.Search(len(packages), func(i int) bool {
return packages[i].Name >= name
})
if first == len(packages) || packages[first].Name != name {
return first, 0
}
last := first + 1
for last < len(packages) && packages[last].Name == name {
last++
}
return first, last - first
}