rename AUR metadata client

This commit is contained in:
jguer 2022-11-15 16:22:57 +01:00
parent f042713aaa
commit c00cd8d88e
No known key found for this signature in database
GPG Key ID: 6D6CC9BEA8556B35
11 changed files with 116 additions and 102 deletions

View File

@ -19,18 +19,28 @@ linters-settings:
goimports: goimports:
local-prefixes: github.com/Jguer/yay/v11 local-prefixes: github.com/Jguer/yay/v11
gomnd: gomnd:
settings: checks:
mnd: - argument
# don't include the "operation" and "assign" - case
checks: argument,case,condition,return - condition
- return
ignored-numbers:
- '0'
- '1'
- '2'
- '3'
ignored-functions:
- strings.SplitN
govet: govet:
check-shadowing: true check-shadowing: true
lll: lll:
line-length: 140 line-length: 140
maligned:
suggest-new: true
misspell: misspell:
locale: US locale: US
nolintlint:
allow-unused: false # report any unused nolint directives
require-explanation: false # don't require an explanation for nolint directives
require-specific: false # don't require nolint directives to be specific about which linter is being skipped
linters: linters:
# please, do not use `enable-all`: it's deprecated and will be removed soon. # please, do not use `enable-all`: it's deprecated and will be removed soon.
@ -38,15 +48,19 @@ linters:
disable-all: true disable-all: true
enable: enable:
- bodyclose - bodyclose
- usestdlibvars
- deadcode
- depguard - depguard
- dogsled
- dupl - dupl
- errcheck - errcheck
- exportloopref
# - funlen # TOFIX
- gochecknoinits - gochecknoinits
# - goconst # TOFIX
- gocritic - gocritic
# - gocyclo # TOFIX
- gofmt - gofmt
- goimports - goimports
# - gomnd # TOFIX
- goprintffuncname - goprintffuncname
- gosec - gosec
- gosimple - gosimple
@ -55,28 +69,15 @@ linters:
- lll - lll
- misspell - misspell
- nakedret - nakedret
- prealloc - noctx
- revive - nolintlint
- rowserrcheck
- staticcheck - staticcheck
- structcheck
- stylecheck - stylecheck
- typecheck - typecheck
- unconvert - unconvert
- unparam - unparam
- unused - unused
- tenv
- varcheck
- whitespace - whitespace
- wsl
- godot
# - maligned
# - interfacer
# - nilerr
# - nlreturn
# - exhaustivestruct
# - errname
# - forbidigo
run: run:
go: '1.18' go: '1.18'

2
cmd.go
View File

@ -331,7 +331,7 @@ func handleUpgrade(ctx context.Context,
config *settings.Configuration, dbExecutor db.Executor, cmdArgs *parser.Arguments, config *settings.Configuration, dbExecutor db.Executor, cmdArgs *parser.Arguments,
) error { ) error {
if cmdArgs.ExistsArg("i", "install") { if cmdArgs.ExistsArg("i", "install") {
return installLocalPKGBUILD(ctx, cmdArgs, dbExecutor) return installLocalPKGBUILD(ctx, config, cmdArgs, dbExecutor)
} }
return config.Runtime.CmdBuilder.Show(config.Runtime.CmdBuilder.BuildPacmanCmd(ctx, return config.Runtime.CmdBuilder.Show(config.Runtime.CmdBuilder.BuildPacmanCmd(ctx,

View File

@ -9,7 +9,6 @@ import (
"github.com/Jguer/yay/v11/pkg/db" "github.com/Jguer/yay/v11/pkg/db"
"github.com/Jguer/yay/v11/pkg/dep" "github.com/Jguer/yay/v11/pkg/dep"
"github.com/Jguer/yay/v11/pkg/metadata"
"github.com/Jguer/yay/v11/pkg/settings" "github.com/Jguer/yay/v11/pkg/settings"
"github.com/Jguer/yay/v11/pkg/settings/parser" "github.com/Jguer/yay/v11/pkg/settings/parser"
"github.com/Jguer/yay/v11/pkg/text" "github.com/Jguer/yay/v11/pkg/text"
@ -23,13 +22,11 @@ var ErrInstallRepoPkgs = errors.New(gotext.Get("error installing repo packages")
func installLocalPKGBUILD( func installLocalPKGBUILD(
ctx context.Context, ctx context.Context,
config *settings.Configuration,
cmdArgs *parser.Arguments, cmdArgs *parser.Arguments,
dbExecutor db.Executor, dbExecutor db.Executor,
) error { ) error {
aurCache, err := metadata.NewAURCache(filepath.Join(config.BuildDir, "aur.json")) aurCache := config.Runtime.AURCache
if err != nil {
return errors.Wrap(err, gotext.Get("failed to retrieve aur Cache"))
}
wd, err := os.Getwd() wd, err := os.Getwd()
if err != nil { if err != nil {

View File

@ -3,6 +3,7 @@ package main
import ( import (
"context" "context"
"fmt" "fmt"
"net/http"
"os" "os"
"path/filepath" "path/filepath"
@ -38,7 +39,7 @@ func handleCmd() error {
return err return err
} }
aurCache, err := metadata.NewAURCache(filepath.Join(config.BuildDir, "aur.json")) aurCache, err := metadata.NewAURCache(http.DefaultClient, filepath.Join(config.BuildDir, "aur.json"))
if err != nil { if err != nil {
return errors.Wrap(err, gotext.Get("failed to retrieve aur Cache")) return errors.Wrap(err, gotext.Get("failed to retrieve aur Cache"))
} }

View File

@ -90,7 +90,7 @@ var colorMap = map[Reason]string{
type Grapher struct { type Grapher struct {
dbExecutor db.Executor dbExecutor db.Executor
aurCache *metadata.AURCache aurCache *metadata.AURCacheClient
fullGraph bool // If true, the graph will include all dependencies including already installed ones or repo fullGraph bool // If true, the graph will include all dependencies including already installed ones or repo
noConfirm bool noConfirm bool
w io.Writer // output writer w io.Writer // output writer
@ -98,7 +98,7 @@ type Grapher struct {
providerCache map[string]*aur.Pkg providerCache map[string]*aur.Pkg
} }
func NewGrapher(dbExecutor db.Executor, aurCache *metadata.AURCache, func NewGrapher(dbExecutor db.Executor, aurCache *metadata.AURCacheClient,
fullGraph, noConfirm bool, output io.Writer, fullGraph, noConfirm bool, output io.Writer,
) *Grapher { ) *Grapher {
return &Grapher{ return &Grapher{

View File

@ -15,11 +15,12 @@ const (
cacheValidity = 1 * time.Hour cacheValidity = 1 * time.Hour
) )
type AURCache struct { type AURCacheClient struct {
cache []byte httpClient HTTPRequestDoer
cachePath string cachePath string
DebugLoggerFn func(a ...interface{})
unmarshalledCache []interface{} unmarshalledCache []interface{}
DebugLoggerFn func(a ...interface{})
} }
type AURQuery struct { type AURQuery struct {
@ -28,29 +29,25 @@ type AURQuery struct {
Contains bool // if true, search for packages containing the needle, not exact matches Contains bool // if true, search for packages containing the needle, not exact matches
} }
func NewAURCache(cachePath string) (*AURCache, error) { // ClientOption allows setting custom parameters during construction.
aurCache, err := MakeOrReadCache(cachePath) type ClientOption func(*AURCacheClient) error
if err != nil {
return nil, err
}
inputStruct, err := oj.Parse(aurCache) func NewAURCache(httpClient HTTPRequestDoer, cachePath string, opts ...ClientOption) (*AURCacheClient, error) {
if err != nil { return &AURCacheClient{
return nil, fmt.Errorf("aur metadata unable to parse cache: %w", err) httpClient: httpClient,
} cachePath: cachePath,
return &AURCache{
cache: aurCache,
cachePath: cachePath,
unmarshalledCache: inputStruct.([]interface{}),
}, nil }, nil
} }
// needsUpdate checks if cachepath is older than 24 hours. // needsUpdate checks if cachepath is older than 24 hours.
func (a *AURCache) needsUpdate() (bool, error) { func (a *AURCacheClient) needsUpdate() (bool, error) {
// check if cache is older than 24 hours // check if cache is older than 24 hours
info, err := os.Stat(a.cachePath) info, err := os.Stat(a.cachePath)
if err != nil { if err != nil {
if os.IsNotExist(err) {
return true, nil
}
return false, fmt.Errorf("unable to read cache: %w", err) return false, fmt.Errorf("unable to read cache: %w", err)
} }
@ -58,30 +55,7 @@ func (a *AURCache) needsUpdate() (bool, error) {
} }
// Get returns a list of packages that provide the given search term. // Get returns a list of packages that provide the given search term.
func (a *AURCache) Get(ctx context.Context, query *AURQuery) ([]*aur.Pkg, error) { func (a *AURCacheClient) Get(ctx context.Context, query *AURQuery) ([]*aur.Pkg, error) {
update, err := a.needsUpdate()
if err != nil {
return nil, err
}
if update {
if a.DebugLoggerFn != nil {
a.DebugLoggerFn("AUR Cache is out of date, updating")
}
var makeErr error
if a.cache, makeErr = MakeCache(a.cachePath); makeErr != nil {
return nil, makeErr
}
inputStruct, unmarshallErr := oj.Parse(a.cache)
if unmarshallErr != nil {
return nil, fmt.Errorf("aur metadata unable to parse cache: %w", unmarshallErr)
}
a.unmarshalledCache = inputStruct.([]interface{})
}
found := make([]*aur.Pkg, 0, len(query.Needles)) found := make([]*aur.Pkg, 0, len(query.Needles))
if len(query.Needles) == 0 { if len(query.Needles) == 0 {
return found, nil return found, nil
@ -97,7 +71,49 @@ func (a *AURCache) Get(ctx context.Context, query *AURQuery) ([]*aur.Pkg, error)
return found, nil return found, nil
} }
func (a *AURCache) gojqGetBatch(ctx context.Context, query *AURQuery) ([]*aur.Pkg, error) { func (a *AURCacheClient) cache(ctx context.Context) ([]interface{}, error) {
if a.unmarshalledCache != nil {
return a.unmarshalledCache, nil
}
update, err := a.needsUpdate()
if err != nil {
return nil, err
}
if update {
if a.DebugLoggerFn != nil {
a.DebugLoggerFn("AUR Cache is out of date, updating")
}
cache, makeErr := MakeCache(ctx, a.httpClient, a.cachePath)
if makeErr != nil {
return nil, makeErr
}
inputStruct, unmarshallErr := oj.Parse(cache)
if unmarshallErr != nil {
return nil, fmt.Errorf("aur metadata unable to parse cache: %w", unmarshallErr)
}
a.unmarshalledCache = inputStruct.([]interface{})
} else {
aurCache, err := ReadCache(a.cachePath)
if err != nil {
return nil, err
}
inputStruct, err := oj.Parse(aurCache)
if err != nil {
return nil, fmt.Errorf("aur metadata unable to parse cache: %w", err)
}
a.unmarshalledCache = inputStruct.([]interface{})
}
return a.unmarshalledCache, nil
}
func (a *AURCacheClient) gojqGetBatch(ctx context.Context, query *AURQuery) ([]*aur.Pkg, error) {
pattern := ".[] | select(" pattern := ".[] | select("
for i, searchTerm := range query.Needles { for i, searchTerm := range query.Needles {
@ -130,8 +146,13 @@ func (a *AURCache) gojqGetBatch(ctx context.Context, query *AURQuery) ([]*aur.Pk
return nil, fmt.Errorf("unable to parse query: %w", err) return nil, fmt.Errorf("unable to parse query: %w", err)
} }
unmarshalledCache, errCache := a.cache(ctx)
if errCache != nil {
return nil, errCache
}
final := make([]*aur.Pkg, 0, len(query.Needles)) final := make([]*aur.Pkg, 0, len(query.Needles))
iter := parsed.RunWithContext(ctx, a.unmarshalledCache) // or query.RunWithContext iter := parsed.RunWithContext(ctx, unmarshalledCache) // or query.RunWithContext
for pkgMap, ok := iter.Next(); ok; pkgMap, ok = iter.Next() { for pkgMap, ok := iter.Next(); ok; pkgMap, ok = iter.Next() {
if err, ok := pkgMap.(error); ok { if err, ok := pkgMap.(error); ok {

View File

@ -1,26 +1,15 @@
package metadata package metadata
import ( import (
"context"
"fmt" "fmt"
"io" "io"
"net/http" "net/http"
"os" "os"
) )
func MakeOrReadCache(cachePath string) ([]byte, error) { type HTTPRequestDoer interface {
cacheBytes, err := ReadCache(cachePath) Do(req *http.Request) (*http.Response, error)
if err != nil {
return nil, err
}
if len(cacheBytes) == 0 {
cacheBytes, err = MakeCache(cachePath)
if err != nil {
return nil, err
}
}
return cacheBytes, nil
} }
func ReadCache(cachePath string) ([]byte, error) { func ReadCache(cachePath string) ([]byte, error) {
@ -46,8 +35,8 @@ func ReadCache(cachePath string) ([]byte, error) {
// Download the metadata for aur packages. // Download the metadata for aur packages.
// create cache file // create cache file
// write to cache file. // write to cache file.
func MakeCache(cachePath string) ([]byte, error) { func MakeCache(ctx context.Context, httpClient HTTPRequestDoer, cachePath string) ([]byte, error) {
body, err := downloadAURMetadata() body, err := downloadAURMetadata(ctx, httpClient)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -71,8 +60,13 @@ func MakeCache(cachePath string) ([]byte, error) {
return s, err return s, err
} }
func downloadAURMetadata() (io.ReadCloser, error) { func downloadAURMetadata(ctx context.Context, httpClient HTTPRequestDoer) (io.ReadCloser, error) {
resp, err := http.Get("https://aur.archlinux.org/packages-meta-ext-v1.json.gz") req, err := http.NewRequestWithContext(ctx, "GET", "https://aur.archlinux.org/packages-meta-ext-v1.json.gz", http.NoBody)
if err != nil {
return nil, fmt.Errorf("failed to create request: %w", err)
}
resp, err := httpClient.Do(req)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -39,12 +39,12 @@ type SourceQueryBuilder struct {
singleLineResults bool singleLineResults bool
aurClient aur.ClientInterface aurClient aur.ClientInterface
aurCache *metadata.AURCache aurCache *metadata.AURCacheClient
} }
func NewSourceQueryBuilder( func NewSourceQueryBuilder(
aurClient aur.ClientInterface, aurClient aur.ClientInterface,
aurCache *metadata.AURCache, aurCache *metadata.AURCacheClient,
sortBy string, sortBy string,
targetMode parser.TargetMode, targetMode parser.TargetMode,
searchBy string, searchBy string,
@ -192,7 +192,7 @@ func filterAURResults(pkgS []string, results []aur.Pkg) []aur.Pkg {
// queryAUR searches AUR and narrows based on subarguments. // queryAUR searches AUR and narrows based on subarguments.
func queryAUR(ctx context.Context, func queryAUR(ctx context.Context,
aurClient aur.ClientInterface, aurMetadata *metadata.AURCache, aurClient aur.ClientInterface, aurMetadata *metadata.AURCacheClient,
pkgS []string, searchBy string, newEngine bool, pkgS []string, searchBy string, newEngine bool,
) ([]aur.Pkg, error) { ) ([]aur.Pkg, error) {
var ( var (

View File

@ -291,7 +291,7 @@ func NewConfig(version string) (*Configuration, error) {
var errAURCache error var errAURCache error
newConfig.Runtime.AURCache, errAURCache = metadata.NewAURCache(filepath.Join(newConfig.BuildDir, "aur.json")) newConfig.Runtime.AURCache, errAURCache = metadata.NewAURCache(newConfig.Runtime.HTTPClient, filepath.Join(newConfig.BuildDir, "aur.json"))
if errAURCache != nil { if errAURCache != nil {
return nil, errors.Wrap(errAURCache, gotext.Get("failed to retrieve aur Cache")) return nil, errors.Wrap(errAURCache, gotext.Get("failed to retrieve aur Cache"))
} }

View File

@ -29,6 +29,6 @@ type Runtime struct {
HTTPClient *http.Client HTTPClient *http.Client
AURClient *aur.Client AURClient *aur.Client
VoteClient *vote.Client VoteClient *vote.Client
AURCache *metadata.AURCache AURCache *metadata.AURCacheClient
DBExecutor db.Executor DBExecutor db.Executor
} }

View File

@ -37,7 +37,7 @@ func filterUpdateList(list []db.Upgrade, filter upgrade.Filter) []db.Upgrade {
} }
// upList returns lists of packages to upgrade from each source. // upList returns lists of packages to upgrade from each source.
func upList(ctx context.Context, aurCache *metadata.AURCache, func upList(ctx context.Context, aurCache *metadata.AURCacheClient,
warnings *query.AURWarnings, dbExecutor db.Executor, enableDowngrade bool, warnings *query.AURWarnings, dbExecutor db.Executor, enableDowngrade bool,
filter upgrade.Filter, filter upgrade.Filter,
) (aurUp, repoUp upgrade.UpSlice, err error) { ) (aurUp, repoUp upgrade.UpSlice, err error) {
@ -261,7 +261,7 @@ func sysupgradeTargets(ctx context.Context, dbExecutor db.Executor,
// Targets for sys upgrade. // Targets for sys upgrade.
func sysupgradeTargetsV2(ctx context.Context, func sysupgradeTargetsV2(ctx context.Context,
aurCache *metadata.AURCache, aurCache *metadata.AURCacheClient,
dbExecutor db.Executor, dbExecutor db.Executor,
graph *topo.Graph[string, *dep.InstallInfo], graph *topo.Graph[string, *dep.InstallInfo],
enableDowngrade bool, enableDowngrade bool,