diff --git a/.tools/go.mod b/.tools/go.mod index 85d89e9..9abafcf 100644 --- a/.tools/go.mod +++ b/.tools/go.mod @@ -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 diff --git a/.tools/go.sum b/.tools/go.sum index 7b3e71b..82089be 100644 --- a/.tools/go.sum +++ b/.tools/go.sum @@ -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= diff --git a/.tools/internal/resolver/apt/apt.go b/.tools/internal/resolver/apt/apt.go index c859bf1..c88b6ff 100644 --- a/.tools/internal/resolver/apt/apt.go +++ b/.tools/internal/resolver/apt/apt.go @@ -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. diff --git a/app-admin/google-cloud-cli-bin/google-cloud-cli-bin-476.0.0.ebuild b/app-admin/google-cloud-cli-bin/google-cloud-cli-bin-476.0.0.ebuild new file mode 100644 index 0000000..d348658 --- /dev/null +++ b/app-admin/google-cloud-cli-bin/google-cloud-cli-bin-476.0.0.ebuild @@ -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 +} diff --git a/packages.yml b/packages.yml index d078cd2..5f5f378 100644 --- a/packages.yml +++ b/packages.yml @@ -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: