updater: support multiple versions of a package in an apt repo
Some apt repos (google-cloud-sdk) have multiple versions of the same package, so we should support that. Now we do. Also added the google-cloud-cli-bin package.
This commit is contained in:
parent
e70f1f9936
commit
1ee7f3f308
5 changed files with 97 additions and 7 deletions
|
@ -8,6 +8,7 @@ require (
|
|||
github.com/docker/docker v25.0.3+incompatible
|
||||
github.com/egym-playground/go-prefix-writer v0.0.0-20180609083313-7326ea162eca
|
||||
github.com/fatih/color v1.15.0
|
||||
github.com/jamespfennell/xz v0.1.2
|
||||
github.com/minio/minio-go/v7 v7.0.70
|
||||
github.com/pkg/errors v0.9.1
|
||||
github.com/spf13/cobra v1.8.0
|
||||
|
|
|
@ -54,6 +54,8 @@ github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.0 h1:Wqo399gCIufwto+VfwCSvsnfGpF
|
|||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.0/go.mod h1:qmOFXW2epJhM0qSnUUYpldc7gVz2KMQwJ/QYCDIa7XU=
|
||||
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
|
||||
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
|
||||
github.com/jamespfennell/xz v0.1.2 h1:iCw5kScLfGCceOKgQaGuj5RilAAlV4iiwauYntak2oU=
|
||||
github.com/jamespfennell/xz v0.1.2/go.mod h1:DhpWvZY1xDkK/6BREFl3c3R/fZh7IBdYq2m7xh4uLl0=
|
||||
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/klauspost/compress v1.17.6 h1:60eq2E/jlfwQXtvZEeBUYADs+BwKBWURIY+Gj2eRGjI=
|
||||
|
|
|
@ -23,12 +23,25 @@ import (
|
|||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/blang/semver/v4"
|
||||
logger "github.com/charmbracelet/log"
|
||||
"github.com/jamespfennell/xz"
|
||||
|
||||
"pault.ag/go/debian/control"
|
||||
)
|
||||
|
||||
// log is the logger for this package.
|
||||
var log = logger.NewWithOptions(os.Stderr, logger.Options{
|
||||
ReportCaller: true,
|
||||
ReportTimestamp: true,
|
||||
Level: logger.DebugLevel,
|
||||
})
|
||||
|
||||
// Repository is a parsed version of a sources.list entry.
|
||||
type Repository struct {
|
||||
// URL is the URL of the repository.
|
||||
|
@ -79,14 +92,14 @@ func GetPackageVersion(l Lookup) (string, error) {
|
|||
var i *index
|
||||
for _, index := range rel.Indexes {
|
||||
for _, comp := range rel.Components {
|
||||
if index.Path == fmt.Sprintf("%s/binary-%s/Packages.gz", comp, l.Architecture) {
|
||||
if strings.HasPrefix(index.Path, fmt.Sprintf("%s/binary-%s/Packages", comp, l.Architecture)) {
|
||||
i = &index
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
if i == nil {
|
||||
return "", fmt.Errorf("failed to find Packages.gz index")
|
||||
return "", fmt.Errorf("failed to find Packages index")
|
||||
}
|
||||
|
||||
// Find the package in the index.
|
||||
|
@ -95,13 +108,39 @@ func GetPackageVersion(l Lookup) (string, error) {
|
|||
return "", fmt.Errorf("failed to parse packages: %w", err)
|
||||
}
|
||||
|
||||
var latestVersion *semver.Version
|
||||
for _, p := range packages {
|
||||
if p.Name == l.Package {
|
||||
return p.Version, nil
|
||||
if p.Name != l.Package {
|
||||
continue
|
||||
}
|
||||
|
||||
plog := log.With("package", p.Name, "version", p.Version)
|
||||
plog.Debug("found package")
|
||||
|
||||
sv, err := semver.ParseTolerant(p.Version)
|
||||
if err != nil {
|
||||
plog.With("error", err).Warn("failed to parse version, skipping")
|
||||
// Can't compare it, skip it.
|
||||
continue
|
||||
}
|
||||
|
||||
// Start w/ this version if it's the first one.
|
||||
if latestVersion == nil {
|
||||
latestVersion = &sv
|
||||
continue
|
||||
}
|
||||
|
||||
// If this version is greater than the latest, update it.
|
||||
if sv.GT(*latestVersion) {
|
||||
latestVersion = &sv
|
||||
}
|
||||
}
|
||||
|
||||
return "", nil
|
||||
if latestVersion == nil {
|
||||
return "", fmt.Errorf("failed to find package: %s", l.Package)
|
||||
}
|
||||
|
||||
return latestVersion.String(), nil
|
||||
}
|
||||
|
||||
// getRepositoryFromSourcesEntry returns a repository from a sources
|
||||
|
@ -132,7 +171,7 @@ func getRepositoryFromSourcesEntry(entry string) (*Repository, error) {
|
|||
}
|
||||
|
||||
// parseRelease parses the Release file for the given repository.
|
||||
func parseRelease(r *Repository, l Lookup) (*release, error) {
|
||||
func parseRelease(r *Repository, _ Lookup) (*release, error) {
|
||||
// TODO(jaredallard): InRelease?
|
||||
releaseURL := fmt.Sprintf("%s/dists/%s/Release", r.URL, r.Distribution)
|
||||
|
||||
|
@ -230,11 +269,21 @@ func parsePackages(p *index) ([]Package, error) {
|
|||
defer resp.Body.Close()
|
||||
|
||||
r := resp.Body
|
||||
if strings.HasSuffix(p.Path, ".gz") {
|
||||
switch filepath.Ext(p.Path) {
|
||||
case ".gz":
|
||||
r, err = gzip.NewReader(r)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create gzip reader: %w", err)
|
||||
}
|
||||
|
||||
case ".xz":
|
||||
r = xz.NewReader(r)
|
||||
case "":
|
||||
// We don't need to handle compression if there is none.
|
||||
break
|
||||
|
||||
default:
|
||||
return nil, fmt.Errorf("unsupported extension for index: %s", filepath.Ext(p.Path))
|
||||
}
|
||||
|
||||
// Parse the index.
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
# Copyright 2020-2023 Gentoo Authors
|
||||
# Distributed under the terms of the GNU General Public License v2
|
||||
|
||||
EAPI=8
|
||||
|
||||
DESCRIPTION="Interact with the Google Cloud Platform"
|
||||
HOMEPAGE="https://cloud.google.com/cli"
|
||||
SITE="https://dl.google.com/dl/cloudsdk/channels/rapid/downloads"
|
||||
SRC_URI="
|
||||
amd64? ( ${SITE}/google-cloud-cli-${PV}-linux-x86_64.tar.gz )
|
||||
arm64? ( ${SITE}/google-cloud-cli-${PV}-linux-arm.tar.gz )
|
||||
"
|
||||
|
||||
LICENSE="Apache-2.0"
|
||||
SLOT="0"
|
||||
KEYWORDS="amd64 arm64 arm"
|
||||
|
||||
QA_PREBUILT="
|
||||
google-cloud-sdk/bin/anothoscli
|
||||
google-cloud-sdk/bin/gcloud-crc32c
|
||||
"
|
||||
RESTRICT="bindist mirror"
|
||||
S="${WORKDIR}"
|
||||
|
||||
src_install() {
|
||||
mkdir -p "${D}/opt/google-cloud-sdk"
|
||||
cp -r "${S}/google-cloud-sdk/"* "${D}/opt/google-cloud-sdk" || die "Install failed!"
|
||||
dosym /opt/google-cloud-sdk/bin/gcloud /usr/bin/gcloud
|
||||
dosym /opt/google-cloud-sdk/bin/gsutil /usr/bin/gsutil
|
||||
|
||||
chmod 4755 /opt/google-cloud-sdk/bin/gsutil
|
||||
chmod 4755 /opt/google-cloud-sdk/bin/gcloud
|
||||
}
|
|
@ -8,6 +8,11 @@ app-admin/1password:
|
|||
options:
|
||||
repository: "deb https://downloads.1password.com/linux/debian/amd64 stable main"
|
||||
package: 1password
|
||||
app-admin/google-cloud-cli-bin:
|
||||
resolver: apt
|
||||
options:
|
||||
repository: "deb https://packages.cloud.google.com/apt cloud-sdk main"
|
||||
package: google-cloud-cli
|
||||
app-admin/op-cli-bin:
|
||||
resolver: apt
|
||||
options:
|
||||
|
|
Loading…
Add table
Reference in a new issue