chore(golangci): add new linters

This commit is contained in:
jguer
2021-08-11 20:13:28 +02:00
committed by J Guerreiro
parent 08d1305ec5
commit cb4b57f6d8
55 changed files with 670 additions and 270 deletions

View File

@@ -14,12 +14,6 @@ linters-settings:
- opinionated
- performance
- style
disabled-checks:
- dupImport # https://github.com/go-critic/go-critic/issues/845
- ifElseChain
- octalLiteral
- whyNoLint
- wrapperFunc
gocyclo:
min-complexity: 15
goimports:
@@ -72,28 +66,25 @@ linters:
- unused
- varcheck
- whitespace
- wsl
- godot
# disabled want to fix
#- scopelint
#- gomnd
#- goconst
#- gocyclo
#- funlen
#- dogsled
# disabled for now
#- godox
run:
issues:
# Excluding configuration per-path, per-linter, per-text and per-source
exclude-rules:
- path: _test\.go
linters:
- gomnd
- lll
- revive
- wsl
- govet
- godot
- errcheck
- stylecheck
- dupl
- gocritic
- gochecknoinits
exclude:
- G107
- G204
- commentedOutCode
run:
tests: false

View File

@@ -17,7 +17,7 @@ import (
"github.com/Jguer/yay/v10/pkg/text"
)
// CleanDependencies removes all dangling dependencies in system
// CleanDependencies removes all dangling dependencies in system.
func cleanDependencies(cmdArgs *parser.Arguments, dbExecutor db.Executor, removeOptional bool) error {
hanging := hangingPackages(removeOptional, dbExecutor)
if len(hanging) != 0 {
@@ -27,7 +27,7 @@ func cleanDependencies(cmdArgs *parser.Arguments, dbExecutor db.Executor, remove
return nil
}
// CleanRemove sends a full removal command to pacman with the pkgName slice
// CleanRemove sends a full removal command to pacman with the pkgName slice.
func cleanRemove(cmdArgs *parser.Arguments, pkgNames []string) error {
if len(pkgNames) == 0 {
return nil
@@ -107,6 +107,7 @@ func cleanAUR(keepInstalled, keepCurrent, removeAll bool, dbExecutor db.Executor
}
cachedPackages := make([]string, 0, len(files))
for _, file := range files {
if !file.IsDir() {
continue
@@ -179,10 +180,12 @@ func cleanUntracked() error {
if isGitRepository(dir) {
if err := config.Runtime.CmdBuilder.Show(config.Runtime.CmdBuilder.BuildGitCmd(dir, "clean", "-fx")); err != nil {
text.Warnln(gotext.Get("Unable to clean:"), dir)
return err
}
}
}
return nil
}
@@ -217,6 +220,7 @@ func cleanBuilds(bases []dep.Base) {
for i, base := range bases {
dir := filepath.Join(config.BuildDir, base.Pkgbase())
text.OperationInfoln(gotext.Get("Deleting (%d/%d): %s", i+1, len(bases), text.Cyan(dir)))
if err := os.RemoveAll(dir); err != nil {
fmt.Fprintln(os.Stderr, err)
}

64
cmd.go
View File

@@ -12,6 +12,7 @@ import (
"github.com/Jguer/yay/v10/pkg/completion"
"github.com/Jguer/yay/v10/pkg/db"
"github.com/Jguer/yay/v10/pkg/download"
"github.com/Jguer/yay/v10/pkg/intrange"
"github.com/Jguer/yay/v10/pkg/news"
"github.com/Jguer/yay/v10/pkg/query"
@@ -156,6 +157,7 @@ func handleCmd(cmdArgs *parser.Arguments, dbExecutor db.Executor) error {
switch cmdArgs.Op {
case "V", "version":
handleVersion()
return nil
case "D", "database":
return config.Runtime.CmdBuilder.Show(config.Runtime.CmdBuilder.BuildPacmanCmd(
@@ -191,6 +193,7 @@ func handleCmd(cmdArgs *parser.Arguments, dbExecutor db.Executor) error {
// updates or their count.
func getFilter(cmdArgs *parser.Arguments) (upgrade.Filter, error) {
deps, explicit := cmdArgs.ExistsArg("d", "deps"), cmdArgs.ExistsArg("e", "explicit")
switch {
case deps && explicit:
return nil, fmt.Errorf(gotext.Get("invalid option: '--deps' and '--explicit' may not be used together"))
@@ -203,6 +206,7 @@ func getFilter(cmdArgs *parser.Arguments) (upgrade.Filter, error) {
return pkg.Reason == alpm.PkgReasonExplicit
}, nil
}
return func(pkg upgrade.Upgrade) bool {
return true
}, nil
@@ -214,8 +218,10 @@ func handleQuery(cmdArgs *parser.Arguments, dbExecutor db.Executor) error {
if err != nil {
return err
}
return printUpdateList(cmdArgs, dbExecutor, cmdArgs.ExistsDouble("u", "sysupgrade"), filter)
}
return config.Runtime.CmdBuilder.Show(config.Runtime.CmdBuilder.BuildPacmanCmd(
cmdArgs, config.Runtime.Mode, settings.NoConfirm))
}
@@ -225,6 +231,7 @@ func handleHelp(cmdArgs *parser.Arguments) error {
usage()
return nil
}
return config.Runtime.CmdBuilder.Show(config.Runtime.CmdBuilder.BuildPacmanCmd(
cmdArgs, config.Runtime.Mode, settings.NoConfirm))
}
@@ -238,19 +245,23 @@ func handlePrint(cmdArgs *parser.Arguments, dbExecutor db.Executor) error {
case cmdArgs.ExistsArg("d", "defaultconfig"):
tmpConfig := settings.DefaultConfig()
fmt.Printf("%v", tmpConfig)
return nil
case cmdArgs.ExistsArg("g", "currentconfig"):
fmt.Printf("%v", config)
return nil
case cmdArgs.ExistsArg("n", "numberupgrades"):
filter, err := getFilter(cmdArgs)
if err != nil {
return err
}
return printNumberOfUpdates(dbExecutor, cmdArgs.ExistsDouble("u", "sysupgrade"), filter)
case cmdArgs.ExistsArg("w", "news"):
double := cmdArgs.ExistsDouble("w", "news")
quiet := cmdArgs.ExistsArg("q", "quiet")
return news.PrintNewsFeed(config.Runtime.HTTPClient, dbExecutor.LastBuildTime(), config.SortMode, double, quiet)
case cmdArgs.ExistsDouble("c", "complete"):
return completion.Show(config.Runtime.HTTPClient, dbExecutor,
@@ -261,29 +272,30 @@ func handlePrint(cmdArgs *parser.Arguments, dbExecutor db.Executor) error {
case cmdArgs.ExistsArg("s", "stats"):
return localStatistics(dbExecutor)
}
return nil
}
func handleYay(cmdArgs *parser.Arguments, dbExecutor db.Executor) error {
if cmdArgs.ExistsArg("gendb") {
switch {
case cmdArgs.ExistsArg("gendb"):
return createDevelDB(config, dbExecutor)
}
if cmdArgs.ExistsDouble("c") {
case cmdArgs.ExistsDouble("c"):
return cleanDependencies(cmdArgs, dbExecutor, true)
}
if cmdArgs.ExistsArg("c", "clean") {
case cmdArgs.ExistsArg("c", "clean"):
return cleanDependencies(cmdArgs, dbExecutor, false)
}
if len(cmdArgs.Targets) > 0 {
case len(cmdArgs.Targets) > 0:
return handleYogurt(cmdArgs, dbExecutor)
}
return nil
}
func handleGetpkgbuild(cmdArgs *parser.Arguments, dbExecutor db.Executor) error {
func handleGetpkgbuild(cmdArgs *parser.Arguments, dbExecutor download.DBSearcher) error {
if cmdArgs.ExistsArg("p", "print") {
return printPkgbuilds(dbExecutor, config.Runtime.HTTPClient, cmdArgs.Targets, config.Runtime.Mode, config.AURURL)
}
return getPkgbuilds(dbExecutor, config, cmdArgs.Targets, cmdArgs.ExistsArg("f", "force"))
}
@@ -295,41 +307,36 @@ func handleYogurt(cmdArgs *parser.Arguments, dbExecutor db.Executor) error {
func handleSync(cmdArgs *parser.Arguments, dbExecutor db.Executor) error {
targets := cmdArgs.Targets
if cmdArgs.ExistsArg("s", "search") {
switch {
case cmdArgs.ExistsArg("s", "search"):
if cmdArgs.ExistsArg("q", "quiet") {
config.SearchMode = minimal
} else {
config.SearchMode = detailed
}
return syncSearch(targets, config.Runtime.AURClient, dbExecutor)
}
if cmdArgs.ExistsArg("p", "print", "print-format") {
case cmdArgs.ExistsArg("p", "print", "print-format"):
return config.Runtime.CmdBuilder.Show(config.Runtime.CmdBuilder.BuildPacmanCmd(
cmdArgs, config.Runtime.Mode, settings.NoConfirm))
}
if cmdArgs.ExistsArg("c", "clean") {
case cmdArgs.ExistsArg("c", "clean"):
return syncClean(cmdArgs, dbExecutor)
}
if cmdArgs.ExistsArg("l", "list") {
case cmdArgs.ExistsArg("l", "list"):
return syncList(config.Runtime.HTTPClient, cmdArgs, dbExecutor)
}
if cmdArgs.ExistsArg("g", "groups") {
case cmdArgs.ExistsArg("g", "groups"):
return config.Runtime.CmdBuilder.Show(config.Runtime.CmdBuilder.BuildPacmanCmd(
cmdArgs, config.Runtime.Mode, settings.NoConfirm))
}
if cmdArgs.ExistsArg("i", "info") {
case cmdArgs.ExistsArg("i", "info"):
return syncInfo(cmdArgs, targets, dbExecutor)
}
if cmdArgs.ExistsArg("u", "sysupgrade") {
case cmdArgs.ExistsArg("u", "sysupgrade"):
return install(cmdArgs, dbExecutor, false)
}
if len(cmdArgs.Targets) > 0 {
case len(cmdArgs.Targets) > 0:
return install(cmdArgs, dbExecutor, false)
}
if cmdArgs.ExistsArg("y", "refresh") {
case cmdArgs.ExistsArg("y", "refresh"):
return config.Runtime.CmdBuilder.Show(config.Runtime.CmdBuilder.BuildPacmanCmd(
cmdArgs, config.Runtime.Mode, settings.NoConfirm))
}
return nil
}
@@ -358,9 +365,11 @@ func displayNumberMenu(pkgS []string, dbExecutor db.Executor, cmdArgs *parser.Ar
aq, aurErr = narrowSearch(config.Runtime.AURClient, pkgS, true)
lenaq = len(aq)
}
if config.Runtime.Mode.AtLeastRepo() {
pq = queryRepo(pkgS, dbExecutor)
lenpq = len(pq)
if repoErr != nil {
return repoErr
}
@@ -375,6 +384,7 @@ func displayNumberMenu(pkgS []string, dbExecutor db.Executor, cmdArgs *parser.Ar
if config.Runtime.Mode.AtLeastRepo() {
pq.printSearch(dbExecutor)
}
if config.Runtime.Mode.AtLeastAUR() {
aq.printSearch(lenpq+1, dbExecutor)
}
@@ -382,6 +392,7 @@ func displayNumberMenu(pkgS []string, dbExecutor db.Executor, cmdArgs *parser.Ar
if config.Runtime.Mode.AtLeastAUR() {
aq.printSearch(lenpq+1, dbExecutor)
}
if config.Runtime.Mode.AtLeastRepo() {
pq.printSearch(dbExecutor)
}
@@ -403,6 +414,7 @@ func displayNumberMenu(pkgS []string, dbExecutor db.Executor, cmdArgs *parser.Ar
if err != nil {
return err
}
if overflow {
return fmt.Errorf(gotext.Get("input too long"))
}
@@ -414,6 +426,7 @@ func displayNumberMenu(pkgS []string, dbExecutor db.Executor, cmdArgs *parser.Ar
for i, pkg := range pq {
var target int
switch config.SortMode {
case settings.TopDown:
target = i + 1
@@ -478,6 +491,7 @@ func syncList(httpClient *http.Client, cmdArgs *parser.Arguments, dbExecutor db.
scanner := bufio.NewScanner(resp.Body)
scanner.Scan()
for scanner.Scan() {
name := scanner.Text()
if cmdArgs.ExistsArg("q", "quiet") {

View File

@@ -13,7 +13,7 @@ import (
"github.com/Jguer/yay/v10/pkg/text"
)
// Verbosity settings for search
// Verbosity settings for search.
const (
numberMenu = iota
detailed
@@ -37,6 +37,7 @@ func editor() (editor string, args []string) {
} else {
return editor, strings.Fields(config.EditorFlags)
}
fallthrough
case os.Getenv("EDITOR") != "":
if editorArgs := strings.Fields(os.Getenv("EDITOR")); len(editorArgs) != 0 {
@@ -47,6 +48,7 @@ func editor() (editor string, args []string) {
return editor, editorArgs[1:]
}
}
fallthrough
case os.Getenv("VISUAL") != "":
if editorArgs := strings.Fields(os.Getenv("VISUAL")); len(editorArgs) != 0 {
@@ -57,6 +59,7 @@ func editor() (editor string, args []string) {
return editor, editorArgs[1:]
}
}
fallthrough
default:
fmt.Fprintln(os.Stderr)
@@ -65,6 +68,7 @@ func editor() (editor string, args []string) {
for {
text.Infoln(gotext.Get("Edit PKGBUILD with?"))
editorInput, err := getInput("")
if err != nil {
fmt.Fprintln(os.Stderr, err)
@@ -81,6 +85,7 @@ func editor() (editor string, args []string) {
fmt.Fprintln(os.Stderr, err)
continue
}
return editor, editorArgs[1:]
}
}
@@ -88,6 +93,7 @@ func editor() (editor string, args []string) {
func getInput(defaultValue string) (string, error) {
text.Info()
if defaultValue != "" || settings.NoConfirm {
fmt.Println(defaultValue)
return defaultValue, nil

17
diff.go
View File

@@ -16,12 +16,15 @@ const gitDiffRefName = "AUR_SEEN"
func showPkgbuildDiffs(bases []dep.Base, cloned map[string]bool) error {
var errMulti multierror.MultiError
for _, base := range bases {
pkg := base.Pkgbase()
dir := filepath.Join(config.BuildDir, pkg)
start, err := getLastSeenHash(config.BuildDir, pkg)
if err != nil {
errMulti.Add(err)
continue
}
@@ -31,11 +34,13 @@ func showPkgbuildDiffs(bases []dep.Base, cloned map[string]bool) error {
hasDiff, err := gitHasDiff(config.BuildDir, pkg)
if err != nil {
errMulti.Add(err)
continue
}
if !hasDiff {
text.Warnln(gotext.Get("%s: No changes -- skipping", text.Cyan(base.String())))
continue
}
}
@@ -50,6 +55,7 @@ func showPkgbuildDiffs(bases []dep.Base, cloned map[string]bool) error {
} else {
args = append(args, "--color=never")
}
_ = config.Runtime.CmdBuilder.Show(config.Runtime.CmdBuilder.BuildGitCmd(dir, args...))
}
@@ -57,7 +63,7 @@ func showPkgbuildDiffs(bases []dep.Base, cloned map[string]bool) error {
}
// Check whether or not a diff exists between the last reviewed diff and
// HEAD@{upstream}
// HEAD@{upstream}.
func gitHasDiff(path, name string) (bool, error) {
if gitHasLastSeenRef(path, name) {
stdout, stderr, err := config.Runtime.CmdBuilder.Capture(
@@ -69,6 +75,7 @@ func gitHasDiff(path, name string) (bool, error) {
lines := strings.Split(stdout, "\n")
lastseen := lines[0]
upstream := lines[1]
return lastseen != upstream, nil
}
// If YAY_DIFF_REVIEW does not exists, we have never reviewed a diff for this package
@@ -77,11 +84,12 @@ func gitHasDiff(path, name string) (bool, error) {
}
// Return wether or not we have reviewed a diff yet. It checks for the existence of
// YAY_DIFF_REVIEW in the git ref-list
// YAY_DIFF_REVIEW in the git ref-list.
func gitHasLastSeenRef(path, name string) bool {
_, _, err := config.Runtime.CmdBuilder.Capture(
config.Runtime.CmdBuilder.BuildGitCmd(
filepath.Join(path, name), "rev-parse", "--quiet", "--verify", gitDiffRefName), 0)
return err == nil
}
@@ -97,13 +105,15 @@ func getLastSeenHash(path, name string) (string, error) {
}
lines := strings.Split(stdout, "\n")
return lines[0], nil
}
return gitEmptyTree, nil
}
// Update the YAY_DIFF_REVIEW ref to HEAD. We use this ref to determine which diff were
// reviewed by the user
// reviewed by the user.
func gitUpdateSeenRef(path, name string) error {
_, stderr, err := config.Runtime.CmdBuilder.Capture(
config.Runtime.CmdBuilder.BuildGitCmd(
@@ -111,6 +121,7 @@ func gitUpdateSeenRef(path, name string) error {
if err != nil {
return fmt.Errorf("%s %s", stderr, err)
}
return nil
}

14
get.go
View File

@@ -8,15 +8,14 @@ import (
"github.com/leonelquinteros/gotext"
"github.com/Jguer/yay/v10/pkg/db"
"github.com/Jguer/yay/v10/pkg/download"
"github.com/Jguer/yay/v10/pkg/settings"
"github.com/Jguer/yay/v10/pkg/settings/parser"
"github.com/Jguer/yay/v10/pkg/text"
)
// yay -Gp
func printPkgbuilds(dbExecutor db.Executor, httpClient *http.Client, targets []string,
// yay -Gp.
func printPkgbuilds(dbExecutor download.DBSearcher, httpClient *http.Client, targets []string,
mode parser.TargetMode, aurURL string) error {
pkgbuilds, err := download.PKGBUILDs(dbExecutor, httpClient, targets, aurURL, mode)
if err != nil {
@@ -32,11 +31,13 @@ func printPkgbuilds(dbExecutor db.Executor, httpClient *http.Client, targets []s
if len(pkgbuilds) != len(targets) {
missing := []string{}
for _, target := range targets {
if _, ok := pkgbuilds[target]; !ok {
missing = append(missing, target)
}
}
text.Warnln(gotext.Get("Unable to find the following packages:"), strings.Join(missing, ", "))
return fmt.Errorf("")
@@ -45,13 +46,14 @@ func printPkgbuilds(dbExecutor db.Executor, httpClient *http.Client, targets []s
return nil
}
// yay -G
func getPkgbuilds(dbExecutor db.Executor, config *settings.Configuration, targets []string,
// yay -G.
func getPkgbuilds(dbExecutor download.DBSearcher, config *settings.Configuration, targets []string,
force bool) error {
wd, err := os.Getwd()
if err != nil {
return err
}
cloned, errD := download.PKGBUILDRepos(dbExecutor,
config.Runtime.CmdBuilder, targets, config.Runtime.Mode, config.AURURL, wd, force)
if errD != nil {
@@ -60,11 +62,13 @@ func getPkgbuilds(dbExecutor db.Executor, config *settings.Configuration, target
if len(targets) != len(cloned) {
missing := []string{}
for _, target := range targets {
if _, ok := cloned[target]; !ok {
missing = append(missing, target)
}
}
text.Warnln(gotext.Get("Unable to find the following packages:"), strings.Join(missing, ", "))
err = fmt.Errorf("")

View File

@@ -38,6 +38,7 @@ func asdeps(cmdArgs *parser.Arguments, pkgs []string) (err error) {
cmdArgs = cmdArgs.CopyGlobal()
_ = cmdArgs.AddArg("q", "D", "asdeps")
cmdArgs.AddTarget(pkgs...)
err = config.Runtime.CmdBuilder.Show(config.Runtime.CmdBuilder.BuildPacmanCmd(
cmdArgs, config.Runtime.Mode, settings.NoConfirm))
if err != nil {
@@ -55,6 +56,7 @@ func asexp(cmdArgs *parser.Arguments, pkgs []string) (err error) {
cmdArgs = cmdArgs.CopyGlobal()
_ = cmdArgs.AddArg("q", "D", "asexplicit")
cmdArgs.AddTarget(pkgs...)
err = config.Runtime.CmdBuilder.Show(config.Runtime.CmdBuilder.BuildPacmanCmd(
cmdArgs, config.Runtime.Mode, settings.NoConfirm))
if err != nil {
@@ -64,7 +66,7 @@ func asexp(cmdArgs *parser.Arguments, pkgs []string) (err error) {
return nil
}
// Install handles package installs
// Install handles package installs.
func install(cmdArgs *parser.Arguments, dbExecutor db.Executor, ignoreProviders bool) (err error) {
var (
incompatible stringset.StringSet
@@ -162,14 +164,17 @@ func install(cmdArgs *parser.Arguments, dbExecutor db.Executor, ignoreProviders
if sysupgradeArg {
fmt.Println(gotext.Get(" there is nothing to do"))
}
return nil
}
cmdArgs.Op = "S"
cmdArgs.DelArg("y", "refresh")
if arguments.ExistsArg("ignore") {
cmdArgs.CreateOrAppendOption("ignore", arguments.GetArgs("ignore")...)
}
return config.Runtime.CmdBuilder.Show(config.Runtime.CmdBuilder.BuildPacmanCmd(
cmdArgs, config.Runtime.Mode, settings.NoConfirm))
}
@@ -184,9 +189,6 @@ func install(cmdArgs *parser.Arguments, dbExecutor db.Executor, ignoreProviders
}
do = dep.GetOrder(dp, noDeps, noCheck)
if err != nil {
return err
}
for _, pkg := range do.Repo {
arguments.AddTarget(pkg.DB().Name() + "/" + pkg.Name())
@@ -230,6 +232,7 @@ func install(cmdArgs *parser.Arguments, dbExecutor db.Executor, ignoreProviders
if config.CleanMenu {
if anyExistInCache(do.Aur) {
askClean := pkgbuildNumberMenu(do.Aur, remoteNamesCache)
toClean, errClean := cleanNumberMenu(do.Aur, remoteNamesCache, askClean)
if errClean != nil {
return errClean
@@ -241,6 +244,7 @@ func install(cmdArgs *parser.Arguments, dbExecutor db.Executor, ignoreProviders
toSkip := pkgbuildsToSkip(do.Aur, targets)
toClone := make([]string, 0, len(do.Aur))
for _, base := range do.Aur {
if !toSkip.Get(base.Pkgbase()) {
toClone = append(toClone, base.Pkgbase())
@@ -260,11 +264,14 @@ func install(cmdArgs *parser.Arguments, dbExecutor db.Executor, ignoreProviders
return err
}
var toDiff []dep.Base
var toEdit []dep.Base
var (
toDiff []dep.Base
toEdit []dep.Base
)
if config.DiffMenu {
pkgbuildNumberMenu(do.Aur, remoteNamesCache)
toDiff, err = diffNumberMenu(do.Aur, remoteNamesCache)
if err != nil {
return err
@@ -281,10 +288,13 @@ func install(cmdArgs *parser.Arguments, dbExecutor db.Executor, ignoreProviders
if len(toDiff) > 0 {
oldValue := settings.NoConfirm
settings.NoConfirm = false
fmt.Println()
if !text.ContinueTask(gotext.Get("Proceed with install?"), true, settings.NoConfirm) {
return fmt.Errorf(gotext.Get("aborting due to user"))
}
err = updatePkgbuildSeenRef(toDiff)
if err != nil {
text.Errorln(err.Error())
@@ -305,6 +315,7 @@ func install(cmdArgs *parser.Arguments, dbExecutor db.Executor, ignoreProviders
if config.EditMenu {
pkgbuildNumberMenu(do.Aur, remoteNamesCache)
toEdit, err = editNumberMenu(do.Aur, remoteNamesCache)
if err != nil {
return err
@@ -321,10 +332,13 @@ func install(cmdArgs *parser.Arguments, dbExecutor db.Executor, ignoreProviders
if len(toEdit) > 0 {
oldValue := settings.NoConfirm
settings.NoConfirm = false
fmt.Println()
if !text.ContinueTask(gotext.Get("Proceed with install?"), true, settings.NoConfirm) {
return errors.New(gotext.Get("aborting due to user"))
}
settings.NoConfirm = oldValue
}
@@ -356,6 +370,7 @@ func install(cmdArgs *parser.Arguments, dbExecutor db.Executor, ignoreProviders
for _, pkg := range do.Repo {
if !dp.Explicit.Get(pkg.Name()) && !localNamesCache.Get(pkg.Name()) && !remoteNamesCache.Get(pkg.Name()) {
deps = append(deps, pkg.Name())
continue
}
@@ -369,6 +384,7 @@ func install(cmdArgs *parser.Arguments, dbExecutor db.Executor, ignoreProviders
if errDeps := asdeps(cmdArgs, deps); errDeps != nil {
return errDeps
}
if errExp := asexp(cmdArgs, exp); errExp != nil {
return errExp
}
@@ -394,6 +410,7 @@ func install(cmdArgs *parser.Arguments, dbExecutor db.Executor, ignoreProviders
func removeMake(do *dep.Order) error {
removeArguments := parser.MakeArguments()
err := removeArguments.AddArg("R", "u")
if err != nil {
return err
@@ -467,6 +484,7 @@ func earlyRefresh(cmdArgs *parser.Arguments) error {
arguments.DelArg("i", "info")
arguments.DelArg("l", "list")
arguments.ClearTargets()
return config.Runtime.CmdBuilder.Show(config.Runtime.CmdBuilder.BuildPacmanCmd(
arguments, config.Runtime.Mode, settings.NoConfirm))
}
@@ -488,6 +506,7 @@ func alpmArchIsSupported(alpmArch []string, arch string) bool {
func getIncompatible(bases []dep.Base, srcinfos map[string]*gosrc.Srcinfo, dbExecutor db.Executor) (stringset.StringSet, error) {
incompatible := make(stringset.StringSet)
basesMap := make(map[string]dep.Base)
alpmArch, err := dbExecutor.AlpmArchitectures()
if err != nil {
return nil, err
@@ -507,6 +526,7 @@ nextpkg:
if len(incompatible) > 0 {
text.Warnln(gotext.Get("The following packages are not compatible with your architecture:"))
for pkg := range incompatible {
fmt.Print(" " + text.Cyan(basesMap[pkg].String()))
}
@@ -609,6 +629,7 @@ func cleanNumberMenu(bases []dep.Base, installed stringset.StringSet, hasClean b
text.Infoln(gotext.Get("Packages to cleanBuild?"))
text.Infoln(gotext.Get("%s [A]ll [Ab]ort [I]nstalled [No]tInstalled or (1 2 3, 1-3, ^4)", text.Cyan(gotext.Get("[N]one"))))
cleanInput, err := getInput(config.AnswerClean)
if err != nil {
return nil, err
@@ -625,6 +646,7 @@ func cleanNumberMenu(bases []dep.Base, installed stringset.StringSet, hasClean b
for i, base := range bases {
pkg := base.Pkgbase()
anyInstalled := false
for _, b := range base {
anyInstalled = anyInstalled || installed.Get(b.Name)
}
@@ -677,13 +699,16 @@ func diffNumberMenu(bases []dep.Base, installed stringset.StringSet) ([]dep.Base
}
func editDiffNumberMenu(bases []dep.Base, installed stringset.StringSet, diff bool) ([]dep.Base, error) {
toEdit := make([]dep.Base, 0)
var editInput string
var err error
var (
toEdit = make([]dep.Base, 0)
editInput string
err error
)
if diff {
text.Infoln(gotext.Get("Diffs to show?"))
text.Infoln(gotext.Get("%s [A]ll [Ab]ort [I]nstalled [No]tInstalled or (1 2 3, 1-3, ^4)", text.Cyan(gotext.Get("[N]one"))))
editInput, err = getInput(config.AnswerDiff)
if err != nil {
return nil, err
@@ -708,6 +733,7 @@ func editDiffNumberMenu(bases []dep.Base, installed stringset.StringSet, diff bo
for i, base := range bases {
pkg := base.Pkgbase()
anyInstalled := false
for _, b := range base {
anyInstalled = anyInstalled || installed.Get(b.Name)
}
@@ -746,18 +772,21 @@ func editDiffNumberMenu(bases []dep.Base, installed stringset.StringSet, diff bo
func updatePkgbuildSeenRef(bases []dep.Base) error {
var errMulti multierror.MultiError
for _, base := range bases {
pkg := base.Pkgbase()
err := gitUpdateSeenRef(config.BuildDir, pkg)
if err != nil {
if err := gitUpdateSeenRef(config.BuildDir, pkg); err != nil {
errMulti.Add(err)
}
}
return errMulti.Return()
}
func editPkgbuilds(bases []dep.Base, srcinfos map[string]*gosrc.Srcinfo) error {
pkgbuilds := make([]string, 0, len(bases))
for _, base := range bases {
pkg := base.Pkgbase()
dir := filepath.Join(config.BuildDir, pkg)
@@ -775,8 +804,8 @@ func editPkgbuilds(bases []dep.Base, srcinfos map[string]*gosrc.Srcinfo) error {
editorArgs = append(editorArgs, pkgbuilds...)
editcmd := exec.Command(editor, editorArgs...)
editcmd.Stdin, editcmd.Stdout, editcmd.Stderr = os.Stdin, os.Stdout, os.Stderr
err := editcmd.Run()
if err != nil {
if err := editcmd.Run(); err != nil {
return errors.New(gotext.Get("editor did not exit successfully, aborting: %s", err))
}
}
@@ -786,6 +815,7 @@ func editPkgbuilds(bases []dep.Base, srcinfos map[string]*gosrc.Srcinfo) error {
func parseSrcinfoFiles(bases []dep.Base, errIsFatal bool) (map[string]*gosrc.Srcinfo, error) {
srcinfos := make(map[string]*gosrc.Srcinfo)
for k, base := range bases {
pkg := base.Pkgbase()
dir := filepath.Join(config.BuildDir, pkg)
@@ -798,6 +828,7 @@ func parseSrcinfoFiles(bases []dep.Base, errIsFatal bool) (map[string]*gosrc.Src
text.Warnln(gotext.Get("failed to parse %s -- skipping: %s", base.String(), err))
continue
}
return nil, errors.New(gotext.Get("failed to parse %s: %s", base.String(), err))
}
@@ -914,6 +945,7 @@ func buildInstallPkgbuilds(
if !dp.AlpmExecutor.LocalSatisfierExists(dep) {
satisfied = false
text.Warnln(gotext.Get("%s not satisfied, flushing install queue", dep))
break all
}
}
@@ -923,8 +955,10 @@ func buildInstallPkgbuilds(
if !satisfied || !config.BatchInstall {
err = doInstall(arguments, cmdArgs, deps, exp)
arguments.ClearTargets()
deps = make([]string, 0)
exp = make([]string, 0)
if err != nil {
return err
}
@@ -953,6 +987,7 @@ func buildInstallPkgbuilds(
for _, b := range base {
isExplicit = isExplicit || dp.Explicit.Get(b.Name)
}
if config.ReBuild == "no" || (config.ReBuild == "yes" && !isExplicit) {
for _, split := range base {
pkgdest, ok := pkgdests[split.Name]
@@ -985,6 +1020,7 @@ func buildInstallPkgbuilds(
}
fmt.Fprintln(os.Stdout, gotext.Get("%s is up to date -- skipping", text.Cyan(pkg+"-"+pkgVersion)))
continue
}
}
@@ -1021,12 +1057,14 @@ func buildInstallPkgbuilds(
for _, split := range base {
if _, ok := conflicts[split.Name]; ok {
settings.NoConfirm = false
break
}
}
}
var errAdd error
for _, split := range base {
for _, suffix := range []string{"", "-debug"} {
deps, exp, errAdd = doAddTarget(dp, localNamesCache, remoteNamesCache,
@@ -1037,10 +1075,14 @@ func buildInstallPkgbuilds(
}
}
var mux sync.Mutex
var wg sync.WaitGroup
var (
mux sync.Mutex
wg sync.WaitGroup
)
for _, pkg := range base {
wg.Add(1)
go config.Runtime.VCSStore.Update(pkg.Name, srcinfo.Source, &mux, &wg)
}
@@ -1049,6 +1091,7 @@ func buildInstallPkgbuilds(
err = doInstall(arguments, cmdArgs, deps, exp)
settings.NoConfirm = oldConfirm
return err
}
@@ -1097,11 +1140,13 @@ func doAddTarget(dp *dep.Pool, localNamesCache, remoteNamesCache stringset.Strin
}
arguments.AddTarget(pkgdest)
if cmdArgs.ExistsArg("asdeps", "asdep") {
switch {
case cmdArgs.ExistsArg("asdeps", "asdep"):
deps = append(deps, name)
} else if cmdArgs.ExistsArg("asexplicit", "asexp") {
case cmdArgs.ExistsArg("asexplicit", "asexp"):
exp = append(exp, name)
} else if !dp.Explicit.Get(name) && !localNamesCache.Get(name) && !remoteNamesCache.Get(name) {
case !dp.Explicit.Get(name) && !localNamesCache.Get(name) && !remoteNamesCache.Get(name):
deps = append(deps, name)
}

21
main.go
View File

@@ -41,6 +41,7 @@ func initAlpm(cmdArgs *parser.Arguments, pacmanConfigPath string) (*pacmanconf.C
if stderr != "" {
cmdErr = fmt.Errorf("%s\n%s", err, stderr)
}
return nil, false, cmdErr
}
@@ -69,6 +70,7 @@ func initAlpm(cmdArgs *parser.Arguments, pacmanConfigPath string) (*pacmanconf.C
}
useColor := pacmanConf.Color && term.IsTerminal(int(os.Stdout.Fd()))
switch value, _, _ := cmdArgs.GetArg("color"); value {
case "always":
useColor = true
@@ -83,9 +85,13 @@ func initAlpm(cmdArgs *parser.Arguments, pacmanConfigPath string) (*pacmanconf.C
func main() {
var err error
ret := 0
defer func() { os.Exit(ret) }()
initGotext()
if os.Geteuid() == 0 {
text.Warnln(gotext.Get("Avoid running yay as root/sudo."))
}
@@ -95,17 +101,21 @@ func main() {
if str := err.Error(); str != "" {
fmt.Fprintln(os.Stderr, str)
}
ret = 1
return
}
cmdArgs := parser.MakeArguments()
err = config.ParseCommandLine(cmdArgs)
if err != nil {
if err = config.ParseCommandLine(cmdArgs); err != nil {
if str := err.Error(); str != "" {
fmt.Fprintln(os.Stderr, str)
}
ret = 1
return
}
@@ -116,14 +126,18 @@ func main() {
}
var useColor bool
config.Runtime.PacmanConf, useColor, err = initAlpm(cmdArgs, config.PacmanConf)
if err != nil {
if str := err.Error(); str != "" {
fmt.Fprintln(os.Stderr, str)
}
ret = 1
return
}
config.Runtime.CmdBuilder.SetPacmanDBPath(config.Runtime.PacmanConf.DBPath)
text.UseColor = useColor
@@ -133,7 +147,9 @@ func main() {
if str := err.Error(); str != "" {
fmt.Fprintln(os.Stderr, str)
}
ret = 1
return
}
@@ -153,6 +169,7 @@ func main() {
// fallback
ret = 1
return
}
}

View File

@@ -10,6 +10,8 @@ import (
)
func TestPacmanConf(t *testing.T) {
t.Parallel()
expectedPacmanConf := &pacmanconf.Config{
RootDir: "/",
DBPath: "//var/lib/pacman/",

View File

@@ -20,7 +20,7 @@ type PkgSynchronizer interface {
SyncPackages(...string) []db.IPackage
}
// Show provides completion info for shells
// Show provides completion info for shells.
func Show(httpClient *http.Client, dbExecutor PkgSynchronizer, aurURL, completionPath string, interval int, force bool) error {
err := Update(httpClient, dbExecutor, aurURL, completionPath, interval, force)
if err != nil {
@@ -34,10 +34,11 @@ func Show(httpClient *http.Client, dbExecutor PkgSynchronizer, aurURL, completio
defer in.Close()
_, err = io.Copy(os.Stdout, in)
return err
}
// Update updates completion cache to be used by Complete
// Update updates completion cache to be used by Complete.
func Update(httpClient *http.Client, dbExecutor PkgSynchronizer, aurURL, completionPath string, interval int, force bool) error {
info, err := os.Stat(completionPath)
@@ -46,6 +47,7 @@ func Update(httpClient *http.Client, dbExecutor PkgSynchronizer, aurURL, complet
if errd != nil {
return errd
}
out, errf := os.Create(completionPath)
if errf != nil {
return errf
@@ -58,18 +60,20 @@ func Update(httpClient *http.Client, dbExecutor PkgSynchronizer, aurURL, complet
erra := createRepoList(dbExecutor, out)
out.Close()
return erra
}
return nil
}
// CreateAURList creates a new completion file
// CreateAURList creates a new completion file.
func createAURList(client *http.Client, aurURL string, out io.Writer) error {
u, err := url.Parse(aurURL)
if err != nil {
return err
}
u.Path = path.Join(u.Path, "packages.gz")
req, err := http.NewRequestWithContext(context.Background(), "GET", u.String(), nil)
@@ -82,6 +86,7 @@ func createAURList(client *http.Client, aurURL string, out io.Writer) error {
return err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return fmt.Errorf("invalid status code: %d", resp.StatusCode)
}
@@ -89,13 +94,14 @@ func createAURList(client *http.Client, aurURL string, out io.Writer) error {
scanner := bufio.NewScanner(resp.Body)
scanner.Scan()
for scanner.Scan() {
text := scanner.Text()
if strings.HasPrefix(text, "#") {
continue
}
_, err = io.WriteString(out, text+"\tAUR\n")
if err != nil {
if _, err := io.WriteString(out, text+"\tAUR\n"); err != nil {
return err
}
}
@@ -103,7 +109,7 @@ func createAURList(client *http.Client, aurURL string, out io.Writer) error {
return nil
}
// CreatePackageList appends Repo packages to completion cache
// CreatePackageList appends Repo packages to completion cache.
func createRepoList(dbExecutor PkgSynchronizer, out io.Writer) error {
for _, pkg := range dbExecutor.SyncPackages() {
_, err := io.WriteString(out, pkg.Name()+"\t"+pkg.DB().Name()+"\n")
@@ -111,5 +117,6 @@ func createRepoList(dbExecutor PkgSynchronizer, out io.Writer) error {
return err
}
}
return nil
}

View File

@@ -39,6 +39,7 @@ func Test_createAURList(t *testing.T) {
Get("/packages.gz").
Reply(200).
BodyString(samplePackageResp)
out := &bytes.Buffer{}
err := createAURList(&http.Client{}, "https://aur.archlinux.org", out)
assert.NoError(t, err)
@@ -52,6 +53,7 @@ func Test_createAURListHTTPError(t *testing.T) {
gock.New("https://aur.archlinux.org").
Get("/packages.gz").
ReplyError(errors.New("Not available"))
out := &bytes.Buffer{}
err := createAURList(&http.Client{}, "https://aur.archlinux.org", out)
assert.EqualError(t, err, "Get \"https://aur.archlinux.org/packages.gz\": Not available")

View File

@@ -53,6 +53,7 @@ func toUsage(usages []string) alpm.Usage {
}
var ret alpm.Usage
for _, usage := range usages {
switch usage {
case "Sync":
@@ -72,11 +73,6 @@ func toUsage(usages []string) alpm.Usage {
}
func configureAlpm(pacmanConf *pacmanconf.Config, alpmHandle *alpm.Handle) error {
// TODO: set SigLevel
// sigLevel := alpm.SigPackage | alpm.SigPackageOptional | alpm.SigDatabase | alpm.SigDatabaseOptional
// localFileSigLevel := alpm.SigUseDefault
// remoteFileSigLevel := alpm.SigUseDefault
for _, repo := range pacmanConf.Repos {
// TODO: set SigLevel
alpmDB, err := alpmHandle.RegisterSyncDB(repo.Name, 0)
@@ -127,18 +123,6 @@ func configureAlpm(pacmanConf *pacmanconf.Config, alpmHandle *alpm.Handle) error
return err
}
/*if err := alpmHandle.SetDefaultSigLevel(sigLevel); err != nil {
return err
}
if err := alpmHandle.SetLocalFileSigLevel(localFileSigLevel); err != nil {
return err
}
if err := alpmHandle.SetRemoteFileSigLevel(remoteFileSigLevel); err != nil {
return err
}*/
if err := alpmHandle.SetUseSyslog(pacmanConf.UseSyslog); err != nil {
return err
}
@@ -180,6 +164,7 @@ func (ae *AlpmExecutor) questionCallback() func(question alpm.QuestionAny) {
str := text.Bold(gotext.Get("There are %d providers available for %s:\n", size, qp.Dep()))
size = 1
var dbName string
_ = qp.Providers(ae.handle).ForEach(func(pkg alpm.IPackage) error {
@@ -202,18 +187,22 @@ func (ae *AlpmExecutor) questionCallback() func(question alpm.QuestionAny) {
// TODO: reenable noconfirm
if settings.NoConfirm {
fmt.Println()
break
}
reader := bufio.NewReader(os.Stdin)
numberBuf, overflow, err := reader.ReadLine()
if err != nil {
text.Errorln(err)
break
}
if overflow {
text.Errorln(gotext.Get(" Input too long"))
continue
}
@@ -233,6 +222,7 @@ func (ae *AlpmExecutor) questionCallback() func(question alpm.QuestionAny) {
}
qp.SetUseIndex(num - 1)
break
}
}
@@ -258,12 +248,14 @@ func (ae *AlpmExecutor) RefreshHandle() error {
alpmSetLogCallback(alpmHandle, logCallback)
ae.handle = alpmHandle
ae.syncDBsCache = nil
ae.syncDB, err = alpmHandle.SyncDBs()
if err != nil {
return err
}
ae.localDB, err = alpmHandle.LocalDB()
return err
}
@@ -271,6 +263,7 @@ func (ae *AlpmExecutor) LocalSatisfierExists(pkgName string) bool {
if _, err := ae.localDB.PkgCache().FindSatisfier(pkgName); err != nil {
return false
}
return true
}
@@ -278,6 +271,7 @@ func (ae *AlpmExecutor) SyncSatisfierExists(pkgName string) bool {
if _, err := ae.syncDB.FindSatisfier(pkgName); err != nil {
return false
}
return true
}
@@ -295,6 +289,7 @@ func (ae *AlpmExecutor) SyncSatisfier(pkgName string) alpm.IPackage {
if err != nil {
return nil
}
return foundPkg
}
@@ -302,8 +297,10 @@ func (ae *AlpmExecutor) PackagesFromGroup(groupName string) []alpm.IPackage {
groupPackages := []alpm.IPackage{}
_ = ae.syncDB.FindGroupPkgs(groupName).ForEach(func(pkg alpm.IPackage) error {
groupPackages = append(groupPackages, pkg)
return nil
})
return groupPackages
}
@@ -313,10 +310,11 @@ func (ae *AlpmExecutor) LocalPackages() []alpm.IPackage {
localPackages = append(localPackages, pkg)
return nil
})
return localPackages
}
// SyncPackages searches SyncDB for packages or returns all packages if no search param is given
// SyncPackages searches SyncDB for packages or returns all packages if no search param is given.
func (ae *AlpmExecutor) SyncPackages(pkgNames ...string) []alpm.IPackage {
repoPackages := []alpm.IPackage{}
_ = ae.syncDB.ForEach(func(alpmDB alpm.IDB) error {
@@ -333,6 +331,7 @@ func (ae *AlpmExecutor) SyncPackages(pkgNames ...string) []alpm.IPackage {
}
return nil
})
return repoPackages
}
@@ -341,6 +340,7 @@ func (ae *AlpmExecutor) LocalPackage(pkgName string) alpm.IPackage {
if pkg == nil {
return nil
}
return pkg
}
@@ -348,6 +348,7 @@ func (ae *AlpmExecutor) syncDBs() []alpm.IDB {
if ae.syncDBsCache == nil {
ae.syncDBsCache = ae.syncDB.Slice()
}
return ae.syncDBsCache
}
@@ -357,6 +358,7 @@ func (ae *AlpmExecutor) SyncPackage(pkgName string) alpm.IPackage {
return dbPkg
}
}
return nil
}
@@ -365,10 +367,12 @@ func (ae *AlpmExecutor) SatisfierFromDB(pkgName, dbName string) alpm.IPackage {
if err != nil {
return nil
}
foundPkg, err := singleDB.PkgCache().FindSatisfier(pkgName)
if err != nil {
return nil
}
return foundPkg
}
@@ -400,26 +404,27 @@ func (ae *AlpmExecutor) PackageGroups(pkg alpm.IPackage) []string {
// upRepo gathers local packages and checks if they have new versions.
// Output: Upgrade type package list.
func (ae *AlpmExecutor) RepoUpgrades(enableDowngrade bool) ([]db.Upgrade, error) {
var errReturn error
slice := []db.Upgrade{}
localDB, err := ae.handle.LocalDB()
if err != nil {
return slice, err
localDB, errDB := ae.handle.LocalDB()
if errDB != nil {
return slice, errDB
}
err = ae.handle.TransInit(alpm.TransFlagNoLock)
if err != nil {
if err := ae.handle.TransInit(alpm.TransFlagNoLock); err != nil {
return slice, err
}
defer func() {
err = ae.handle.TransRelease()
errReturn = ae.handle.TransRelease()
}()
err = ae.handle.SyncSysupgrade(enableDowngrade)
if err != nil {
if err := ae.handle.SyncSysupgrade(enableDowngrade); err != nil {
return slice, err
}
_ = ae.handle.TransGetAdd().ForEach(func(pkg alpm.IPackage) error {
localVer := "-"
reason := alpm.PkgReasonExplicit
@@ -439,7 +444,7 @@ func (ae *AlpmExecutor) RepoUpgrades(enableDowngrade bool) ([]db.Upgrade, error)
return nil
})
return slice, nil
return slice, errReturn
}
func (ae *AlpmExecutor) BiggestPackages() []alpm.IPackage {
@@ -448,11 +453,13 @@ func (ae *AlpmExecutor) BiggestPackages() []alpm.IPackage {
localPackages = append(localPackages, pkg)
return nil
})
return localPackages
}
func (ae *AlpmExecutor) LastBuildTime() time.Time {
var lastTime time.Time
_ = ae.syncDB.ForEach(func(db alpm.IDB) error {
_ = db.PkgCache().ForEach(func(pkg alpm.IPackage) error {
thisTime := pkg.BuildDate()
@@ -480,6 +487,7 @@ func (ae *AlpmExecutor) Repos() (repos []string) {
repos = append(repos, db.Name())
return nil
})
return
}

View File

@@ -9,6 +9,7 @@ import (
)
func TestAlpmExecutor(t *testing.T) {
t.Parallel()
pacmanConf := &pacmanconf.Config{
RootDir: "/",
DBPath: "/var/lib/pacman/",

View File

@@ -111,7 +111,7 @@ func (p *Package) Files() []alpm.File {
panic("not implemented") // TODO: Implement
}
// ContainsFile checks if the path is in the package filelist
// ContainsFile checks if the path is in the package filelist.
func (p *Package) ContainsFile(path string) (alpm.File, error) {
panic("not implemented") // TODO: Implement
}
@@ -166,13 +166,13 @@ func (p *Package) URL() string {
panic("not implemented") // TODO: Implement
}
// ComputeRequiredBy returns the names of reverse dependencies of a package
// ComputeRequiredBy returns the names of reverse dependencies of a package.
func (p *Package) ComputeRequiredBy() []string {
panic("not implemented") // TODO: Implement
}
// ComputeOptionalFor returns the names of packages that optionally
// require the given package
// require the given package.
func (p *Package) ComputeOptionalFor() []string {
panic("not implemented") // TODO: Implement
}

View File

@@ -2,7 +2,7 @@ package dep
import aur "github.com/Jguer/yay/v10/pkg/query"
// Base is an AUR base package
// Base is an AUR base package.
type Base []*aur.Pkg
// Pkgbase returns the first base package.
@@ -21,15 +21,17 @@ func (b Base) URLPath() string {
}
// Packages foo and bar from a pkgbase named base would print like so:
// base (foo bar)
// base (foo bar).
func (b Base) String() string {
pkg := b[0]
str := pkg.PackageBase
if len(b) > 1 || pkg.PackageBase != pkg.Name {
str2 := " ("
for _, split := range b {
str2 += split.Name + " "
}
str2 = str2[:len(str2)-1] + ")"
str += str2

View File

@@ -45,6 +45,7 @@ func (dp *Pool) checkForwardConflict(name, conflict string, conflicts stringset.
if n != conflict {
n += " (" + conflict + ")"
}
conflicts.Add(name, n)
}
}
@@ -113,6 +114,7 @@ func (dp *Pool) checkReverseConflicts(conflicts stringset.MapStringSet) {
if dp.hasPackage(pkg.Name()) {
continue
}
for _, conflict := range dp.AlpmExecutor.PackageConflicts(pkg) {
dp.checkReverseConflict(pkg.Name(), conflict.String(), conflicts)
}
@@ -126,10 +128,13 @@ func (dp *Pool) CheckConflicts(useAsk, noConfirm, noDeps bool) (stringset.MapStr
}
var wg sync.WaitGroup
innerConflicts := make(stringset.MapStringSet)
wg.Add(2)
text.OperationInfoln(gotext.Get("Checking for conflicts..."))
go func() {
dp.checkForwardConflicts(conflicts)
dp.checkReverseConflicts(conflicts)
@@ -137,6 +142,7 @@ func (dp *Pool) CheckConflicts(useAsk, noConfirm, noDeps bool) (stringset.MapStr
}()
text.OperationInfoln(gotext.Get("Checking for inner conflicts..."))
go func() {
dp.checkInnerConflicts(innerConflicts)
wg.Done()
@@ -152,6 +158,7 @@ func (dp *Pool) CheckConflicts(useAsk, noConfirm, noDeps bool) (stringset.MapStr
for pkg := range pkgs {
str += " " + text.Cyan(pkg) + ","
}
str = strings.TrimSuffix(str, ",")
fmt.Println(str)
@@ -166,6 +173,7 @@ func (dp *Pool) CheckConflicts(useAsk, noConfirm, noDeps bool) (stringset.MapStr
for pkg := range pkgs {
str += " " + text.Cyan(pkg) + ","
}
str = strings.TrimSuffix(str, ",")
fmt.Println(str)
@@ -211,12 +219,15 @@ func (dp *Pool) _checkMissing(dep string, stack []string, missing *missing, noDe
return
}
}
missing.Missing[dep] = append(missing.Missing[dep], stack)
return
}
if aurPkg := dp.findSatisfierAur(dep); aurPkg != nil {
missing.Good.Set(dep)
combinedDepList := ComputeCombinedDepList(aurPkg, noDeps, noCheckDeps)
for _, deps := range combinedDepList {
for _, aurDep := range deps {
@@ -291,6 +302,7 @@ func (dp *Pool) CheckMissing(noDeps, noCheckDeps bool) error {
}
text.Errorln(gotext.Get("Could not find all required packages:"))
for dep, trees := range missing.Missing {
for _, tree := range trees {
fmt.Fprintf(os.Stderr, "\t%s", text.Cyan(dep))

View File

@@ -45,6 +45,7 @@ func (do *Order) orderPkgAur(pkg *aur.Pkg, dp *Pool, runtime, noDeps, noCheckDep
if runtime {
do.Runtime.Set(pkg.Name)
}
delete(dp.Aur, pkg.Name)
for i, deps := range ComputeCombinedDepList(pkg, noDeps, noCheckDeps) {
@@ -73,6 +74,7 @@ func (do *Order) orderPkgRepo(pkg db.IPackage, dp *Pool, runtime bool) {
if runtime {
do.Runtime.Set(pkg.Name())
}
delete(dp.Repo, pkg.Name())
for _, dep := range dp.AlpmExecutor.PackageDepends(pkg) {
@@ -113,7 +115,7 @@ func (do *Order) GetMake() []string {
return makeOnly
}
// Print prints repository packages to be downloaded
// Print prints repository packages to be downloaded.
func (do *Order) Print() {
repo := ""
repoMake := ""
@@ -153,6 +155,7 @@ func (do *Order) Print() {
if do.Runtime.Get(split.Name) {
pkgStr += split.Name + " "
aurLen++
push = true
} else {
pkgStrMake += split.Name + " "
@@ -165,15 +168,18 @@ func (do *Order) Print() {
pkgStrMake = pkgStrMake[:len(pkgStrMake)-1] + ")"
case do.Runtime.Get(base[0].Name):
aurLen++
push = true
default:
aurMakeLen++
pushMake = true
}
if push {
aurString += pkgStr
}
if pushMake {
aurMake += pkgStrMake
}

View File

@@ -81,7 +81,7 @@ func makePool(dbExecutor db.Executor, aurClient *aur.Client) *Pool {
return dp
}
// Includes db/ prefixes and group installs
// Includes db/ prefixes and group installs.
func (dp *Pool) ResolveTargets(pkgs []string,
mode parser.TargetMode,
ignoreProviders, noConfirm, provides bool, rebuild string, splitN int, noDeps, noCheckDeps bool, assumeInstalled []string) error {
@@ -109,6 +109,7 @@ func (dp *Pool) ResolveTargets(pkgs []string,
if target.DB == "aur" || mode == parser.ModeAUR {
dp.Targets = append(dp.Targets, target)
aurTargets.Set(target.DepString())
continue
}
@@ -124,6 +125,7 @@ func (dp *Pool) ResolveTargets(pkgs []string,
dp.Targets = append(dp.Targets, target)
dp.Explicit.Set(foundPkg.Name())
dp.ResolveRepoDependency(foundPkg, noDeps)
continue
} else {
// check for groups
@@ -169,15 +171,20 @@ func (dp *Pool) ResolveTargets(pkgs []string,
// Ofcouse only the first three packages provide yay, the rest are just false
// positives.
//
// This method increases dependency resolve time
// This method increases dependency resolve time.
func (dp *Pool) findProvides(pkgs stringset.StringSet) error {
var mux sync.Mutex
var wg sync.WaitGroup
var (
mux sync.Mutex
wg sync.WaitGroup
)
doSearch := func(pkg string) {
defer wg.Done()
var err error
var results []query.Pkg
var (
err error
results []query.Pkg
)
// Hack for a bigger search result, if the user wants
// java-envronment we can search for just java instead and get
@@ -209,7 +216,9 @@ func (dp *Pool) findProvides(pkgs stringset.StringSet) error {
if dp.AlpmExecutor.LocalPackage(pkg) != nil {
continue
}
wg.Add(1)
go doSearch(pkg)
}
@@ -264,7 +273,7 @@ func (dp *Pool) cacheAURPackages(_pkgs stringset.StringSet, provides bool, split
}
// Compute dependency lists used in Package dep searching and ordering.
// Order sensitive TOFIX
// Order sensitive TOFIX.
func ComputeCombinedDepList(pkg *aur.Pkg, noDeps, noCheckDeps bool) [][]string {
combinedDepList := make([][]string, 0, 3)
@@ -310,6 +319,7 @@ func (dp *Pool) resolveAURPackages(pkgs stringset.StringSet,
if explicit {
dp.Explicit.Set(pkg.Name)
}
dp.Aur[pkg.Name] = pkg
combinedDepList := ComputeCombinedDepList(pkg, noDeps, noCheckDeps)
@@ -330,6 +340,7 @@ func (dp *Pool) resolveAURPackages(pkgs stringset.StringSet,
settings.HideMenus = isInstalled
repoPkg := dp.AlpmExecutor.SyncSatisfier(dep) // has satisfier in repo: fetch it
settings.HideMenus = hm
if isInstalled && (rebuild != "tree" || repoPkg != nil) {
continue
}
@@ -345,11 +356,13 @@ func (dp *Pool) resolveAURPackages(pkgs stringset.StringSet,
}
err = dp.resolveAURPackages(newAURPackages, false, ignoreProviders, noConfirm, provides, rebuild, splitN, noDeps, noCheckDeps)
return err
}
func (dp *Pool) ResolveRepoDependency(pkg db.IPackage, noDeps bool) {
dp.Repo[pkg.Name()] = pkg
if noDeps {
return
}
@@ -405,7 +418,7 @@ func (dp *Pool) findSatisfierAur(dep string) *query.Pkg {
// foo and foo-git.
// Using Pacman's ways trying to install foo would never give you
// a menu.
// TODO: maybe intermix repo providers in the menu
// TODO: maybe intermix repo providers in the menu.
func (dp *Pool) findSatisfierAurCache(dep string, ignoreProviders, noConfirm, provides bool) *query.Pkg {
depName, _, _ := splitDep(dep)
seen := make(stringset.StringSet)
@@ -437,6 +450,7 @@ func (dp *Pool) findSatisfierAurCache(dep string, ignoreProviders, noConfirm, pr
if pkgSatisfies(pkg.Name, pkg.Version, dep) {
providerSlice.Pkgs = append(providerSlice.Pkgs, pkg)
seen.Set(pkg.Name)
continue
}
@@ -444,6 +458,7 @@ func (dp *Pool) findSatisfierAurCache(dep string, ignoreProviders, noConfirm, pr
if provideSatisfies(provide, dep, pkg.Version) {
providerSlice.Pkgs = append(providerSlice.Pkgs, pkg)
seen.Set(pkg.Name)
continue
}
}
@@ -504,6 +519,7 @@ func (dp *Pool) hasPackage(name string) bool {
func isInAssumeInstalled(name string, assumeInstalled []string) bool {
for _, pkgAndVersion := range assumeInstalled {
assumeName, _, _ := splitDep(pkgAndVersion)
depName, _, _ := splitDep(name)
if assumeName == depName {
return true
@@ -537,9 +553,11 @@ func providerMenu(dep string, providers providers, noConfirm bool) *query.Pkg {
}
reader := bufio.NewReader(os.Stdin)
numberBuf, overflow, err := reader.ReadLine()
if err != nil {
fmt.Fprintln(os.Stderr, err)
break
}

View File

@@ -36,6 +36,7 @@ package() {
}`
func Test_getPackageURL(t *testing.T) {
t.Parallel()
type args struct {
db string
pkgName string
@@ -75,7 +76,9 @@ func Test_getPackageURL(t *testing.T) {
},
}
for _, tt := range tests {
tt := tt
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
got, err := getPackageURL(tt.args.db, tt.args.pkgName)
if tt.wantErr {
assert.ErrorIs(t, err, ErrInvalidRepository)
@@ -86,6 +89,7 @@ func Test_getPackageURL(t *testing.T) {
}
func TestGetABSPkgbuild(t *testing.T) {
t.Parallel()
pkgBuildHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(200)
w.Write([]byte(gitExtrasPKGBUILD))
@@ -95,7 +99,6 @@ func TestGetABSPkgbuild(t *testing.T) {
w.WriteHeader(404)
})
PKGBuild := httptest.NewServer(pkgBuildHandler)
type args struct {
handler http.Handler
dbName string
@@ -129,7 +132,10 @@ func TestGetABSPkgbuild(t *testing.T) {
},
}
for _, tt := range tests {
tt := tt
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
PKGBuild := httptest.NewServer(pkgBuildHandler)
ABSPackageURL = PKGBuild.URL
PKGBuild.Config.Handler = tt.args.handler
got, err := ABSPKGBUILD(PKGBuild.Client(), tt.args.dbName, tt.args.pkgName)
@@ -145,8 +151,7 @@ func TestGetABSPkgbuild(t *testing.T) {
}
func Test_getPackageRepoURL(t *testing.T) {
ABSPackageURL = "https://github.com/archlinux/svntogit-packages"
ABSCommunityURL = "https://github.com/archlinux/svntogit-community"
t.Parallel()
type args struct {
db string
@@ -177,7 +182,9 @@ func Test_getPackageRepoURL(t *testing.T) {
},
}
for _, tt := range tests {
tt := tt
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
got, err := getPackageRepoURL(tt.args.db)
if tt.wantErr {
assert.ErrorIs(t, err, ErrInvalidRepository)
@@ -191,6 +198,7 @@ func Test_getPackageRepoURL(t *testing.T) {
// WHEN ABSPKGBUILDRepo is called
// THEN a clone command should be formed
func TestABSPKGBUILDRepo(t *testing.T) {
t.Parallel()
cmdRunner := &testRunner{}
cmdBuilder := &testGitBuilder{
index: 0,
@@ -211,6 +219,7 @@ func TestABSPKGBUILDRepo(t *testing.T) {
// WHEN ABSPKGBUILDRepo is called
// THEN a pull command should be formed
func TestABSPKGBUILDRepoExistsPerms(t *testing.T) {
t.Parallel()
dir, _ := ioutil.TempDir("/tmp/", "yay-test")
defer os.RemoveAll(dir)

View File

@@ -14,8 +14,6 @@ import (
"github.com/Jguer/yay/v10/pkg/text"
)
var AURPackageURL = "https://aur.archlinux.org/cgit/aur.git"
func AURPKGBUILD(httpClient *http.Client, pkgName, aurURL string) ([]byte, error) {
values := url.Values{}
values.Set("h", pkgName)
@@ -69,6 +67,7 @@ func AURPKGBUILDRepos(
newClone, err := AURPKGBUILDRepo(cmdBuilder, aurURL, target, dest, force)
progress := 0
if err != nil {
errs.Add(err)
} else {

View File

@@ -15,6 +15,7 @@ import (
)
func TestGetAURPkgbuild(t *testing.T) {
t.Parallel()
pkgBuildHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(200)
w.Write([]byte(gitExtrasPKGBUILD))
@@ -24,7 +25,6 @@ func TestGetAURPkgbuild(t *testing.T) {
w.WriteHeader(404)
})
PKGBuild := httptest.NewServer(pkgBuildHandler)
type args struct {
handler http.Handler
pkgName string
@@ -55,7 +55,10 @@ func TestGetAURPkgbuild(t *testing.T) {
},
}
for _, tt := range tests {
tt := tt
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
PKGBuild := httptest.NewServer(pkgBuildHandler)
PKGBuild.Config.Handler = tt.args.handler
got, err := AURPKGBUILD(PKGBuild.Client(), tt.args.pkgName, PKGBuild.URL)
if tt.wantErr {
@@ -73,6 +76,7 @@ func TestGetAURPkgbuild(t *testing.T) {
// WHEN AURPKGBUILDRepo is called
// THEN a clone command should be formed
func TestAURPKGBUILDRepo(t *testing.T) {
t.Parallel()
cmdRunner := &testRunner{}
cmdBuilder := &testGitBuilder{
index: 0,
@@ -93,6 +97,7 @@ func TestAURPKGBUILDRepo(t *testing.T) {
// WHEN AURPKGBUILDRepo is called
// THEN a pull command should be formed
func TestAURPKGBUILDRepoExistsPerms(t *testing.T) {
t.Parallel()
dir, _ := ioutil.TempDir("/tmp/", "yay-test")
defer os.RemoveAll(dir)
@@ -114,8 +119,8 @@ func TestAURPKGBUILDRepoExistsPerms(t *testing.T) {
assert.Equal(t, false, cloned)
}
// GIVEN
func TestAURPKGBUILDRepos(t *testing.T) {
t.Parallel()
dir, _ := ioutil.TempDir("/tmp/", "yay-test")
defer os.RemoveAll(dir)

View File

@@ -25,7 +25,8 @@ func downloadGitRepo(cmdBuilder exe.GitCmdBuilder,
finalDir := filepath.Join(dest, pkgName)
newClone := true
if _, err := os.Stat(filepath.Join(finalDir, ".git")); os.IsNotExist(err) || (err == nil && force) {
switch _, err := os.Stat(filepath.Join(finalDir, ".git")); {
case os.IsNotExist(err) || (err == nil && force):
if _, errD := os.Stat(finalDir); force && errD == nil {
if errR := os.RemoveAll(finalDir); errR != nil {
return false, ErrGetPKGBUILDRepo{inner: errR, pkgName: pkgName, errOut: ""}
@@ -43,19 +44,20 @@ func downloadGitRepo(cmdBuilder exe.GitCmdBuilder,
if errCapture != nil {
return false, ErrGetPKGBUILDRepo{inner: errCapture, pkgName: pkgName, errOut: stderr}
}
} else if err != nil {
case err != nil:
return false, ErrGetPKGBUILDRepo{
inner: err,
pkgName: pkgName,
errOut: gotext.Get("error reading %s", filepath.Join(dest, pkgName, ".git")),
}
} else {
default:
cmd := cmdBuilder.BuildGitCmd(filepath.Join(dest, pkgName), "pull", "--ff-only")
_, stderr, errCmd := cmdBuilder.Capture(cmd, 0)
if errCmd != nil {
return false, ErrGetPKGBUILDRepo{inner: errCmd, pkgName: pkgName, errOut: stderr}
}
newClone = false
}
@@ -149,8 +151,10 @@ func PKGBUILDRepos(dbExecutor DBSearcher,
wg.Add(1)
go func(target, dbName, pkgName string, aur bool) {
var err error
var newClone bool
var (
err error
newClone bool
)
if aur {
newClone, err = AURPKGBUILDRepo(cmdBuilder, aurURL, pkgName, dest, force)
@@ -159,6 +163,7 @@ func PKGBUILDRepos(dbExecutor DBSearcher,
}
progress := 0
if err != nil {
errs.Add(err)
} else {
@@ -189,7 +194,7 @@ func PKGBUILDRepos(dbExecutor DBSearcher,
return cloned, errs.Return()
}
// TODO: replace with dep.ResolveTargets
// TODO: replace with dep.ResolveTargets.
func getPackageUsableName(dbExecutor DBSearcher, target string, mode parser.TargetMode) (dbname, pkgname string, aur, toSkip bool) {
aur = true

View File

@@ -19,6 +19,7 @@ import (
// WHEN defining package db as a target
// THEN all should be found and cloned, except the repo one
func TestPKGBUILDReposDefinedDBPull(t *testing.T) {
t.Parallel()
dir, _ := ioutil.TempDir("/tmp/", "yay-test")
defer os.RemoveAll(dir)
@@ -50,6 +51,7 @@ func TestPKGBUILDReposDefinedDBPull(t *testing.T) {
// WHEN defining package db as a target
// THEN all should be found and cloned
func TestPKGBUILDReposDefinedDBClone(t *testing.T) {
t.Parallel()
dir, _ := ioutil.TempDir("/tmp/", "yay-test")
defer os.RemoveAll(dir)
@@ -79,6 +81,7 @@ func TestPKGBUILDReposDefinedDBClone(t *testing.T) {
// WHEN defining as non specified targets
// THEN all should be found and cloned
func TestPKGBUILDReposClone(t *testing.T) {
t.Parallel()
dir, _ := ioutil.TempDir("/tmp/", "yay-test")
defer os.RemoveAll(dir)
@@ -108,6 +111,7 @@ func TestPKGBUILDReposClone(t *testing.T) {
// WHEN defining as non specified targets
// THEN all aur be found and cloned
func TestPKGBUILDReposNotFound(t *testing.T) {
t.Parallel()
dir, _ := ioutil.TempDir("/tmp/", "yay-test")
defer os.RemoveAll(dir)
@@ -137,6 +141,7 @@ func TestPKGBUILDReposNotFound(t *testing.T) {
// WHEN defining as non specified targets in repo mode
// THEN only repo should be cloned
func TestPKGBUILDReposRepoMode(t *testing.T) {
t.Parallel()
dir, _ := ioutil.TempDir("/tmp/", "yay-test")
defer os.RemoveAll(dir)
@@ -166,7 +171,7 @@ func TestPKGBUILDReposRepoMode(t *testing.T) {
// WHEN defining as specified targets
// THEN all aur be found and cloned
func TestPKGBUILDFull(t *testing.T) {
defer gock.Off()
t.Parallel()
gock.New("https://aur.archlinux.org").
Get("/cgit/aur.git/plain/PKGBUILD").MatchParam("h", "yay-git").
@@ -182,6 +187,7 @@ func TestPKGBUILDFull(t *testing.T) {
Reply(200).
BodyString("example_yay")
defer gock.Off()
targets := []string{"core/yay", "aur/yay-bin", "yay-git"}
searcher := &testDBSearcher{
absPackagesDB: map[string]string{"yay": "core"},

View File

@@ -8,13 +8,13 @@ import (
"github.com/Jguer/yay/v10/pkg/stringset"
)
// IntRange stores a max and min amount for range
// IntRange stores a max and min amount for range.
type IntRange struct {
min int
max int
}
// IntRanges is a slice of IntRange
// IntRanges is a slice of IntRange.
type IntRanges []IntRange
func makeIntRange(min, max int) IntRange {
@@ -25,13 +25,13 @@ func makeIntRange(min, max int) IntRange {
}
// Get returns true if the argument n is included in the closed range
// between min and max
// between min and max.
func (r IntRange) Get(n int) bool {
return n >= r.min && n <= r.max
}
// Get returns true if the argument n is included in the closed range
// between min and max of any of the provided IntRanges
// between min and max of any of the provided IntRanges.
func (rs IntRanges) Get(n int) bool {
for _, r := range rs {
if r.Get(n) {
@@ -42,19 +42,21 @@ func (rs IntRanges) Get(n int) bool {
return false
}
// Min returns min value between a and b
// Min returns min value between a and b.
func Min(a, b int) int {
if a < b {
return a
}
return b
}
// Max returns max value between a and b
// Max returns max value between a and b.
func Max(a, b int) int {
if a < b {
return b
}
return a
}
@@ -67,7 +69,7 @@ func Max(a, b int) int {
// respectively. other holds anything that can't be parsed as an int. This is
// intended to allow words inside of number menus. e.g. 'all' 'none' 'abort'
// of course the implementation is up to the caller, this function mearley parses
// the input and organizes it
// the input and organizes it.
func ParseNumberMenu(input string) (include, exclude IntRanges,
otherInclude, otherExclude stringset.StringSet) {
include = make(IntRanges, 0)
@@ -80,9 +82,12 @@ func ParseNumberMenu(input string) (include, exclude IntRanges,
})
for _, word := range words {
var num1 int
var num2 int
var err error
var (
num1 int
num2 int
err error
)
invert := false
other := otherInclude

View File

@@ -7,6 +7,7 @@ import (
)
func TestParseNumberMenu(t *testing.T) {
t.Parallel()
type result struct {
Include IntRanges
Exclude IntRanges
@@ -99,6 +100,7 @@ func TestParseNumberMenu(t *testing.T) {
}
func TestIntRange_Get(t *testing.T) {
t.Parallel()
type fields struct {
min int
max int
@@ -120,7 +122,9 @@ func TestIntRange_Get(t *testing.T) {
{name: "normal end range false", fields: fields{1, 2}, args: args{3}, want: false},
}
for _, tt := range tests {
tt := tt
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
r := IntRange{
min: tt.fields.min,
max: tt.fields.max,
@@ -158,6 +162,7 @@ func intRangesEqual(a, b IntRanges) bool {
}
func TestIntRanges_Get(t *testing.T) {
t.Parallel()
type args struct {
n int
}
@@ -168,8 +173,8 @@ func TestIntRanges_Get(t *testing.T) {
want bool
}{
{name: "normal range true", rs: IntRanges{{0, 10}}, args: args{5}, want: true},
{name: "normal ranges inbetween true", rs: IntRanges{{0, 4}, {5, 10}}, args: args{5}, want: true},
{name: "normal ranges inbetween false", rs: IntRanges{{0, 4}, {6, 10}}, args: args{5}, want: false},
{name: "normal ranges in between true", rs: IntRanges{{0, 4}, {5, 10}}, args: args{5}, want: true},
{name: "normal ranges in between false", rs: IntRanges{{0, 4}, {6, 10}}, args: args{5}, want: false},
{name: "normal start range true", rs: IntRanges{{0, 10}}, args: args{0}, want: true},
{name: "normal end range true", rs: IntRanges{{0, 10}}, args: args{10}, want: true},
{name: "small range true", rs: IntRanges{{1, 1}, {3, 3}}, args: args{1}, want: true},
@@ -177,7 +182,9 @@ func TestIntRanges_Get(t *testing.T) {
{name: "normal end range false", rs: IntRanges{{1, 2}}, args: args{3}, want: false},
}
for _, tt := range tests {
tt := tt
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
if got := tt.rs.Get(tt.args.n); got != tt.want {
t.Errorf("IntRanges.Get() = %v, want %v", got, tt.want)
}

View File

@@ -2,13 +2,13 @@ package multierror
import "sync"
// MultiError type handles error accumulation from goroutines
// MultiError type handles error accumulation from goroutines.
type MultiError struct {
Errors []error
mux sync.Mutex
}
// Error turns the MultiError structure into a string
// Error turns the MultiError structure into a string.
func (err *MultiError) Error() string {
str := ""
@@ -19,7 +19,7 @@ func (err *MultiError) Error() string {
return str[:len(str)-1]
}
// Add adds an error to the Multierror structure
// Add adds an error to the Multierror structure.
func (err *MultiError) Add(e error) {
if e == nil {
return
@@ -31,7 +31,7 @@ func (err *MultiError) Add(e error) {
}
// Return is used as a wrapper on return on whether to return the
// MultiError Structure if errors exist or nil instead of delivering an empty structure
// MultiError Structure if errors exist or nil instead of delivering an empty structure.
func (err *MultiError) Return() error {
if len(err.Errors) > 0 {
return err

View File

@@ -26,6 +26,7 @@ type item struct {
func (item *item) print(buildTime time.Time, all, quiet bool) {
var fd string
date, err := time.Parse(time.RFC1123Z, item.PubDate)
if err != nil {
@@ -72,6 +73,7 @@ func PrintNewsFeed(client *http.Client, cutOffDate time.Time, sortMode int, all,
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return err
@@ -80,8 +82,7 @@ func PrintNewsFeed(client *http.Client, cutOffDate time.Time, sortMode int, all,
rssGot := rss{}
d := xml.NewDecoder(bytes.NewReader(body))
err = d.Decode(&rssGot)
if err != nil {
if err := d.Decode(&rssGot); err != nil {
return err
}
@@ -100,18 +101,21 @@ func PrintNewsFeed(client *http.Client, cutOffDate time.Time, sortMode int, all,
// Crude html parsing, good enough for the arch news
// This is only displayed in the terminal so there should be no security
// concerns
// concerns.
func parseNews(str string) string {
var buffer bytes.Buffer
var tagBuffer bytes.Buffer
var escapeBuffer bytes.Buffer
inTag := false
inEscape := false
var (
buffer bytes.Buffer
tagBuffer bytes.Buffer
escapeBuffer bytes.Buffer
inTag = false
inEscape = false
)
for _, char := range str {
if inTag {
if char == '>' {
inTag = false
switch tagBuffer.String() {
case "code":
buffer.WriteString(text.CyanCode)
@@ -125,32 +129,40 @@ func parseNews(str string) string {
}
tagBuffer.WriteRune(char)
continue
}
if inEscape {
if char == ';' {
inEscape = false
escapeBuffer.WriteRune(char)
s := html.UnescapeString(escapeBuffer.String())
buffer.WriteString(s)
continue
}
escapeBuffer.WriteRune(char)
continue
}
if char == '<' {
inTag = true
tagBuffer.Reset()
continue
}
if char == '&' {
inEscape = true
escapeBuffer.Reset()
escapeBuffer.WriteRune(char)
continue
}
@@ -158,5 +170,6 @@ func parseNews(str string) string {
}
buffer.WriteString(text.ResetCode)
return buffer.String()
}

View File

@@ -79,6 +79,7 @@ intervention when you hit this message:&lt;/p&gt;
`
func TestPrintNewsFeed(t *testing.T) {
t.Parallel()
layout := "2006-01-02"
str := "2020-04-13"
lastNewsTime, _ := time.Parse(layout, str)
@@ -100,13 +101,15 @@ func TestPrintNewsFeed(t *testing.T) {
{name: "latest-quiet-topdown", args: args{sortMode: 1, cutOffDate: lastNewsTime, all: false, quiet: true}, wantErr: false},
}
for _, tt := range tests {
tt := tt
t.Run(tt.name, func(t *testing.T) {
defer gock.Off()
gock.New("https://archlinux.org").
Get("/feeds/news").
Reply(200).
BodyString(sampleNews)
defer gock.Off()
rescueStdout := os.Stdout
r, w, _ := os.Pipe()
os.Stdout = w

View File

@@ -24,6 +24,7 @@ func (set pgpKeySet) toSlice() []string {
for v := range set {
slice = append(slice, v)
}
return slice
}
@@ -37,6 +38,7 @@ func (set pgpKeySet) set(key string, p dep.Base) {
func (set pgpKeySet) get(key string) bool {
upperKey := strings.ToUpper(key)
_, exists := set[upperKey]
return exists
}
@@ -47,6 +49,7 @@ func CheckPgpKeys(bases []dep.Base, srcinfos map[string]*gosrc.Srcinfo,
// Let's check the keys individually, and then we can offer to import
// the problematic ones.
problematic := make(pgpKeySet)
args := append(strings.Fields(gpgFlags), "--list-keys")
// Mapping all the keys.
@@ -63,8 +66,7 @@ func CheckPgpKeys(bases []dep.Base, srcinfos map[string]*gosrc.Srcinfo,
}
cmd := exec.Command(gpgBin, append(args, key)...)
err := cmd.Run()
if err != nil {
if err := cmd.Run(); err != nil {
problematic.set(key, base)
}
}
@@ -97,10 +99,11 @@ func importKeys(keys []string, gpgBin, gpgFlags string) error {
cmd.Stdin, cmd.Stdout, cmd.Stderr = os.Stdin, os.Stdout, os.Stderr
text.OperationInfoln(gotext.Get("Importing keys with gpg..."))
err := cmd.Run()
if err != nil {
if err := cmd.Run(); err != nil {
return errors.New(gotext.Get("problem importing keys"))
}
return nil
}
@@ -112,14 +115,18 @@ func formatKeysToImport(keys pgpKeySet) (string, error) {
}
var buffer bytes.Buffer
buffer.WriteString(text.SprintOperationInfo(gotext.Get("PGP keys need importing:")))
for key, bases := range keys {
pkglist := ""
for _, base := range bases {
pkglist += base.String() + " "
}
pkglist = strings.TrimRight(pkglist, " ")
buffer.WriteString("\n" + text.SprintWarn(gotext.Get("%s, required by: %s", text.Cyan(key), text.Cyan(pkglist))))
}
return buffer.String(), nil
}

View File

@@ -241,6 +241,7 @@ func TestCheckPgpKeys(t *testing.T) {
}
for _, tt := range casetests {
tt := tt
t.Run(tt.name, func(t *testing.T) {
rescueStdout := os.Stdout
r, w, _ := os.Pipe()

View File

@@ -22,17 +22,22 @@ type Pkg = aur.Pkg
func AURInfo(aurClient *aur.Client, names []string, warnings *AURWarnings, splitN int) ([]*Pkg, error) {
info := make([]*Pkg, 0, len(names))
seen := make(map[string]int)
var mux sync.Mutex
var wg sync.WaitGroup
var errs multierror.MultiError
var (
mux sync.Mutex
wg sync.WaitGroup
errs multierror.MultiError
)
makeRequest := func(n, max int) {
defer wg.Done()
tempInfo, requestErr := aurClient.Info(context.Background(), names[n:max])
errs.Add(requestErr)
if requestErr != nil {
errs.Add(requestErr)
return
}
mux.Lock()
for i := range tempInfo {
info = append(info, &tempInfo[i])
@@ -42,7 +47,9 @@ func AURInfo(aurClient *aur.Client, names []string, warnings *AURWarnings, split
for n := 0; n < len(names); n += splitN {
max := intrange.Min(len(names), n+splitN)
wg.Add(1)
go makeRequest(n, max)
}
@@ -68,6 +75,7 @@ func AURInfo(aurClient *aur.Client, names []string, warnings *AURWarnings, split
if pkg.Maintainer == "" && !warnings.Ignore.Get(name) {
warnings.Orphans = append(warnings.Orphans, name)
}
if pkg.OutOfDate != 0 && !warnings.Ignore.Get(name) {
warnings.OutOfDate = append(warnings.OutOfDate, name)
}
@@ -80,6 +88,7 @@ func AURInfoPrint(aurClient *aur.Client, names []string, splitN int) ([]*Pkg, er
text.OperationInfoln(gotext.Get("Querying AUR..."))
warnings := &AURWarnings{}
info, err := AURInfo(aurClient, names, warnings, splitN)
if err != nil {
return info, err

View File

@@ -64,5 +64,6 @@ func printRange(names []string) {
for _, name := range names {
fmt.Print(" " + text.Cyan(name))
}
fmt.Println()
}

View File

@@ -8,7 +8,7 @@ import (
"github.com/Jguer/yay/v10/pkg/text"
)
// GetPackageNamesBySource returns package names with and without correspondence in SyncDBS respectively
// GetPackageNamesBySource returns package names with and without correspondence in SyncDBS respectively.
func GetPackageNamesBySource(dbExecutor db.Executor) (local, remote []string, err error) {
for _, localpkg := range dbExecutor.LocalPackages() {
pkgName := localpkg.Name()
@@ -18,6 +18,7 @@ func GetPackageNamesBySource(dbExecutor db.Executor) (local, remote []string, er
remote = append(remote, pkgName)
}
}
return local, remote, err
}
@@ -32,6 +33,7 @@ func GetRemotePackages(dbExecutor db.Executor) (
remoteNames = append(remoteNames, pkgName)
}
}
return remote, remoteNames
}

View File

@@ -20,15 +20,15 @@ import (
)
const (
// Describes Sorting method for numberdisplay
// Describes Sorting method for numberdisplay.
BottomUp = iota
TopDown
)
// HideMenus indicates if pacman's provider menus must be hidden
// HideMenus indicates if pacman's provider menus must be hidden.
var HideMenus = false
// NoConfirm indicates if user input should be skipped
// NoConfirm indicates if user input should be skipped.
var NoConfirm = false
// Configuration stores yay's config.
@@ -93,14 +93,17 @@ func (c *Configuration) Save(configPath string) error {
return mkErr
}
}
in, err := os.OpenFile(configPath, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0o644)
if err != nil {
return err
}
defer in.Close()
if _, err = in.Write(marshalledinfo); err != nil {
return err
}
return in.Sync()
}
@@ -136,9 +139,11 @@ func (c *Configuration) String() string {
var buf bytes.Buffer
enc := json.NewEncoder(&buf)
enc.SetIndent("", "\t")
if err := enc.Encode(c); err != nil {
fmt.Fprintln(os.Stderr, err)
}
return buf.String()
}
@@ -249,6 +254,7 @@ func (c *Configuration) load(configPath string) {
}
defer cfile.Close()
if !os.IsNotExist(err) {
decoder := json.NewDecoder(cfile)
if err = decoder.Decode(c); err != nil {
@@ -262,6 +268,7 @@ func (c *Configuration) CmdBuilder(runner exe.Runner) exe.ICmdBuilder {
if runner == nil {
runner = &exe.OSRunner{}
}
return &exe.CmdBuilder{
GitBin: c.GitBin,
GitFlags: strings.Fields(c.GitFlags),

View File

@@ -58,7 +58,9 @@ func (c *CmdBuilder) BuildGitCmd(dir string, extraArgs ...string) *exec.Cmd {
}
cmd := exec.Command(c.GitBin, args...)
cmd.Env = append(os.Environ(), "GIT_TERMINAL_PROMPT=0")
return cmd
}
@@ -80,6 +82,7 @@ func (c *CmdBuilder) BuildMakepkgCmd(dir string, extraArgs ...string) *exec.Cmd
cmd := exec.Command(c.MakepkgBin, args...)
cmd.Dir = dir
return cmd
}
@@ -99,6 +102,7 @@ func (c *CmdBuilder) BuildPacmanCmd(args *parser.Arguments, mode parser.TargetMo
argArr = append(argArr, c.PacmanBin)
argArr = append(argArr, args.FormatGlobals()...)
argArr = append(argArr, args.FormatArgs()...)
if noConfirm {
argArr = append(argArr, "--noconfirm")
}
@@ -109,10 +113,11 @@ func (c *CmdBuilder) BuildPacmanCmd(args *parser.Arguments, mode parser.TargetMo
if needsRoot {
waitLock(c.PacmanDBPath)
}
return exec.Command(argArr[0], argArr[1:]...)
}
// waitLock will lock yay checking the status of db.lck until it does not exist
// waitLock will lock yay checking the status of db.lck until it does not exist.
func waitLock(dbPath string) {
lockDBPath := filepath.Join(dbPath, "db.lck")
if _, err := os.Stat(lockDBPath); err != nil {
@@ -124,8 +129,10 @@ func waitLock(dbPath string) {
for {
time.Sleep(3 * time.Second)
if _, err := os.Stat(lockDBPath); err != nil {
fmt.Println()
return
}
}
@@ -133,6 +140,7 @@ func waitLock(dbPath string) {
func (c *CmdBuilder) SudoLoop() {
c.updateSudo()
go c.sudoLoopBackground()
}

View File

@@ -17,8 +17,7 @@ type Runner interface {
Show(cmd *exec.Cmd) error
}
type OSRunner struct {
}
type OSRunner struct{}
func (r *OSRunner) Show(cmd *exec.Cmd) error {
cmd.Stdin, cmd.Stdout, cmd.Stderr = os.Stdin, os.Stdout, os.Stderr
@@ -26,9 +25,11 @@ func (r *OSRunner) Show(cmd *exec.Cmd) error {
}
func (r *OSRunner) Capture(cmd *exec.Cmd, timeout int64) (stdout, stderr string, err error) {
var outbuf, errbuf bytes.Buffer
var timer *time.Timer
timedOut := false
var (
outbuf, errbuf bytes.Buffer
timer *time.Timer
timedOut = false
)
cmd.Stdout = &outbuf
cmd.Stderr = &errbuf
@@ -38,6 +39,7 @@ func (r *OSRunner) Capture(cmd *exec.Cmd, timeout int64) (stdout, stderr string,
if err != nil {
stdout = strings.TrimSpace(outbuf.String())
stderr = strings.TrimSpace(errbuf.String())
return stdout, stderr, err
}
@@ -52,12 +54,14 @@ func (r *OSRunner) Capture(cmd *exec.Cmd, timeout int64) (stdout, stderr string,
}
err = cmd.Wait()
if timeout != 0 {
timer.Stop()
}
stdout = strings.TrimSpace(outbuf.String())
stderr = strings.TrimSpace(errbuf.String())
if err != nil {
return stdout, stderr, err
}

View File

@@ -20,6 +20,7 @@ func (o *Option) Add(args ...string) {
o.Args = args
return
}
o.Args = append(o.Args, args...)
}
@@ -27,6 +28,7 @@ func (o *Option) First() string {
if o.Args == nil || len(o.Args) == 0 {
return ""
}
return o.Args[0]
}
@@ -70,6 +72,7 @@ func MakeArguments() *Arguments {
func (a *Arguments) CopyGlobal() *Arguments {
cp := MakeArguments()
for k, v := range a.Options {
if v.Global {
cp.Options[k] = v
@@ -110,44 +113,44 @@ func (a *Arguments) NeedRoot(mode TargetMode) bool {
if a.ExistsArg("k", "check") {
return false
}
return true
case "F", "files":
if a.ExistsArg("y", "refresh") {
return true
}
return false
case "Q", "query":
if a.ExistsArg("k", "check") {
return true
}
return false
case "R", "remove":
if a.ExistsArg("p", "print", "print-format") {
return false
}
return true
case "S", "sync":
if a.ExistsArg("y", "refresh") {
switch {
case a.ExistsArg("y", "refresh"):
return true
}
if a.ExistsArg("p", "print", "print-format") {
return false
}
if a.ExistsArg("s", "search") {
return false
}
if a.ExistsArg("l", "list") {
return false
}
if a.ExistsArg("g", "groups") {
return false
}
if a.ExistsArg("i", "info") {
return false
}
if a.ExistsArg("c", "clean") && mode == ModeAUR {
case a.ExistsArg("p", "print", "print-format"):
return false
case a.ExistsArg("s", "search"):
return false
case a.ExistsArg("l", "list"):
return false
case a.ExistsArg("g", "groups"):
return false
case a.ExistsArg("i", "info"):
return false
case a.ExistsArg("c", "clean") && mode == ModeAUR:
return false
}
return true
case "U", "upgrade":
return true
@@ -162,6 +165,7 @@ func (a *Arguments) addOP(op string) error {
}
a.Op = op
return nil
}
@@ -179,6 +183,7 @@ func (a *Arguments) addParam(option, arg string) error {
if isGlobal(option) {
a.Options[option].Global = true
}
return nil
}
@@ -189,16 +194,18 @@ func (a *Arguments) AddArg(options ...string) error {
return err
}
}
return nil
}
// Multiple args acts as an OR operator
// Multiple args acts as an OR operator.
func (a *Arguments) ExistsArg(options ...string) bool {
for _, option := range options {
if _, exists := a.Options[option]; exists {
return true
}
}
return false
}
@@ -230,13 +237,14 @@ func (a *Arguments) ClearTargets() {
a.Targets = make([]string, 0)
}
// Multiple args acts as an OR operator
// Multiple args acts as an OR operator.
func (a *Arguments) ExistsDouble(options ...string) bool {
for _, option := range options {
if value, exists := a.Options[option]; exists {
return len(value.Args) >= 2
}
}
return false
}
@@ -258,6 +266,7 @@ func (a *Arguments) FormatArgs() (args []string) {
}
}
}
return args
}
@@ -266,6 +275,7 @@ func (a *Arguments) FormatGlobals() (args []string) {
if !arg.Global {
continue
}
formattedOption := formatArg(option)
for _, value := range arg.Args {
@@ -275,6 +285,7 @@ func (a *Arguments) FormatGlobals() (args []string) {
}
}
}
return args
}
@@ -534,7 +545,7 @@ func hasParam(arg string) bool {
}
// Parses short hand options such as:
// -Syu -b/some/path -
// -Syu -b/some/path -.
func (a *Arguments) parseShortOption(arg, param string) (usedNext bool, err error) {
if arg == "-" {
err = a.AddArg("-")
@@ -568,7 +579,7 @@ func (a *Arguments) parseShortOption(arg, param string) (usedNext bool, err erro
}
// Parses full length options such as:
// --sync --refresh --sysupgrade --dbpath /some/path --
// --sync --refresh --sysupgrade --dbpath /some/path --.
func (a *Arguments) parseLongOption(arg, param string) (usedNext bool, err error) {
if arg == "--" {
err = a.AddArg(arg)
@@ -648,6 +659,7 @@ func (a *Arguments) Parse() error {
if err := a.parseStdin(); err != nil {
return err
}
a.DelArg("-")
file, err := os.Open("/dev/tty")

View File

@@ -7,6 +7,7 @@ import (
)
func TestOption_Add(t *testing.T) {
t.Parallel()
type fields struct {
Args []string
}
@@ -31,7 +32,9 @@ func TestOption_Add(t *testing.T) {
}, want: []string{"c"}},
}
for _, tt := range tests {
tt := tt
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
o := &Option{
Args: tt.fields.Args,
}
@@ -42,6 +45,7 @@ func TestOption_Add(t *testing.T) {
}
func TestOption_Set(t *testing.T) {
t.Parallel()
type fields struct {
Args []string
}
@@ -66,7 +70,9 @@ func TestOption_Set(t *testing.T) {
}, want: []string{"c"}},
}
for _, tt := range tests {
tt := tt
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
o := &Option{
Args: tt.fields.Args,
}
@@ -77,6 +83,7 @@ func TestOption_Set(t *testing.T) {
}
func TestOption_First(t *testing.T) {
t.Parallel()
type fields struct {
Args []string
}
@@ -93,7 +100,9 @@ func TestOption_First(t *testing.T) {
}, want: ""},
}
for _, tt := range tests {
tt := tt
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
o := &Option{
Args: tt.fields.Args,
}
@@ -103,6 +112,7 @@ func TestOption_First(t *testing.T) {
}
func TestMakeArguments(t *testing.T) {
t.Parallel()
args := MakeArguments()
assert.NotNil(t, args)
assert.Equal(t, "", args.Op)
@@ -111,6 +121,7 @@ func TestMakeArguments(t *testing.T) {
}
func TestArguments_CopyGlobal(t *testing.T) {
t.Parallel()
type fields struct {
Op string
Options map[string]*Option
@@ -142,7 +153,9 @@ func TestArguments_CopyGlobal(t *testing.T) {
}},
}
for _, tt := range tests {
tt := tt
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
cmdArgs := &Arguments{
Op: tt.fields.Op,
Options: tt.fields.Options,
@@ -158,6 +171,7 @@ func TestArguments_CopyGlobal(t *testing.T) {
}
func TestArguments_Copy(t *testing.T) {
t.Parallel()
type fields struct {
Op string
Options map[string]*Option
@@ -188,7 +202,9 @@ func TestArguments_Copy(t *testing.T) {
}},
}
for _, tt := range tests {
tt := tt
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
cmdArgs := &Arguments{
Op: tt.fields.Op,
Options: tt.fields.Options,
@@ -202,6 +218,7 @@ func TestArguments_Copy(t *testing.T) {
}
func TestArguments_DelArg(t *testing.T) {
t.Parallel()
args := MakeArguments()
args.addParam("arch", "arg")
args.addParam("ask", "arg")
@@ -210,6 +227,7 @@ func TestArguments_DelArg(t *testing.T) {
}
func TestArguments_FormatArgs(t *testing.T) {
t.Parallel()
type fields struct {
Op string
Options map[string]*Option
@@ -242,7 +260,9 @@ func TestArguments_FormatArgs(t *testing.T) {
}, wantArgs: []string{"-Y", "--overwrite", "/tmp/a", "--overwrite", "/tmp/b", "--overwrite", "/tmp/c", "--needed"}},
}
for _, tt := range tests {
tt := tt
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
cmdArgs := &Arguments{
Op: tt.fields.Op,
Options: tt.fields.Options,
@@ -255,6 +275,7 @@ func TestArguments_FormatArgs(t *testing.T) {
}
func TestArguments_FormatGlobalArgs(t *testing.T) {
t.Parallel()
type fields struct {
Op string
Options map[string]*Option
@@ -287,7 +308,9 @@ func TestArguments_FormatGlobalArgs(t *testing.T) {
}, wantArgs: []string(nil)},
}
for _, tt := range tests {
tt := tt
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
cmdArgs := &Arguments{
Op: tt.fields.Op,
Options: tt.fields.Options,
@@ -300,6 +323,7 @@ func TestArguments_FormatGlobalArgs(t *testing.T) {
}
func Test_isArg(t *testing.T) {
t.Parallel()
got := isArg("zorg")
assert.False(t, got)

View File

@@ -13,12 +13,12 @@ type MapStringSet map[string]StringSet
// Add adds a new value to the Map.
// If n is already in the map, then v is appended to the StringSet under that key.
// Otherwise a new StringSet is creayed containing v
// Otherwise a new StringSet is creayed containing v.
func (mss MapStringSet) Add(n, v string) {
_, ok := mss[n]
if !ok {
if _, ok := mss[n]; !ok {
mss[n] = make(StringSet)
}
mss[n].Set(v)
}
@@ -67,7 +67,7 @@ func (set StringSet) Copy() StringSet {
return newSet
}
// FromSlice creates a new StringSet from an input slice
// FromSlice creates a new StringSet from an input slice.
func FromSlice(in []string) StringSet {
set := make(StringSet)
@@ -78,12 +78,12 @@ func FromSlice(in []string) StringSet {
return set
}
// Make creates a new StringSet from a set of arguments
// Make creates a new StringSet from a set of arguments.
func Make(in ...string) StringSet {
return FromSlice(in)
}
// Equal compares if two StringSets have the same values
// Equal compares if two StringSets have the same values.
func Equal(a, b StringSet) bool {
if a == nil && b == nil {
return true

View File

@@ -14,7 +14,7 @@ const (
ResetCode = "\x1b[0m"
)
// UseColor determines if package will emit colors
// UseColor determines if package will emit colors.
var UseColor = true
func stylize(startCode, in string) string {
@@ -59,9 +59,12 @@ func ColorHash(name string) (output string) {
if !UseColor {
return name
}
var hash uint = 5381
for i := 0; i < len(name); i++ {
hash = uint(name[i]) + ((hash << 5) + (hash))
}
return fmt.Sprintf("\x1b[%dm%s\x1b[0m", hash%6+31, name)
}

View File

@@ -7,12 +7,15 @@ import (
// Human method returns results in human readable format.
func Human(size int64) string {
floatsize := float32(size)
units := [...]string{"", "Ki", "Mi", "Gi", "Ti", "Pi", "Ei", "Zi", "Yi"}
for _, unit := range units {
if floatsize < 1024 {
return fmt.Sprintf("%.1f %sB", floatsize, unit)
}
floatsize /= 1024
}
return fmt.Sprintf("%d%s", size, "B")
}

View File

@@ -69,14 +69,17 @@ func getColumnCount() int {
if cachedColumnCount > 0 {
return cachedColumnCount
}
if count, err := strconv.Atoi(os.Getenv("COLUMNS")); err == nil {
cachedColumnCount = count
return cachedColumnCount
}
if ws, err := unix.IoctlGetWinsize(syscall.Stdout, unix.TIOCGWINSZ); err == nil {
cachedColumnCount = int(ws.Col)
return cachedColumnCount
}
return 80
}
@@ -96,6 +99,7 @@ func PrintInfoValue(key string, values ...string) {
maxCols := getColumnCount()
cols := keyLength + len(values[0])
str += values[0]
for _, value := range values[1:] {
if maxCols > keyLength && cols+len(value)+delimCount >= maxCols {
cols = keyLength
@@ -104,8 +108,10 @@ func PrintInfoValue(key string, values ...string) {
str += strings.Repeat(" ", delimCount)
cols += delimCount
}
str += value
cols += len(value)
}
fmt.Println(str)
}

View File

@@ -8,13 +8,14 @@ import (
"github.com/leonelquinteros/gotext"
)
// SplitDBFromName split apart db/package to db and package
// SplitDBFromName split apart db/package to db and package.
func SplitDBFromName(pkg string) (db, name string) {
split := strings.SplitN(pkg, "/", 2)
if len(split) == 2 {
return split[0], split[1]
}
return "", split[0]
}
@@ -52,12 +53,14 @@ func ContinueTask(s string, cont, noConfirm bool) bool {
return cont
}
var response string
var postFix string
yes := gotext.Get("yes")
no := gotext.Get("no")
y := string([]rune(yes)[0])
n := string([]rune(no)[0])
var (
response string
postFix string
yes = gotext.Get("yes")
no = gotext.Get("no")
y = string([]rune(yes)[0])
n = string([]rune(no)[0])
)
if cont {
postFix = fmt.Sprintf(" [%s/%s] ", strings.ToUpper(y), n)
@@ -72,5 +75,6 @@ func ContinueTask(s string, cont, noConfirm bool) bool {
}
response = strings.ToLower(response)
return response == yes || response == y
}

View File

@@ -8,10 +8,12 @@ import (
func TestLessRunes(t *testing.T) {
t.Parallel()
type args struct {
iRunes []rune
jRunes []rune
}
tests := []struct {
name string
args args
@@ -27,8 +29,11 @@ func TestLessRunes(t *testing.T) {
{name: "longerSecondArg", args: args{iRunes: []rune{'a'}, jRunes: []rune{'a', 'b'}}, want: true},
{name: "utf8 less", args: args{iRunes: []rune{'世', '2', '0'}, jRunes: []rune{'世', '界', '3'}}, want: true},
}
for _, tt := range tests {
tt := tt
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
got := LessRunes(tt.args.iRunes, tt.args.jRunes)
assert.Equal(t, tt.want, got)
})

View File

@@ -2,13 +2,13 @@ package text
import "time"
// Formats a unix timestamp to ISO 8601 date (yyyy-mm-dd)
// Formats a unix timestamp to ISO 8601 date (yyyy-mm-dd).
func FormatTime(i int) string {
t := time.Unix(int64(i), 0)
return t.Format("2006-01-02")
}
// Formats a unix timestamp to ISO 8601 date (Mon 02 Jan 2006 03:04:05 PM MST)
// Formats a unix timestamp to ISO 8601 date (Mon 02 Jan 2006 03:04:05 PM MST).
func FormatTimeQuery(i int) string {
t := time.Unix(int64(i), 0)
return t.Format("Mon 02 Jan 2006 03:04:05 PM MST")

View File

@@ -18,8 +18,10 @@ func UpDevel(
toUpdate := make([]db.IPackage, 0, len(aurdata))
toRemove := make([]string, 0)
var mux1, mux2 sync.Mutex
var wg sync.WaitGroup
var (
mux1, mux2 sync.Mutex
wg sync.WaitGroup
)
checkUpdate := func(pkgName string, e vcs.OriginInfoByURL) {
defer wg.Done()
@@ -31,6 +33,7 @@ func UpDevel(
mux1.Lock()
toUpdate = append(toUpdate, pkg)
mux1.Unlock()
return
}
}
@@ -44,12 +47,14 @@ func UpDevel(
for pkgName, e := range localCache.OriginsByPackage {
wg.Add(1)
go checkUpdate(pkgName, e)
}
wg.Wait()
toUpgrade := UpSlice{Up: make([]Upgrade, 0), Repos: []string{"devel"}}
for _, pkg := range toUpdate {
if pkg.ShouldIgnore() {
printIgnoringPackage(pkg, "latest-commit")
@@ -65,6 +70,7 @@ func UpDevel(
}
localCache.RemovePackage(toRemove)
return toUpgrade
}

View File

@@ -22,6 +22,7 @@ import (
)
func Test_upAUR(t *testing.T) {
t.Parallel()
type args struct {
remote []alpm.IPackage
aurdata map[string]*aur.Pkg
@@ -68,7 +69,9 @@ func Test_upAUR(t *testing.T) {
},
}
for _, tt := range tests {
tt := tt
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
rescueStdout := os.Stdout
r, w, _ := os.Pipe()
os.Stdout = w
@@ -106,6 +109,7 @@ func (r *MockRunner) Capture(cmd *exec.Cmd, timeout int64) (stdout, stderr strin
}
func Test_upDevel(t *testing.T) {
t.Parallel()
var err error
config, err := settings.NewConfig("v0")
assert.NoError(t, err)
@@ -163,7 +167,7 @@ func Test_upDevel(t *testing.T) {
SHA: "991c5b4146fd27f4aacf4e3111258a848934aaa1",
},
},
"hello-non-existant": {
"hello-non-existent": {
"github.com/Jguer/y.git": vcs.OriginInfo{
Protocols: []string{"https"},
Branch: "0",
@@ -263,7 +267,9 @@ func Test_upDevel(t *testing.T) {
},
}
for _, tt := range tests {
tt := tt
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
config.Runtime.CmdBuilder.(*exe.CmdBuilder).Runner.(*MockRunner).t = t
got := UpDevel(tt.args.remote, tt.args.aurdata, &tt.args.cached)
assert.ElementsMatch(t, tt.want.Up, got.Up)

View File

@@ -19,7 +19,7 @@ func StylizedNameWithRepository(u Upgrade) string {
return text.Bold(text.ColorHash(u.Repository)) + "/" + text.Bold(u.Name)
}
// upSlice is a slice of Upgrades
// upSlice is a slice of Upgrades.
type UpSlice struct {
Up []Upgrade
Repos []string
@@ -32,6 +32,7 @@ func (u UpSlice) Less(i, j int) bool {
if u.Up[i].Repository == u.Up[j].Repository {
iRunes := []rune(u.Up[i].Name)
jRunes := []rune(u.Up[j].Name)
return text.LessRunes(iRunes, jRunes)
}
@@ -45,6 +46,7 @@ func (u UpSlice) Less(i, j int) bool {
iRunes := []rune(u.Up[i].Repository)
jRunes := []rune(u.Up[j].Repository)
return text.LessRunes(iRunes, jRunes)
}
@@ -58,12 +60,14 @@ func GetVersionDiff(oldVersion, newVersion string) (left, right string) {
checkWords := func(str string, index int, words ...string) bool {
for _, word := range words {
wordLength := len(word)
nextIndex := index + 1
if (index < len(str)-wordLength) &&
(str[nextIndex:(nextIndex+wordLength)] == word) {
return true
}
}
return false
}
@@ -74,6 +78,7 @@ func GetVersionDiff(oldVersion, newVersion string) (left, right string) {
if charIsSpecial {
diffPosition = index
}
break
}
@@ -97,6 +102,7 @@ func GetVersionDiff(oldVersion, newVersion string) (left, right string) {
// Print prints the details of the packages to upgrade.
func (u UpSlice) Print() {
longestName, longestVersion := 0, 0
for _, pack := range u.Up {
packNameLen := len(StylizedNameWithRepository(pack))
packVersion, _ := GetVersionDiff(pack.LocalVersion, pack.RemoteVersion)

View File

@@ -7,6 +7,7 @@ import (
)
func TestGetVersionDiff(t *testing.T) {
t.Parallel()
text.UseColor = true
type versionPair struct {

View File

@@ -16,14 +16,14 @@ import (
)
// InfoStore is a collection of OriginInfoByURL by Package.
// Containing a map of last commit SHAs of a repo
// Containing a map of last commit SHAs of a repo.
type InfoStore struct {
OriginsByPackage map[string]OriginInfoByURL
FilePath string
CmdBuilder exe.GitCmdBuilder
}
// OriginInfoByURL stores the OriginInfo of each origin URL provided
// OriginInfoByURL stores the OriginInfo of each origin URL provided.
type OriginInfoByURL map[string]OriginInfo
// OriginInfo contains the last commit sha of a repo
@@ -34,7 +34,7 @@ type OriginInfoByURL map[string]OriginInfo
// ],
// "branch": "next",
// "sha": "c1171d41467c68ffd3c46748182a16366aaaf87b"
// }
// }.
type OriginInfo struct {
Protocols []string `json:"protocols"`
Branch string `json:"branch"`
@@ -51,12 +51,13 @@ func NewInfoStore(filePath string, cmdBuilder exe.GitCmdBuilder) *InfoStore {
return infoStore
}
// GetCommit parses HEAD commit from url and branch
// GetCommit parses HEAD commit from url and branch.
func (v *InfoStore) getCommit(url, branch string, protocols []string) string {
if len(protocols) > 0 {
protocol := protocols[len(protocols)-1]
cmd := v.CmdBuilder.BuildGitCmd("", "ls-remote", protocol+"://"+url, branch)
stdout, _, err := v.CmdBuilder.Capture(cmd, 5)
if err != nil {
if exiterr, ok := err.(*exec.ExitError); ok && exiterr.ExitCode() == 128 {
@@ -65,6 +66,7 @@ func (v *InfoStore) getCommit(url, branch string, protocols []string) string {
}
text.Warnln(err)
return ""
}
@@ -75,6 +77,7 @@ func (v *InfoStore) getCommit(url, branch string, protocols []string) string {
}
commit := split[0]
return commit
}
@@ -87,6 +90,7 @@ func (v *InfoStore) Update(pkgName string, sources []gosrc.ArchString, mux sync.
info := make(OriginInfoByURL)
checkSource := func(source gosrc.ArchString) {
defer wg.Done()
url, branch, protocols := parseSource(source.Value)
if url == "" || branch == "" {
return
@@ -105,6 +109,7 @@ func (v *InfoStore) Update(pkgName string, sources []gosrc.ArchString, mux sync.
}
v.OriginsByPackage[pkgName] = info
text.Warnln(gotext.Get("Found git repo: %s", text.Cyan(url)))
if err := v.Save(); err != nil {
@@ -115,11 +120,12 @@ func (v *InfoStore) Update(pkgName string, sources []gosrc.ArchString, mux sync.
for _, source := range sources {
wg.Add(1)
go checkSource(source)
}
}
// parseSource returns the git url, default branch and protocols it supports
// parseSource returns the git url, default branch and protocols it supports.
func parseSource(source string) (url, branch string, protocols []string) {
split := strings.Split(source, "::")
source = split[len(split)-1]
@@ -128,9 +134,11 @@ func parseSource(source string) (url, branch string, protocols []string) {
if len(split) != 2 {
return "", "", nil
}
protocols = strings.SplitN(split[0], "+", 2)
git := false
for _, protocol := range protocols {
if protocol == "git" {
git = true
@@ -197,6 +205,7 @@ func (v *InfoStore) NeedsUpdate(infos OriginInfoByURL) bool {
for url, info := range infos {
alive++
go checkHash(url, info)
}
@@ -218,26 +227,29 @@ func (v *InfoStore) Save() error {
if err != nil || string(marshalledinfo) == "null" {
return err
}
in, err := os.OpenFile(v.FilePath, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0o644)
if err != nil {
return err
}
defer in.Close()
_, err = in.Write(marshalledinfo)
if err != nil {
return err
if _, errM := in.Write(marshalledinfo); errM != nil {
return errM
}
err = in.Sync()
return err
return in.Sync()
}
// RemovePackage removes package from VCS information
// RemovePackage removes package from VCS information.
func (v *InfoStore) RemovePackage(pkgs []string) {
updated := false
for _, pkgName := range pkgs {
if _, ok := v.OriginsByPackage[pkgName]; ok {
delete(v.OriginsByPackage, pkgName)
updated = true
}
}
@@ -249,7 +261,7 @@ func (v *InfoStore) RemovePackage(pkgs []string) {
}
}
// LoadStore reads a json file and populates a InfoStore structure
// LoadStore reads a json file and populates a InfoStore structure.
func (v InfoStore) Load() error {
vfile, err := os.Open(v.FilePath)
if !os.IsNotExist(err) && err != nil {
@@ -257,6 +269,7 @@ func (v InfoStore) Load() error {
}
defer vfile.Close()
if !os.IsNotExist(err) {
decoder := json.NewDecoder(vfile)
if err = decoder.Decode(&v.OriginsByPackage); err != nil {

View File

@@ -18,6 +18,7 @@ import (
)
func TestParsing(t *testing.T) {
t.Parallel()
type source struct {
URL string
Branch string
@@ -53,6 +54,7 @@ func TestParsing(t *testing.T) {
}
func TestNewInfoStore(t *testing.T) {
t.Parallel()
type args struct {
filePath string
cmdBuilder *exe.CmdBuilder
@@ -70,7 +72,9 @@ func TestNewInfoStore(t *testing.T) {
},
}
for _, tt := range tests {
tt := tt
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
got := NewInfoStore(tt.args.filePath, tt.args.cmdBuilder)
assert.NotNil(t, got)
assert.Equal(t, []string{"--a", "--b"}, got.CmdBuilder.(*exe.CmdBuilder).GitFlags)
@@ -98,6 +102,7 @@ func (r *MockRunner) Capture(cmd *exec.Cmd, timeout int64) (stdout, stderr strin
}
func TestInfoStore_NeedsUpdate(t *testing.T) {
t.Parallel()
type fields struct {
CmdBuilder *exe.CmdBuilder
}
@@ -213,7 +218,9 @@ func TestInfoStore_NeedsUpdate(t *testing.T) {
},
}
for _, tt := range tests {
tt := tt
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
v := &InfoStore{
CmdBuilder: tt.fields.CmdBuilder,
}
@@ -224,6 +231,7 @@ func TestInfoStore_NeedsUpdate(t *testing.T) {
}
func TestInfoStore_Update(t *testing.T) {
t.Parallel()
type fields struct {
OriginsByPackage map[string]OriginInfoByURL
CmdBuilder *exe.CmdBuilder
@@ -258,7 +266,9 @@ func TestInfoStore_Update(t *testing.T) {
defer os.Remove(file.Name())
for _, tt := range tests {
tt := tt
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
v := &InfoStore{
OriginsByPackage: tt.fields.OriginsByPackage,
FilePath: file.Name(),
@@ -289,6 +299,7 @@ func TestInfoStore_Update(t *testing.T) {
}
func TestInfoStore_Remove(t *testing.T) {
t.Parallel()
type fields struct {
OriginsByPackage map[string]OriginInfoByURL
}
@@ -319,7 +330,9 @@ func TestInfoStore_Remove(t *testing.T) {
defer os.Remove(file.Name())
for _, tt := range tests {
tt := tt
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
v := &InfoStore{
OriginsByPackage: tt.fields.OriginsByPackage,
FilePath: file.Name(),

View File

@@ -17,10 +17,11 @@ import (
"github.com/Jguer/yay/v10/pkg/upgrade"
)
// PrintSearch handles printing search results in a given format
// PrintSearch handles printing search results in a given format.
func (q aurQuery) printSearch(start int, dbExecutor db.Executor) {
for i := range q {
var toprint string
if config.SearchMode == numberMenu {
switch config.SortMode {
case settings.TopDown:
@@ -55,6 +56,7 @@ func (q aurQuery) printSearch(start int, dbExecutor db.Executor) {
toprint += text.Bold(text.Green(gotext.Get("(Installed)")))
}
}
toprint += "\n " + q[i].Description
fmt.Println(toprint)
}
@@ -64,6 +66,7 @@ func (q aurQuery) printSearch(start int, dbExecutor db.Executor) {
func (s repoQuery) printSearch(dbExecutor db.Executor) {
for i, res := range s {
var toprint string
if config.SearchMode == numberMenu {
switch config.SortMode {
case settings.TopDown:
@@ -153,7 +156,6 @@ func biggestPackages(dbExecutor db.Executor) {
for i := 0; i < 10; i++ {
fmt.Printf("%s: %s\n", text.Bold(pkgS[i].Name()), text.Cyan(text.Human(pkgS[i].ISize())))
}
// Could implement size here as well, but we just want the general idea
}
// localStatistics prints installed packages statistics.
@@ -181,27 +183,28 @@ func localStatistics(dbExecutor db.Executor) error {
return nil
}
// TODO: Make it less hacky
func printNumberOfUpdates(dbExecutor db.Executor, enableDowngrade bool, filter upgrade.Filter) error {
warnings := query.NewWarnings()
old := os.Stdout // keep backup of the real stdout
os.Stdout = nil
aurUp, repoUp, err := upList(warnings, dbExecutor, enableDowngrade, filter)
os.Stdout = old // restoring the real stdout
if err != nil {
return err
}
fmt.Println(len(aurUp.Up) + len(repoUp.Up))
return nil
}
// TODO: Make it less hacky
func printUpdateList(cmdArgs *parser.Arguments, dbExecutor db.Executor, enableDowngrade bool, filter upgrade.Filter) error {
targets := stringset.FromSlice(cmdArgs.Targets)
warnings := query.NewWarnings()
old := os.Stdout // keep backup of the real stdout
os.Stdout = nil
localNames, remoteNames, err := query.GetPackageNamesBySource(dbExecutor)
if err != nil {
os.Stdout = old
@@ -210,6 +213,7 @@ func printUpdateList(cmdArgs *parser.Arguments, dbExecutor db.Executor, enableDo
aurUp, repoUp, err := upList(warnings, dbExecutor, enableDowngrade, filter)
os.Stdout = old // restoring the real stdout
if err != nil {
return err
}
@@ -224,6 +228,7 @@ func printUpdateList(cmdArgs *parser.Arguments, dbExecutor db.Executor, enableDo
} else {
fmt.Printf("%s %s -> %s\n", text.Bold(pkg.Name), text.Green(pkg.LocalVersion), text.Green(pkg.RemoteVersion))
}
delete(targets, pkg.Name)
}
}
@@ -237,6 +242,7 @@ func printUpdateList(cmdArgs *parser.Arguments, dbExecutor db.Executor, enableDo
} else {
fmt.Printf("%s %s -> %s\n", text.Bold(pkg.Name), text.Green(pkg.LocalVersion), text.Green(pkg.RemoteVersion))
}
delete(targets, pkg.Name)
}
}

View File

@@ -20,7 +20,7 @@ import (
"github.com/Jguer/yay/v10/pkg/text"
)
// Query is a collection of Results
// Query is a collection of Results.
type aurQuery []aur.Pkg
// Query holds the results of a repository search.
@@ -88,11 +88,13 @@ func getSearchBy(value string) aur.By {
}
}
// NarrowSearch searches AUR and narrows based on subarguments
// NarrowSearch searches AUR and narrows based on subarguments.
func narrowSearch(aurClient *aur.Client, pkgS []string, sortS bool) (aurQuery, error) {
var r []aur.Pkg
var err error
var usedIndex int
var (
r []aur.Pkg
err error
usedIndex int
)
by := getSearchBy(config.SearchBy)
@@ -104,6 +106,7 @@ func narrowSearch(aurClient *aur.Client, pkgS []string, sortS bool) (aurQuery, e
r, err = aurClient.Search(context.Background(), word, by)
if err == nil {
usedIndex = i
break
}
}
@@ -116,14 +119,18 @@ func narrowSearch(aurClient *aur.Client, pkgS []string, sortS bool) (aurQuery, e
if sortS {
sort.Sort(aurQuery(r))
}
return r, err
}
var aq aurQuery
var n int
var (
aq aurQuery
n int
)
for i := range r {
match := true
for j, pkgN := range pkgS {
if usedIndex == j {
continue
@@ -131,12 +138,14 @@ func narrowSearch(aurClient *aur.Client, pkgS []string, sortS bool) (aurQuery, e
if !(strings.Contains(r[i].Name, pkgN) || strings.Contains(strings.ToLower(r[i].Description), pkgN)) {
match = false
break
}
}
if match {
n++
aq = append(aq, r[i])
}
}
@@ -151,13 +160,17 @@ func narrowSearch(aurClient *aur.Client, pkgS []string, sortS bool) (aurQuery, e
// SyncSearch presents a query to the local repos and to the AUR.
func syncSearch(pkgS []string, aurClient *aur.Client, dbExecutor db.Executor) (err error) {
pkgS = query.RemoveInvalidTargets(pkgS, config.Runtime.Mode)
var aurErr error
var aq aurQuery
var pq repoQuery
var (
aurErr error
aq aurQuery
pq repoQuery
)
if config.Runtime.Mode.AtLeastAUR() {
aq, aurErr = narrowSearch(aurClient, pkgS, true)
}
if config.Runtime.Mode.AtLeastRepo() {
pq = queryRepo(pkgS, dbExecutor)
}
@@ -167,6 +180,7 @@ func syncSearch(pkgS []string, aurClient *aur.Client, dbExecutor db.Executor) (e
if config.Runtime.Mode.AtLeastRepo() {
pq.printSearch(dbExecutor)
}
if config.Runtime.Mode.AtLeastAUR() {
aq.printSearch(1, dbExecutor)
}
@@ -174,6 +188,7 @@ func syncSearch(pkgS []string, aurClient *aur.Client, dbExecutor db.Executor) (e
if config.Runtime.Mode.AtLeastAUR() {
aq.printSearch(1, dbExecutor)
}
if config.Runtime.Mode.AtLeastRepo() {
pq.printSearch(dbExecutor)
}
@@ -191,9 +206,12 @@ func syncSearch(pkgS []string, aurClient *aur.Client, dbExecutor db.Executor) (e
// SyncInfo serves as a pacman -Si for repo packages and AUR packages.
func syncInfo(cmdArgs *parser.Arguments, pkgS []string, dbExecutor db.Executor) error {
var info []*aur.Pkg
var err error
missing := false
var (
info []*aur.Pkg
err error
missing = false
)
pkgS = query.RemoveInvalidTargets(pkgS, config.Runtime.Mode)
aurS, repoS := packageSlices(pkgS, dbExecutor)
@@ -208,6 +226,7 @@ func syncInfo(cmdArgs *parser.Arguments, pkgS []string, dbExecutor db.Executor)
info, err = query.AURInfoPrint(config.Runtime.AURClient, noDB, config.RequestSplitN)
if err != nil {
missing = true
fmt.Fprintln(os.Stderr, err)
}
}
@@ -217,9 +236,9 @@ func syncInfo(cmdArgs *parser.Arguments, pkgS []string, dbExecutor db.Executor)
arguments := cmdArgs.Copy()
arguments.ClearTargets()
arguments.AddTarget(repoS...)
err = config.Runtime.CmdBuilder.Show(config.Runtime.CmdBuilder.BuildPacmanCmd(
cmdArgs, config.Runtime.Mode, settings.NoConfirm))
if err != nil {
return err
}
@@ -249,10 +268,11 @@ func queryRepo(pkgInputN []string, dbExecutor db.Executor) repoQuery {
if config.SortMode == settings.BottomUp {
s.Reverse()
}
return s
}
// PackageSlices separates an input slice into aur and repo slices
// PackageSlices separates an input slice into aur and repo slices.
func packageSlices(toCheck []string, dbExecutor db.Executor) (aurNames, repoNames []string) {
for _, _pkg := range toCheck {
dbName, name := text.SplitDBFromName(_pkg)
@@ -278,7 +298,7 @@ func packageSlices(toCheck []string, dbExecutor db.Executor) (aurNames, repoName
// HangingPackages returns a list of packages installed as deps
// and unneeded by the system
// removeOptional decides whether optional dependencies are counted or not
// removeOptional decides whether optional dependencies are counted or not.
func hangingPackages(removeOptional bool, dbExecutor db.Executor) (hanging []string) {
// safePackages represents every package in the system in one of 3 states
// State = 0 - Remove package from the system
@@ -306,6 +326,7 @@ func hangingPackages(removeOptional bool, dbExecutor db.Executor) (hanging []str
for iterateAgain {
iterateAgain = false
for _, pkg := range packages {
if state := safePackages[pkg.Name()]; state == 0 || state == 2 {
continue
@@ -313,6 +334,7 @@ func hangingPackages(removeOptional bool, dbExecutor db.Executor) (hanging []str
safePackages[pkg.Name()] = 2
deps := dbExecutor.PackageDepends(pkg)
if !removeOptional {
deps = append(deps, dbExecutor.PackageOptionalDepends(pkg)...)
}
@@ -331,6 +353,7 @@ func hangingPackages(removeOptional bool, dbExecutor db.Executor) (hanging []str
}
}
}
continue
}
@@ -352,20 +375,24 @@ func hangingPackages(removeOptional bool, dbExecutor db.Executor) (hanging []str
return hanging
}
// Statistics returns statistics about packages installed in system
// Statistics returns statistics about packages installed in system.
func statistics(dbExecutor db.Executor) *struct {
Totaln int
Expln int
TotalSize int64
} {
var totalSize int64
localPackages := dbExecutor.LocalPackages()
totalInstalls := 0
explicitInstalls := 0
var (
totalSize int64
localPackages = dbExecutor.LocalPackages()
totalInstalls = 0
explicitInstalls = 0
)
for _, pkg := range localPackages {
totalSize += pkg.ISize()
totalInstalls++
if pkg.Reason() == alpm.PkgReasonExplicit {
explicitInstalls++
}

View File

@@ -21,11 +21,13 @@ import (
func filterUpdateList(list []db.Upgrade, filter upgrade.Filter) []db.Upgrade {
tmp := list[:0]
for _, pkg := range list {
if filter(pkg) {
tmp = append(tmp, pkg)
}
}
return tmp
}
@@ -34,10 +36,12 @@ func upList(warnings *query.AURWarnings, dbExecutor db.Executor, enableDowngrade
filter upgrade.Filter) (aurUp, repoUp upgrade.UpSlice, err error) {
remote, remoteNames := query.GetRemotePackages(dbExecutor)
var wg sync.WaitGroup
var develUp upgrade.UpSlice
var repoSlice []db.Upgrade
var errs multierror.MultiError
var (
wg sync.WaitGroup
develUp upgrade.UpSlice
repoSlice []db.Upgrade
errs multierror.MultiError
)
aurdata := make(map[string]*aur.Pkg)
@@ -50,6 +54,7 @@ func upList(warnings *query.AURWarnings, dbExecutor db.Executor, enableDowngrade
if config.Runtime.Mode.AtLeastRepo() {
text.OperationInfoln(gotext.Get("Searching databases for updates..."))
wg.Add(1)
go func() {
repoSlice, err = dbExecutor.RepoUpgrades(enableDowngrade)
errs.Add(err)
@@ -63,22 +68,27 @@ func upList(warnings *query.AURWarnings, dbExecutor db.Executor, enableDowngrade
var _aurdata []*aur.Pkg
_aurdata, err = query.AURInfo(config.Runtime.AURClient, remoteNames, warnings, config.RequestSplitN)
errs.Add(err)
if err == nil {
for _, pkg := range _aurdata {
aurdata[pkg.Name] = pkg
}
wg.Add(1)
go func() {
aurUp = upgrade.UpAUR(remote, aurdata, config.TimeUpdate)
wg.Done()
}()
if config.Devel {
text.OperationInfoln(gotext.Get("Checking development packages..."))
wg.Add(1)
go func() {
develUp = upgrade.UpDevel(remote, aurdata, config.Runtime.VCSStore)
wg.Done()
}()
}
@@ -88,15 +98,19 @@ func upList(warnings *query.AURWarnings, dbExecutor db.Executor, enableDowngrade
wg.Wait()
printLocalNewerThanAUR(remote, aurdata)
names := make(stringset.StringSet)
for _, up := range develUp.Up {
names.Set(up.Name)
}
for _, up := range aurUp.Up {
if !names.Get(up.Name) {
develUp.Up = append(develUp.Up, up)
}
}
aurUp = develUp
aurUp.Repos = []string{"aur", "devel"}
@@ -104,6 +118,7 @@ func upList(warnings *query.AURWarnings, dbExecutor db.Executor, enableDowngrade
aurUp.Up = filterUpdateList(aurUp.Up, filter)
repoUp.Up = filterUpdateList(repoUp.Up, filter)
return aurUp, repoUp, errs.Return()
}
@@ -160,7 +175,9 @@ func upgradePkgsMenu(aurUp, repoUp upgrade.UpSlice) (stringset.StringSet, []stri
sort.Sort(repoUp)
sort.Sort(aurUp)
allUp := upgrade.UpSlice{Up: append(repoUp.Up, aurUp.Up...), Repos: append(repoUp.Repos, aurUp.Repos...)}
fmt.Printf("%s"+text.Bold(" %d ")+"%s\n", text.Bold(text.Cyan("::")), allUpLen, text.Bold(gotext.Get("Packages to upgrade.")))
allUp.Print()
@@ -212,9 +229,10 @@ func upgradePkgsMenu(aurUp, repoUp upgrade.UpSlice) (stringset.StringSet, []stri
return ignore, targets, err
}
// Targets for sys upgrade
// Targets for sys upgrade.
func sysupgradeTargets(dbExecutor db.Executor, enableDowngrade bool) (stringset.StringSet, []string, error) {
warnings := query.NewWarnings()
aurUp, repoUp, err := upList(warnings, dbExecutor, enableDowngrade, func(upgrade.Upgrade) bool { return true })
if err != nil {
return nil, nil, err
@@ -223,5 +241,6 @@ func sysupgradeTargets(dbExecutor db.Executor, enableDowngrade bool) (stringset.
warnings.Print()
ignore, targets, errUp := upgradePkgsMenu(aurUp, repoUp)
return ignore, targets, errUp
}

11
vcs.go
View File

@@ -15,10 +15,12 @@ import (
"github.com/Jguer/yay/v10/pkg/text"
)
// createDevelDB forces yay to create a DB of the existing development packages
// createDevelDB forces yay to create a DB of the existing development packages.
func createDevelDB(config *settings.Configuration, dbExecutor db.Executor) error {
var mux sync.Mutex
var wg sync.WaitGroup
var (
mux sync.Mutex
wg sync.WaitGroup
)
_, remoteNames, err := query.GetPackageNamesBySource(dbExecutor)
if err != nil {
@@ -34,6 +36,7 @@ func createDevelDB(config *settings.Configuration, dbExecutor db.Executor) error
toSkip := pkgbuildsToSkip(bases, stringset.FromSlice(remoteNames))
targets := make([]string, 0, len(bases))
for _, base := range bases {
if !toSkip.Get(base.Pkgbase()) {
targets = append(targets, base.Pkgbase())
@@ -60,11 +63,13 @@ func createDevelDB(config *settings.Configuration, dbExecutor db.Executor) error
for i := range srcinfos {
for iP := range srcinfos[i].Packages {
wg.Add(1)
go config.Runtime.VCSStore.Update(srcinfos[i].Packages[iP].Pkgname, srcinfos[i].Source, &mux, &wg)
}
}
wg.Wait()
text.OperationInfoln(gotext.Get("GenDB finished. No packages were installed"))
return err
}