Jelajahi Sumber

fix(parser): package parser

jguer 4 tahun lalu
induk
melakukan
fb5b6b74fe
15 mengubah file dengan 348 tambahan dan 342 penghapusan
  1. 8 7
      clean.go
  2. 51 51
      cmd.go
  3. 0 14
      config.go
  4. 4 3
      depPool.go
  5. 1 1
      download.go
  6. 7 6
      exec.go
  7. 80 79
      install.go
  8. 10 10
      main.go
  9. 44 43
      pkg/settings/config.go
  10. 104 105
      parser.go
  11. 14 0
      pkg/settings/runtime.go
  12. 7 7
      print.go
  13. 11 11
      query.go
  14. 4 3
      upgrade.go
  15. 3 2
      utils.go

+ 8 - 7
clean.go

@@ -9,6 +9,7 @@ import (
 	"github.com/leonelquinteros/gotext"
 
 	"github.com/Jguer/yay/v10/pkg/query"
+	"github.com/Jguer/yay/v10/pkg/settings"
 	"github.com/Jguer/yay/v10/pkg/stringset"
 	"github.com/Jguer/yay/v10/pkg/text"
 )
@@ -54,18 +55,18 @@ func cleanRemove(pkgNames []string) error {
 		return nil
 	}
 
-	arguments := cmdArgs.copyGlobal()
-	_ = arguments.addArg("R")
-	arguments.addTarget(pkgNames...)
+	arguments := cmdArgs.CopyGlobal()
+	_ = arguments.AddArg("R")
+	arguments.AddTarget(pkgNames...)
 
 	return show(passToPacman(arguments))
 }
 
-func syncClean(parser *arguments) error {
+func syncClean(parser *settings.Arguments) error {
 	keepInstalled := false
 	keepCurrent := false
 
-	_, removeAll, _ := parser.getArg("c", "clean")
+	_, removeAll, _ := parser.GetArg("c", "clean")
 
 	for _, v := range pacmanConf.CleanMethod {
 		if v == "KeepInstalled" {
@@ -75,13 +76,13 @@ func syncClean(parser *arguments) error {
 		}
 	}
 
-	if mode == modeRepo || mode == modeAny {
+	if config.Runtime.Mode == settings.ModeRepo || config.Runtime.Mode == settings.ModeAny {
 		if err := show(passToPacman(parser)); err != nil {
 			return err
 		}
 	}
 
-	if !(mode == modeAUR || mode == modeAny) {
+	if !(config.Runtime.Mode == settings.ModeAUR || config.Runtime.Mode == settings.ModeAny) {
 		return nil
 	}
 

+ 51 - 51
cmd.go

@@ -16,7 +16,7 @@ import (
 	"github.com/Jguer/yay/v10/pkg/text"
 )
 
-var cmdArgs = makeArguments()
+var cmdArgs = settings.MakeArguments()
 
 func usage() {
 	fmt.Println(`Usage:
@@ -140,15 +140,15 @@ getpkgbuild specific options:
 }
 
 func handleCmd() error {
-	if cmdArgs.existsArg("h", "help") {
+	if cmdArgs.ExistsArg("h", "help") {
 		return handleHelp()
 	}
 
-	if config.SudoLoop && cmdArgs.needRoot() {
+	if config.SudoLoop && cmdArgs.NeedRoot(&config.Runtime) {
 		sudoLoopBackground()
 	}
 
-	switch cmdArgs.op {
+	switch cmdArgs.Op {
 	case "V", "version":
 		handleVersion()
 		return nil
@@ -178,14 +178,14 @@ func handleCmd() error {
 }
 
 func handleQuery() error {
-	if cmdArgs.existsArg("u", "upgrades") {
+	if cmdArgs.ExistsArg("u", "upgrades") {
 		return printUpdateList(cmdArgs)
 	}
 	return show(passToPacman(cmdArgs))
 }
 
 func handleHelp() error {
-	if cmdArgs.op == "Y" || cmdArgs.op == "yay" {
+	if cmdArgs.Op == "Y" || cmdArgs.Op == "yay" {
 		usage()
 		return nil
 	}
@@ -198,25 +198,25 @@ func handleVersion() {
 
 func handlePrint() (err error) {
 	switch {
-	case cmdArgs.existsArg("d", "defaultconfig"):
+	case cmdArgs.ExistsArg("d", "defaultconfig"):
 		tmpConfig := defaultSettings()
 		tmpConfig.ExpandEnv()
 		fmt.Printf("%v", tmpConfig)
-	case cmdArgs.existsArg("g", "currentconfig"):
+	case cmdArgs.ExistsArg("g", "currentconfig"):
 		fmt.Printf("%v", config)
-	case cmdArgs.existsArg("n", "numberupgrades"):
+	case cmdArgs.ExistsArg("n", "numberupgrades"):
 		err = printNumberOfUpdates()
-	case cmdArgs.existsArg("u", "upgrades"):
+	case cmdArgs.ExistsArg("u", "upgrades"):
 		err = printUpdateList(cmdArgs)
-	case cmdArgs.existsArg("w", "news"):
-		_, double, _ := cmdArgs.getArg("news", "w")
-		quiet := cmdArgs.existsArg("q", "quiet")
+	case cmdArgs.ExistsArg("w", "news"):
+		double := cmdArgs.ExistsDouble("w", "news")
+		quiet := cmdArgs.ExistsArg("q", "quiet")
 		err = news.PrintNewsFeed(alpmHandle, config.SortMode, double, quiet)
-	case cmdArgs.existsDouble("c", "complete"):
+	case cmdArgs.ExistsDouble("c", "complete"):
 		err = completion.Show(alpmHandle, config.AURURL, cacheHome, config.CompletionInterval, true)
-	case cmdArgs.existsArg("c", "complete"):
+	case cmdArgs.ExistsArg("c", "complete"):
 		err = completion.Show(alpmHandle, config.AURURL, cacheHome, config.CompletionInterval, false)
-	case cmdArgs.existsArg("s", "stats"):
+	case cmdArgs.ExistsArg("s", "stats"):
 		err = localStatistics()
 	default:
 		err = nil
@@ -225,63 +225,63 @@ func handlePrint() (err error) {
 }
 
 func handleYay() error {
-	if cmdArgs.existsArg("gendb") {
+	if cmdArgs.ExistsArg("gendb") {
 		return createDevelDB()
 	}
-	if cmdArgs.existsDouble("c") {
+	if cmdArgs.ExistsDouble("c") {
 		return cleanDependencies(true)
 	}
-	if cmdArgs.existsArg("c", "clean") {
+	if cmdArgs.ExistsArg("c", "clean") {
 		return cleanDependencies(false)
 	}
-	if len(cmdArgs.targets) > 0 {
+	if len(cmdArgs.Targets) > 0 {
 		return handleYogurt()
 	}
 	return nil
 }
 
 func handleGetpkgbuild() error {
-	return getPkgbuilds(cmdArgs.targets)
+	return getPkgbuilds(cmdArgs.Targets)
 }
 
 func handleYogurt() error {
 	config.SearchMode = numberMenu
-	return displayNumberMenu(cmdArgs.targets)
+	return displayNumberMenu(cmdArgs.Targets)
 }
 
 func handleSync() error {
-	targets := cmdArgs.targets
+	targets := cmdArgs.Targets
 
-	if cmdArgs.existsArg("s", "search") {
-		if cmdArgs.existsArg("q", "quiet") {
+	if cmdArgs.ExistsArg("s", "search") {
+		if cmdArgs.ExistsArg("q", "quiet") {
 			config.SearchMode = minimal
 		} else {
 			config.SearchMode = detailed
 		}
 		return syncSearch(targets)
 	}
-	if cmdArgs.existsArg("p", "print", "print-format") {
+	if cmdArgs.ExistsArg("p", "print", "print-format") {
 		return show(passToPacman(cmdArgs))
 	}
-	if cmdArgs.existsArg("c", "clean") {
+	if cmdArgs.ExistsArg("c", "clean") {
 		return syncClean(cmdArgs)
 	}
-	if cmdArgs.existsArg("l", "list") {
+	if cmdArgs.ExistsArg("l", "list") {
 		return syncList(cmdArgs)
 	}
-	if cmdArgs.existsArg("g", "groups") {
+	if cmdArgs.ExistsArg("g", "groups") {
 		return show(passToPacman(cmdArgs))
 	}
-	if cmdArgs.existsArg("i", "info") {
+	if cmdArgs.ExistsArg("i", "info") {
 		return syncInfo(targets)
 	}
-	if cmdArgs.existsArg("u", "sysupgrade") {
+	if cmdArgs.ExistsArg("u", "sysupgrade") {
 		return install(cmdArgs)
 	}
-	if len(cmdArgs.targets) > 0 {
+	if len(cmdArgs.Targets) > 0 {
 		return install(cmdArgs)
 	}
-	if cmdArgs.existsArg("y", "refresh") {
+	if cmdArgs.ExistsArg("y", "refresh") {
 		return show(passToPacman(cmdArgs))
 	}
 	return nil
@@ -290,7 +290,7 @@ func handleSync() error {
 func handleRemove() error {
 	err := show(passToPacman(cmdArgs))
 	if err == nil {
-		removeVCSPackage(cmdArgs.targets)
+		removeVCSPackage(cmdArgs.Targets)
 	}
 
 	return err
@@ -307,11 +307,11 @@ func displayNumberMenu(pkgS []string) error {
 
 	pkgS = removeInvalidTargets(pkgS)
 
-	if mode == modeAUR || mode == modeAny {
+	if config.Runtime.Mode == settings.ModeAUR || config.Runtime.Mode == settings.ModeAny {
 		aq, aurErr = narrowSearch(pkgS, true)
 		lenaq = len(aq)
 	}
-	if mode == modeRepo || mode == modeAny {
+	if config.Runtime.Mode == settings.ModeRepo || config.Runtime.Mode == settings.ModeAny {
 		pq, repoErr = queryRepo(pkgS)
 		lenpq = len(pq)
 		if repoErr != nil {
@@ -325,17 +325,17 @@ func displayNumberMenu(pkgS []string) error {
 
 	switch config.SortMode {
 	case settings.TopDown:
-		if mode == modeRepo || mode == modeAny {
+		if config.Runtime.Mode == settings.ModeRepo || config.Runtime.Mode == settings.ModeAny {
 			pq.printSearch()
 		}
-		if mode == modeAUR || mode == modeAny {
+		if config.Runtime.Mode == settings.ModeAUR || config.Runtime.Mode == settings.ModeAny {
 			aq.printSearch(lenpq + 1)
 		}
 	case settings.BottomUp:
-		if mode == modeAUR || mode == modeAny {
+		if config.Runtime.Mode == settings.ModeAUR || config.Runtime.Mode == settings.ModeAny {
 			aq.printSearch(lenpq + 1)
 		}
-		if mode == modeRepo || mode == modeAny {
+		if config.Runtime.Mode == settings.ModeRepo || config.Runtime.Mode == settings.ModeAny {
 			pq.printSearch()
 		}
 	default:
@@ -361,7 +361,7 @@ func displayNumberMenu(pkgS []string) error {
 	}
 
 	include, exclude, _, otherExclude := intrange.ParseNumberMenu(string(numberBuf))
-	arguments := cmdArgs.copyGlobal()
+	arguments := cmdArgs.CopyGlobal()
 
 	isInclude := len(exclude) == 0 && len(otherExclude) == 0
 
@@ -377,7 +377,7 @@ func displayNumberMenu(pkgS []string) error {
 		}
 
 		if (isInclude && include.Get(target)) || (!isInclude && !exclude.Get(target)) {
-			arguments.addTarget(pkg.DB().Name() + "/" + pkg.Name())
+			arguments.AddTarget(pkg.DB().Name() + "/" + pkg.Name())
 		}
 	}
 
@@ -394,11 +394,11 @@ func displayNumberMenu(pkgS []string) error {
 		}
 
 		if (isInclude && include.Get(target)) || (!isInclude && !exclude.Get(target)) {
-			arguments.addTarget("aur/" + aq[i].Name)
+			arguments.AddTarget("aur/" + aq[i].Name)
 		}
 	}
 
-	if len(arguments.targets) == 0 {
+	if len(arguments.Targets) == 0 {
 		fmt.Println(gotext.Get(" there is nothing to do"))
 		return nil
 	}
@@ -410,17 +410,17 @@ func displayNumberMenu(pkgS []string) error {
 	return install(arguments)
 }
 
-func syncList(parser *arguments) error {
+func syncList(parser *settings.Arguments) error {
 	aur := false
 
-	for i := len(parser.targets) - 1; i >= 0; i-- {
-		if parser.targets[i] == "aur" && (mode == modeAny || mode == modeAUR) {
-			parser.targets = append(parser.targets[:i], parser.targets[i+1:]...)
+	for i := len(parser.Targets) - 1; i >= 0; i-- {
+		if parser.Targets[i] == "aur" && (config.Runtime.Mode == settings.ModeAny || config.Runtime.Mode == settings.ModeAUR) {
+			parser.Targets = append(parser.Targets[:i], parser.Targets[i+1:]...)
 			aur = true
 		}
 	}
 
-	if (mode == modeAny || mode == modeAUR) && (len(parser.targets) == 0 || aur) {
+	if (config.Runtime.Mode == settings.ModeAny || config.Runtime.Mode == settings.ModeAUR) && (len(parser.Targets) == 0 || aur) {
 		localDB, err := alpmHandle.LocalDB()
 		if err != nil {
 			return err
@@ -437,7 +437,7 @@ func syncList(parser *arguments) error {
 		scanner.Scan()
 		for scanner.Scan() {
 			name := scanner.Text()
-			if cmdArgs.existsArg("q", "quiet") {
+			if cmdArgs.ExistsArg("q", "quiet") {
 				fmt.Println(name)
 			} else {
 				fmt.Printf("%s %s %s", magenta("aur"), bold(name), bold(green(gotext.Get("unknown-version"))))
@@ -451,7 +451,7 @@ func syncList(parser *arguments) error {
 		}
 	}
 
-	if (mode == modeAny || mode == modeRepo) && (len(parser.targets) != 0 || !aur) {
+	if (config.Runtime.Mode == settings.ModeAny || config.Runtime.Mode == settings.ModeRepo) && (len(parser.Targets) != 0 || !aur) {
 		return show(passToPacman(parser))
 	}
 

+ 0 - 14
config.go

@@ -22,14 +22,6 @@ const (
 	minimal
 )
 
-const (
-	modeAUR targetMode = iota
-	modeRepo
-	modeAny
-)
-
-type targetMode int
-
 var yayVersion = "10.0.0"
 
 var localePath = "/usr/share/locale"
@@ -55,9 +47,6 @@ var configFile string
 // vcsfile holds yay vcs info file path.
 var vcsFile string
 
-// shouldSaveConfig holds whether or not the config should be saved
-var shouldSaveConfig bool
-
 // YayConf holds the current config values for yay.
 var config *settings.Configuration
 
@@ -67,9 +56,6 @@ var pacmanConf *pacmanconf.Config
 // AlpmHandle is the alpm handle used by yay.
 var alpmHandle *alpm.Handle
 
-// Mode is used to restrict yay to AUR or repo only modes
-var mode = modeAny
-
 var hideMenus = false
 
 func defaultSettings() *settings.Configuration {

+ 4 - 3
depPool.go

@@ -8,6 +8,7 @@ import (
 	alpm "github.com/Jguer/go-alpm"
 	rpc "github.com/mikkeloscar/aur"
 
+	"github.com/Jguer/yay/v10/pkg/settings"
 	"github.com/Jguer/yay/v10/pkg/stringset"
 )
 
@@ -105,7 +106,7 @@ func (dp *depPool) ResolveTargets(pkgs []string) error {
 		var singleDB *alpm.DB
 
 		// aur/ prefix means we only check the aur
-		if target.DB == "aur" || mode == modeAUR {
+		if target.DB == "aur" || config.Runtime.Mode == settings.ModeAUR {
 			dp.Targets = append(dp.Targets, target)
 			aurTargets.Set(target.DepString())
 			continue
@@ -155,7 +156,7 @@ func (dp *depPool) ResolveTargets(pkgs []string) error {
 		dp.Targets = append(dp.Targets, target)
 	}
 
-	if len(aurTargets) > 0 && (mode == modeAny || mode == modeAUR) {
+	if len(aurTargets) > 0 && (config.Runtime.Mode == settings.ModeAny || config.Runtime.Mode == settings.ModeAUR) {
 		return dp.resolveAURPackages(aurTargets, true)
 	}
 
@@ -396,7 +397,7 @@ func (dp *depPool) findSatisfierAurCache(dep string) *rpc.Pkg {
 		}
 	}
 
-	if cmdArgs.op == "Y" || cmdArgs.op == "yay" {
+	if cmdArgs.Op == "Y" || cmdArgs.Op == "yay" {
 		for _, pkg := range dp.AurCache {
 			if pkgSatisfies(pkg.Name, pkg.Version, dep) {
 				for _, target := range dp.Targets {

+ 1 - 1
download.go

@@ -264,7 +264,7 @@ func getPkgbuildsfromABS(pkgs []string, path string) (bool, error) {
 		case err != nil && !os.IsNotExist(err):
 			fmt.Fprintln(os.Stderr, bold(red(smallArrow)), err)
 			continue
-		case os.IsNotExist(err), cmdArgs.existsArg("f", "force"):
+		case os.IsNotExist(err), cmdArgs.ExistsArg("f", "force"):
 			if err = os.RemoveAll(filepath.Join(path, name)); err != nil {
 				fmt.Fprintln(os.Stderr, bold(red(smallArrow)), err)
 				continue

+ 7 - 6
exec.go

@@ -12,6 +12,7 @@ import (
 	"github.com/leonelquinteros/gotext"
 	"golang.org/x/crypto/ssh/terminal"
 
+	"github.com/Jguer/yay/v10/pkg/settings"
 	"github.com/Jguer/yay/v10/pkg/text"
 )
 
@@ -79,27 +80,27 @@ func waitLock() {
 	}
 }
 
-func passToPacman(args *arguments) *exec.Cmd {
+func passToPacman(args *settings.Arguments) *exec.Cmd {
 	argArr := make([]string, 0)
 
 	mSudoFlags := strings.Fields(config.SudoFlags)
 
-	if args.needRoot() {
+	if args.NeedRoot(&config.Runtime) {
 		argArr = append(argArr, config.SudoBin)
 		argArr = append(argArr, mSudoFlags...)
 	}
 
 	argArr = append(argArr, config.PacmanBin)
-	argArr = append(argArr, cmdArgs.formatGlobals()...)
-	argArr = append(argArr, args.formatArgs()...)
+	argArr = append(argArr, cmdArgs.FormatGlobals()...)
+	argArr = append(argArr, args.FormatArgs()...)
 	if config.NoConfirm {
 		argArr = append(argArr, "--noconfirm")
 	}
 
 	argArr = append(argArr, "--config", config.PacmanConf, "--")
-	argArr = append(argArr, args.targets...)
+	argArr = append(argArr, args.Targets...)
 
-	if args.needRoot() {
+	if args.NeedRoot(&config.Runtime) {
 		waitLock()
 	}
 	return exec.Command(argArr[0], argArr[1:]...)

+ 80 - 79
install.go

@@ -18,18 +18,19 @@ import (
 	"github.com/Jguer/yay/v10/pkg/intrange"
 	"github.com/Jguer/yay/v10/pkg/multierror"
 	"github.com/Jguer/yay/v10/pkg/query"
+	"github.com/Jguer/yay/v10/pkg/settings"
 	"github.com/Jguer/yay/v10/pkg/stringset"
 	"github.com/Jguer/yay/v10/pkg/text"
 )
 
-func asdeps(parser *arguments, pkgs []string) error {
+func asdeps(parser *settings.Arguments, pkgs []string) error {
 	if len(pkgs) == 0 {
 		return nil
 	}
 
-	parser = parser.copyGlobal()
-	_ = parser.addArg("D", "asdeps")
-	parser.addTarget(pkgs...)
+	parser = parser.CopyGlobal()
+	_ = parser.AddArg("D", "asdeps")
+	parser.AddTarget(pkgs...)
 	_, stderr, err := capture(passToPacman(parser))
 	if err != nil {
 		return fmt.Errorf("%s %s", stderr, err)
@@ -38,14 +39,14 @@ func asdeps(parser *arguments, pkgs []string) error {
 	return nil
 }
 
-func asexp(parser *arguments, pkgs []string) error {
+func asexp(parser *settings.Arguments, pkgs []string) error {
 	if len(pkgs) == 0 {
 		return nil
 	}
 
-	parser = parser.copyGlobal()
-	_ = parser.addArg("D", "asexplicit")
-	parser.addTarget(pkgs...)
+	parser = parser.CopyGlobal()
+	_ = parser.AddArg("D", "asexplicit")
+	parser.AddTarget(pkgs...)
 	_, stderr, err := capture(passToPacman(parser))
 	if err != nil {
 		return fmt.Errorf("%s %s", stderr, err)
@@ -55,7 +56,7 @@ func asexp(parser *arguments, pkgs []string) error {
 }
 
 // Install handles package installs
-func install(parser *arguments) (err error) {
+func install(parser *settings.Arguments) (err error) {
 	var incompatible stringset.StringSet
 	var do *depOrder
 
@@ -66,15 +67,15 @@ func install(parser *arguments) (err error) {
 
 	warnings := makeWarnings()
 
-	if mode == modeAny || mode == modeRepo {
+	if config.Runtime.Mode == settings.ModeAny || config.Runtime.Mode == settings.ModeRepo {
 		if config.CombinedUpgrade {
-			if parser.existsArg("y", "refresh") {
+			if parser.ExistsArg("y", "refresh") {
 				err = earlyRefresh(parser)
 				if err != nil {
 					return fmt.Errorf(gotext.Get("error refreshing databases"))
 				}
 			}
-		} else if parser.existsArg("y", "refresh") || parser.existsArg("u", "sysupgrade") || len(parser.targets) > 0 {
+		} else if parser.ExistsArg("y", "refresh") || parser.ExistsArg("u", "sysupgrade") || len(parser.Targets) > 0 {
 			err = earlyPacmanCall(parser)
 			if err != nil {
 				return err
@@ -97,21 +98,21 @@ func install(parser *arguments) (err error) {
 	remoteNamesCache := stringset.FromSlice(remoteNames)
 	localNamesCache := stringset.FromSlice(localNames)
 
-	requestTargets := parser.copy().targets
+	requestTargets := parser.Copy().Targets
 
 	// create the arguments to pass for the repo install
-	arguments := parser.copy()
-	arguments.delArg("asdeps", "asdep")
-	arguments.delArg("asexplicit", "asexp")
-	arguments.op = "S"
-	arguments.clearTargets()
+	arguments := parser.Copy()
+	arguments.DelArg("asdeps", "asdep")
+	arguments.DelArg("asexplicit", "asexp")
+	arguments.Op = "S"
+	arguments.ClearTargets()
 
-	if mode == modeAUR {
-		arguments.delArg("u", "sysupgrade")
+	if config.Runtime.Mode == settings.ModeAUR {
+		arguments.DelArg("u", "sysupgrade")
 	}
 
 	// if we are doing -u also request all packages needing update
-	if parser.existsArg("u", "sysupgrade") {
+	if parser.ExistsArg("u", "sysupgrade") {
 		aurUp, repoUp, err = upList(warnings)
 		if err != nil {
 			return err
@@ -127,27 +128,27 @@ func install(parser *arguments) (err error) {
 		for _, up := range repoUp {
 			if !ignore.Get(up.Name) {
 				requestTargets = append(requestTargets, up.Name)
-				parser.addTarget(up.Name)
+				parser.AddTarget(up.Name)
 			}
 		}
 
 		for up := range aurUp {
 			requestTargets = append(requestTargets, "aur/"+up)
-			parser.addTarget("aur/" + up)
+			parser.AddTarget("aur/" + up)
 		}
 
-		value, _, exists := cmdArgs.getArg("ignore")
+		value, _, exists := cmdArgs.GetArg("ignore")
 
 		if len(ignore) > 0 {
 			ignoreStr := strings.Join(ignore.ToSlice(), ",")
 			if exists {
 				ignoreStr += "," + value
 			}
-			arguments.options["ignore"] = ignoreStr
+			arguments.Options["ignore"] = ignoreStr
 		}
 	}
 
-	targets := stringset.FromSlice(parser.targets)
+	targets := stringset.FromSlice(parser.Targets)
 
 	dp, err := getDepPool(requestTargets, warnings)
 	if err != nil {
@@ -161,15 +162,15 @@ func install(parser *arguments) (err error) {
 
 	if len(dp.Aur) == 0 {
 		if !config.CombinedUpgrade {
-			if parser.existsArg("u", "sysupgrade") {
+			if parser.ExistsArg("u", "sysupgrade") {
 				fmt.Println(gotext.Get(" there is nothing to do"))
 			}
 			return nil
 		}
 
-		parser.op = "S"
-		parser.delArg("y", "refresh")
-		parser.options["ignore"] = arguments.options["ignore"]
+		parser.Op = "S"
+		parser.DelArg("y", "refresh")
+		parser.Options["ignore"] = arguments.Options["ignore"]
 		return show(passToPacman(parser))
 	}
 
@@ -188,14 +189,14 @@ func install(parser *arguments) (err error) {
 	}
 
 	for _, pkg := range do.Repo {
-		arguments.addTarget(pkg.DB().Name() + "/" + pkg.Name())
+		arguments.AddTarget(pkg.DB().Name() + "/" + pkg.Name())
 	}
 
 	for _, pkg := range dp.Groups {
-		arguments.addTarget(pkg)
+		arguments.AddTarget(pkg)
 	}
 
-	if len(do.Aur) == 0 && len(arguments.targets) == 0 && (!parser.existsArg("u", "sysupgrade") || mode == modeAUR) {
+	if len(do.Aur) == 0 && len(arguments.Targets) == 0 && (!parser.ExistsArg("u", "sysupgrade") || config.Runtime.Mode == settings.ModeAUR) {
 		fmt.Println(gotext.Get(" there is nothing to do"))
 		return nil
 	}
@@ -324,10 +325,10 @@ func install(parser *arguments) (err error) {
 	}
 
 	if !config.CombinedUpgrade {
-		arguments.delArg("u", "sysupgrade")
+		arguments.DelArg("u", "sysupgrade")
 	}
 
-	if len(arguments.targets) > 0 || arguments.existsArg("u") {
+	if len(arguments.Targets) > 0 || arguments.ExistsArg("u") {
 		if errShow := show(passToPacman(arguments)); errShow != nil {
 			return errors.New(gotext.Get("error installing repo packages"))
 		}
@@ -341,9 +342,9 @@ func install(parser *arguments) (err error) {
 				continue
 			}
 
-			if parser.existsArg("asdeps", "asdep") && dp.Explicit.Get(pkg.Name()) {
+			if parser.ExistsArg("asdeps", "asdep") && dp.Explicit.Get(pkg.Name()) {
 				deps = append(deps, pkg.Name())
-			} else if parser.existsArg("asexp", "asexplicit") && dp.Explicit.Get(pkg.Name()) {
+			} else if parser.ExistsArg("asexp", "asexplicit") && dp.Explicit.Get(pkg.Name()) {
 				exp = append(exp, pkg.Name())
 			}
 		}
@@ -372,14 +373,14 @@ func install(parser *arguments) (err error) {
 }
 
 func removeMake(do *depOrder) error {
-	removeArguments := makeArguments()
-	err := removeArguments.addArg("R", "u")
+	removeArguments := settings.MakeArguments()
+	err := removeArguments.AddArg("R", "u")
 	if err != nil {
 		return err
 	}
 
 	for _, pkg := range do.getMake() {
-		removeArguments.addTarget(pkg)
+		removeArguments.AddTarget(pkg)
 	}
 
 	oldValue := config.NoConfirm
@@ -410,32 +411,32 @@ func inRepos(syncDB alpm.DBList, pkg string) bool {
 	return !syncDB.FindGroupPkgs(target.Name).Empty()
 }
 
-func earlyPacmanCall(parser *arguments) error {
-	arguments := parser.copy()
-	arguments.op = "S"
-	targets := parser.targets
-	parser.clearTargets()
-	arguments.clearTargets()
+func earlyPacmanCall(parser *settings.Arguments) error {
+	arguments := parser.Copy()
+	arguments.Op = "S"
+	targets := parser.Targets
+	parser.ClearTargets()
+	arguments.ClearTargets()
 
 	syncDB, err := alpmHandle.SyncDBs()
 	if err != nil {
 		return err
 	}
 
-	if mode == modeRepo {
-		arguments.targets = targets
+	if config.Runtime.Mode == settings.ModeRepo {
+		arguments.Targets = targets
 	} else {
 		// separate aur and repo targets
 		for _, target := range targets {
 			if inRepos(syncDB, target) {
-				arguments.addTarget(target)
+				arguments.AddTarget(target)
 			} else {
-				parser.addTarget(target)
+				parser.AddTarget(target)
 			}
 		}
 	}
 
-	if parser.existsArg("y", "refresh") || parser.existsArg("u", "sysupgrade") || len(arguments.targets) > 0 {
+	if parser.ExistsArg("y", "refresh") || parser.ExistsArg("u", "sysupgrade") || len(arguments.Targets) > 0 {
 		err = show(passToPacman(arguments))
 		if err != nil {
 			return errors.New(gotext.Get("error installing repo packages"))
@@ -445,14 +446,14 @@ func earlyPacmanCall(parser *arguments) error {
 	return nil
 }
 
-func earlyRefresh(parser *arguments) error {
-	arguments := parser.copy()
-	parser.delArg("y", "refresh")
-	arguments.delArg("u", "sysupgrade")
-	arguments.delArg("s", "search")
-	arguments.delArg("i", "info")
-	arguments.delArg("l", "list")
-	arguments.clearTargets()
+func earlyRefresh(parser *settings.Arguments) error {
+	arguments := parser.Copy()
+	parser.DelArg("y", "refresh")
+	arguments.DelArg("u", "sysupgrade")
+	arguments.DelArg("s", "search")
+	arguments.DelArg("i", "info")
+	arguments.DelArg("l", "list")
+	arguments.ClearTargets()
 	return show(passToPacman(arguments))
 }
 
@@ -931,20 +932,20 @@ func buildInstallPkgbuilds(
 	dp *depPool,
 	do *depOrder,
 	srcinfos map[string]*gosrc.Srcinfo,
-	parser *arguments,
+	parser *settings.Arguments,
 	incompatible stringset.StringSet,
 	conflicts stringset.MapStringSet) error {
-	arguments := parser.copy()
-	arguments.clearTargets()
-	arguments.op = "U"
-	arguments.delArg("confirm")
-	arguments.delArg("noconfirm")
-	arguments.delArg("c", "clean")
-	arguments.delArg("q", "quiet")
-	arguments.delArg("q", "quiet")
-	arguments.delArg("y", "refresh")
-	arguments.delArg("u", "sysupgrade")
-	arguments.delArg("w", "downloadonly")
+	arguments := parser.Copy()
+	arguments.ClearTargets()
+	arguments.Op = "U"
+	arguments.DelArg("confirm")
+	arguments.DelArg("noconfirm")
+	arguments.DelArg("c", "clean")
+	arguments.DelArg("q", "quiet")
+	arguments.DelArg("q", "quiet")
+	arguments.DelArg("y", "refresh")
+	arguments.DelArg("u", "sysupgrade")
+	arguments.DelArg("w", "downloadonly")
 
 	deps := make([]string, 0)
 	exp := make([]string, 0)
@@ -963,7 +964,7 @@ func buildInstallPkgbuilds(
 	localNamesCache := stringset.FromSlice(localNames)
 
 	doInstall := func() error {
-		if len(arguments.targets) == 0 {
+		if len(arguments.Targets) == 0 {
 			return nil
 		}
 
@@ -985,7 +986,7 @@ func buildInstallPkgbuilds(
 
 		config.NoConfirm = oldConfirm
 
-		arguments.clearTargets()
+		arguments.ClearTargets()
 		deps = make([]string, 0)
 		exp = make([]string, 0)
 		config.NoConfirm = true
@@ -1057,7 +1058,7 @@ func buildInstallPkgbuilds(
 			built = false
 		}
 
-		if cmdArgs.existsArg("needed") {
+		if cmdArgs.ExistsArg("needed") {
 			installed := true
 			for _, split := range base {
 				if alpmpkg := dp.LocalDB.Pkg(split.Name); alpmpkg == nil || alpmpkg.Version() != pkgVersion {
@@ -1097,9 +1098,9 @@ func buildInstallPkgbuilds(
 
 		// conflicts have been checked so answer y for them
 		if config.UseAsk {
-			ask, _ := strconv.Atoi(cmdArgs.globals["ask"])
+			ask, _ := strconv.Atoi(cmdArgs.Globals["ask"])
 			uask := alpm.QuestionType(ask) | alpm.QuestionTypeConflictPkg
-			cmdArgs.globals["ask"] = fmt.Sprint(uask)
+			cmdArgs.Globals["ask"] = fmt.Sprint(uask)
 		} else {
 			for _, split := range base {
 				if _, ok := conflicts[split.Name]; ok {
@@ -1130,10 +1131,10 @@ func buildInstallPkgbuilds(
 						name, pkgdest))
 			}
 
-			arguments.addTarget(pkgdest)
-			if parser.existsArg("asdeps", "asdep") {
+			arguments.AddTarget(pkgdest)
+			if parser.ExistsArg("asdeps", "asdep") {
 				deps = append(deps, name)
-			} else if parser.existsArg("asexplicit", "asexp") {
+			} else if parser.ExistsArg("asexplicit", "asexp") {
 				exp = append(exp, name)
 			} else if !dp.Explicit.Get(name) && !localNamesCache.Get(name) && !remoteNamesCache.Get(name) {
 				deps = append(deps, name)

+ 10 - 10
main.go

@@ -122,7 +122,7 @@ func initAlpm(pacmanConfigPath string) error {
 	var stderr string
 
 	root := "/"
-	if value, _, exists := cmdArgs.getArg("root", "r"); exists {
+	if value, _, exists := cmdArgs.GetArg("root", "r"); exists {
 		root = value
 	}
 
@@ -131,19 +131,19 @@ func initAlpm(pacmanConfigPath string) error {
 		return fmt.Errorf("%s", stderr)
 	}
 
-	if value, _, exists := cmdArgs.getArg("dbpath", "b"); exists {
+	if value, _, exists := cmdArgs.GetArg("dbpath", "b"); exists {
 		pacmanConf.DBPath = value
 	}
 
-	if value, _, exists := cmdArgs.getArg("arch"); exists {
+	if value, _, exists := cmdArgs.GetArg("arch"); exists {
 		pacmanConf.Architecture = value
 	}
 
-	if value, _, exists := cmdArgs.getArg("ignore"); exists {
+	if value, _, exists := cmdArgs.GetArg("ignore"); exists {
 		pacmanConf.IgnorePkg = append(pacmanConf.IgnorePkg, strings.Split(value, ",")...)
 	}
 
-	if value, _, exists := cmdArgs.getArg("ignoregroup"); exists {
+	if value, _, exists := cmdArgs.GetArg("ignoregroup"); exists {
 		pacmanConf.IgnoreGroup = append(pacmanConf.IgnoreGroup, strings.Split(value, ",")...)
 	}
 
@@ -151,11 +151,11 @@ func initAlpm(pacmanConfigPath string) error {
 	// current system does not allow duplicate arguments
 	// but pacman allows multiple cachedirs to be passed
 	// for now only handle one cache dir
-	if value, _, exists := cmdArgs.getArg("cachedir"); exists {
+	if value, _, exists := cmdArgs.GetArg("cachedir"); exists {
 		pacmanConf.CacheDir = []string{value}
 	}
 
-	if value, _, exists := cmdArgs.getArg("gpgdir"); exists {
+	if value, _, exists := cmdArgs.GetArg("gpgdir"); exists {
 		pacmanConf.GPGDir = value
 	}
 
@@ -163,7 +163,7 @@ func initAlpm(pacmanConfigPath string) error {
 		return err
 	}
 
-	switch value, _, _ := cmdArgs.getArg("color"); value {
+	switch value, _, _ := cmdArgs.GetArg("color"); value {
 	case "always":
 		text.UseColor = true
 	case "auto":
@@ -229,8 +229,8 @@ func main() {
 	config = defaultSettings()
 	exitOnError(initHomeDirs())
 	exitOnError(initConfig())
-	exitOnError(cmdArgs.parseCommandLine())
-	if shouldSaveConfig {
+	exitOnError(cmdArgs.ParseCommandLine(config))
+	if config.Runtime.SaveConfig {
 		err := config.SaveConfig(configFile)
 		if err != nil {
 			fmt.Fprintln(os.Stderr, err)

+ 44 - 43
pkg/settings/config.go

@@ -15,49 +15,50 @@ const (
 
 // Configuration stores yay's config.
 type Configuration struct {
-	AURURL             string `json:"aururl"`
-	BuildDir           string `json:"buildDir"`
-	ABSDir             string `json:"absdir"`
-	Editor             string `json:"editor"`
-	EditorFlags        string `json:"editorflags"`
-	MakepkgBin         string `json:"makepkgbin"`
-	MakepkgConf        string `json:"makepkgconf"`
-	PacmanBin          string `json:"pacmanbin"`
-	PacmanConf         string `json:"pacmanconf"`
-	ReDownload         string `json:"redownload"`
-	ReBuild            string `json:"rebuild"`
-	AnswerClean        string `json:"answerclean"`
-	AnswerDiff         string `json:"answerdiff"`
-	AnswerEdit         string `json:"answeredit"`
-	AnswerUpgrade      string `json:"answerupgrade"`
-	GitBin             string `json:"gitbin"`
-	GpgBin             string `json:"gpgbin"`
-	GpgFlags           string `json:"gpgflags"`
-	MFlags             string `json:"mflags"`
-	SortBy             string `json:"sortby"`
-	SearchBy           string `json:"searchby"`
-	GitFlags           string `json:"gitflags"`
-	RemoveMake         string `json:"removemake"`
-	SudoBin            string `json:"sudobin"`
-	SudoFlags          string `json:"sudoflags"`
-	RequestSplitN      int    `json:"requestsplitn"`
-	SearchMode         int    `json:"-"`
-	SortMode           int    `json:"sortmode"`
-	CompletionInterval int    `json:"completionrefreshtime"`
-	SudoLoop           bool   `json:"sudoloop"`
-	TimeUpdate         bool   `json:"timeupdate"`
-	NoConfirm          bool   `json:"-"`
-	Devel              bool   `json:"devel"`
-	CleanAfter         bool   `json:"cleanAfter"`
-	Provides           bool   `json:"provides"`
-	PGPFetch           bool   `json:"pgpfetch"`
-	UpgradeMenu        bool   `json:"upgrademenu"`
-	CleanMenu          bool   `json:"cleanmenu"`
-	DiffMenu           bool   `json:"diffmenu"`
-	EditMenu           bool   `json:"editmenu"`
-	CombinedUpgrade    bool   `json:"combinedupgrade"`
-	UseAsk             bool   `json:"useask"`
-	BatchInstall       bool   `json:"batchinstall"`
+	AURURL             string  `json:"aururl"`
+	BuildDir           string  `json:"buildDir"`
+	ABSDir             string  `json:"absdir"`
+	Editor             string  `json:"editor"`
+	EditorFlags        string  `json:"editorflags"`
+	MakepkgBin         string  `json:"makepkgbin"`
+	MakepkgConf        string  `json:"makepkgconf"`
+	PacmanBin          string  `json:"pacmanbin"`
+	PacmanConf         string  `json:"pacmanconf"`
+	ReDownload         string  `json:"redownload"`
+	ReBuild            string  `json:"rebuild"`
+	AnswerClean        string  `json:"answerclean"`
+	AnswerDiff         string  `json:"answerdiff"`
+	AnswerEdit         string  `json:"answeredit"`
+	AnswerUpgrade      string  `json:"answerupgrade"`
+	GitBin             string  `json:"gitbin"`
+	GpgBin             string  `json:"gpgbin"`
+	GpgFlags           string  `json:"gpgflags"`
+	MFlags             string  `json:"mflags"`
+	SortBy             string  `json:"sortby"`
+	SearchBy           string  `json:"searchby"`
+	GitFlags           string  `json:"gitflags"`
+	RemoveMake         string  `json:"removemake"`
+	SudoBin            string  `json:"sudobin"`
+	SudoFlags          string  `json:"sudoflags"`
+	RequestSplitN      int     `json:"requestsplitn"`
+	SearchMode         int     `json:"-"`
+	SortMode           int     `json:"sortmode"`
+	CompletionInterval int     `json:"completionrefreshtime"`
+	SudoLoop           bool    `json:"sudoloop"`
+	TimeUpdate         bool    `json:"timeupdate"`
+	NoConfirm          bool    `json:"-"`
+	Devel              bool    `json:"devel"`
+	CleanAfter         bool    `json:"cleanAfter"`
+	Provides           bool    `json:"provides"`
+	PGPFetch           bool    `json:"pgpfetch"`
+	UpgradeMenu        bool    `json:"upgrademenu"`
+	CleanMenu          bool    `json:"cleanmenu"`
+	DiffMenu           bool    `json:"diffmenu"`
+	EditMenu           bool    `json:"editmenu"`
+	CombinedUpgrade    bool    `json:"combinedupgrade"`
+	UseAsk             bool    `json:"useask"`
+	BatchInstall       bool    `json:"batchinstall"`
+	Runtime            Runtime `json:"-"`
 }
 
 // SaveConfig writes yay config to file.

+ 104 - 105
parser.go

@@ -1,4 +1,4 @@
-package main
+package settings
 
 import (
 	"bufio"
@@ -10,22 +10,21 @@ import (
 	rpc "github.com/mikkeloscar/aur"
 	"github.com/pkg/errors"
 
-	"github.com/Jguer/yay/v10/pkg/settings"
 	"github.com/Jguer/yay/v10/pkg/stringset"
 )
 
-// Parses command line arguments in a way we can interact with programmatically but
+// Arguments Parses command line arguments in a way we can interact with programmatically but
 // also in a way that can easily be passed to pacman later on.
-type arguments struct {
-	op      string
-	options map[string]string
-	globals map[string]string
-	doubles stringset.StringSet // Tracks args passed twice such as -yy and -dd
-	targets []string
+type Arguments struct {
+	Op      string
+	Options map[string]string
+	Globals map[string]string
+	Doubles stringset.StringSet // Tracks args passed twice such as -yy and -dd
+	Targets []string
 }
 
-func makeArguments() *arguments {
-	return &arguments{
+func MakeArguments() *Arguments {
+	return &Arguments{
 		"",
 		make(map[string]string),
 		make(map[string]string),
@@ -34,92 +33,92 @@ func makeArguments() *arguments {
 	}
 }
 
-func (parser *arguments) copyGlobal() (cp *arguments) {
-	cp = makeArguments()
-	for k, v := range parser.globals {
-		cp.globals[k] = v
+func (parser *Arguments) CopyGlobal() (cp *Arguments) {
+	cp = MakeArguments()
+	for k, v := range parser.Globals {
+		cp.Globals[k] = v
 	}
 
 	return
 }
 
-func (parser *arguments) copy() (cp *arguments) {
-	cp = makeArguments()
+func (parser *Arguments) Copy() (cp *Arguments) {
+	cp = MakeArguments()
 
-	cp.op = parser.op
+	cp.Op = parser.Op
 
-	for k, v := range parser.options {
-		cp.options[k] = v
+	for k, v := range parser.Options {
+		cp.Options[k] = v
 	}
 
-	for k, v := range parser.globals {
-		cp.globals[k] = v
+	for k, v := range parser.Globals {
+		cp.Globals[k] = v
 	}
 
-	cp.targets = make([]string, len(parser.targets))
-	copy(cp.targets, parser.targets)
+	cp.Targets = make([]string, len(parser.Targets))
+	copy(cp.Targets, parser.Targets)
 
-	for k, v := range parser.doubles {
-		cp.doubles[k] = v
+	for k, v := range parser.Doubles {
+		cp.Doubles[k] = v
 	}
 
 	return
 }
 
-func (parser *arguments) delArg(options ...string) {
+func (parser *Arguments) DelArg(options ...string) {
 	for _, option := range options {
-		delete(parser.options, option)
-		delete(parser.globals, option)
-		delete(parser.doubles, option)
+		delete(parser.Options, option)
+		delete(parser.Globals, option)
+		delete(parser.Doubles, option)
 	}
 }
 
-func (parser *arguments) needRoot() bool {
-	if parser.existsArg("h", "help") {
+func (parser *Arguments) NeedRoot(runtime *Runtime) bool {
+	if parser.ExistsArg("h", "help") {
 		return false
 	}
 
-	switch parser.op {
+	switch parser.Op {
 	case "D", "database":
-		if parser.existsArg("k", "check") {
+		if parser.ExistsArg("k", "check") {
 			return false
 		}
 		return true
 	case "F", "files":
-		if parser.existsArg("y", "refresh") {
+		if parser.ExistsArg("y", "refresh") {
 			return true
 		}
 		return false
 	case "Q", "query":
-		if parser.existsArg("k", "check") {
+		if parser.ExistsArg("k", "check") {
 			return true
 		}
 		return false
 	case "R", "remove":
-		if parser.existsArg("p", "print", "print-format") {
+		if parser.ExistsArg("p", "print", "print-format") {
 			return false
 		}
 		return true
 	case "S", "sync":
-		if parser.existsArg("y", "refresh") {
+		if parser.ExistsArg("y", "refresh") {
 			return true
 		}
-		if parser.existsArg("p", "print", "print-format") {
+		if parser.ExistsArg("p", "print", "print-format") {
 			return false
 		}
-		if parser.existsArg("s", "search") {
+		if parser.ExistsArg("s", "search") {
 			return false
 		}
-		if parser.existsArg("l", "list") {
+		if parser.ExistsArg("l", "list") {
 			return false
 		}
-		if parser.existsArg("g", "groups") {
+		if parser.ExistsArg("g", "groups") {
 			return false
 		}
-		if parser.existsArg("i", "info") {
+		if parser.ExistsArg("i", "info") {
 			return false
 		}
-		if parser.existsArg("c", "clean") && mode == modeAUR {
+		if parser.ExistsArg("c", "clean") && runtime.Mode == ModeAUR {
 			return false
 		}
 		return true
@@ -130,17 +129,17 @@ func (parser *arguments) needRoot() bool {
 	}
 }
 
-func (parser *arguments) addOP(op string) (err error) {
-	if parser.op != "" {
+func (parser *Arguments) addOP(op string) (err error) {
+	if parser.Op != "" {
 		err = errors.New(gotext.Get("only one operation may be used at a time"))
 		return
 	}
 
-	parser.op = op
+	parser.Op = op
 	return
 }
 
-func (parser *arguments) addParam(option, arg string) (err error) {
+func (parser *Arguments) addParam(option, arg string) (err error) {
 	if !isArg(option) {
 		return errors.New(gotext.Get("invalid option '%s'", option))
 	}
@@ -151,18 +150,18 @@ func (parser *arguments) addParam(option, arg string) (err error) {
 	}
 
 	switch {
-	case parser.existsArg(option):
-		parser.doubles[option] = struct{}{}
+	case parser.ExistsArg(option):
+		parser.Doubles[option] = struct{}{}
 	case isGlobal(option):
-		parser.globals[option] = arg
+		parser.Globals[option] = arg
 	default:
-		parser.options[option] = arg
+		parser.Options[option] = arg
 	}
 
 	return
 }
 
-func (parser *arguments) addArg(options ...string) (err error) {
+func (parser *Arguments) AddArg(options ...string) (err error) {
 	for _, option := range options {
 		err = parser.addParam(option, "")
 		if err != nil {
@@ -174,14 +173,14 @@ func (parser *arguments) addArg(options ...string) (err error) {
 }
 
 // Multiple args acts as an OR operator
-func (parser *arguments) existsArg(options ...string) bool {
+func (parser *Arguments) ExistsArg(options ...string) bool {
 	for _, option := range options {
-		_, exists := parser.options[option]
+		_, exists := parser.Options[option]
 		if exists {
 			return true
 		}
 
-		_, exists = parser.globals[option]
+		_, exists = parser.Globals[option]
 		if exists {
 			return true
 		}
@@ -189,30 +188,30 @@ func (parser *arguments) existsArg(options ...string) bool {
 	return false
 }
 
-func (parser *arguments) getArg(options ...string) (arg string, double, exists bool) {
+func (parser *Arguments) GetArg(options ...string) (arg string, double, exists bool) {
 	existCount := 0
 
 	for _, option := range options {
 		var value string
 
-		value, exists = parser.options[option]
+		value, exists = parser.Options[option]
 
 		if exists {
 			arg = value
 			existCount++
-			_, exists = parser.doubles[option]
+			_, exists = parser.Doubles[option]
 
 			if exists {
 				existCount++
 			}
 		}
 
-		value, exists = parser.globals[option]
+		value, exists = parser.Globals[option]
 
 		if exists {
 			arg = value
 			existCount++
-			_, exists = parser.doubles[option]
+			_, exists = parser.Doubles[option]
 
 			if exists {
 				existCount++
@@ -226,18 +225,18 @@ func (parser *arguments) getArg(options ...string) (arg string, double, exists b
 	return arg, double, exists
 }
 
-func (parser *arguments) addTarget(targets ...string) {
-	parser.targets = append(parser.targets, targets...)
+func (parser *Arguments) AddTarget(targets ...string) {
+	parser.Targets = append(parser.Targets, targets...)
 }
 
-func (parser *arguments) clearTargets() {
-	parser.targets = make([]string, 0)
+func (parser *Arguments) ClearTargets() {
+	parser.Targets = make([]string, 0)
 }
 
 // Multiple args acts as an OR operator
-func (parser *arguments) existsDouble(options ...string) bool {
+func (parser *Arguments) ExistsDouble(options ...string) bool {
 	for _, option := range options {
-		_, exists := parser.doubles[option]
+		_, exists := parser.Doubles[option]
 		if exists {
 			return true
 		}
@@ -246,16 +245,16 @@ func (parser *arguments) existsDouble(options ...string) bool {
 	return false
 }
 
-func (parser *arguments) formatArgs() (args []string) {
+func (parser *Arguments) FormatArgs() (args []string) {
 	var op string
 
-	if parser.op != "" {
-		op = formatArg(parser.op)
+	if parser.Op != "" {
+		op = formatArg(parser.Op)
 	}
 
 	args = append(args, op)
 
-	for option, arg := range parser.options {
+	for option, arg := range parser.Options {
 		if option == "--" {
 			continue
 		}
@@ -267,7 +266,7 @@ func (parser *arguments) formatArgs() (args []string) {
 			args = append(args, arg)
 		}
 
-		if parser.existsDouble(option) {
+		if parser.ExistsDouble(option) {
 			args = append(args, formattedOption)
 		}
 	}
@@ -275,8 +274,8 @@ func (parser *arguments) formatArgs() (args []string) {
 	return
 }
 
-func (parser *arguments) formatGlobals() (args []string) {
-	for option, arg := range parser.globals {
+func (parser *Arguments) FormatGlobals() (args []string) {
+	for option, arg := range parser.Globals {
 		formattedOption := formatArg(option)
 		args = append(args, formattedOption)
 
@@ -284,7 +283,7 @@ func (parser *arguments) formatGlobals() (args []string) {
 			args = append(args, arg)
 		}
 
-		if parser.existsDouble(option) {
+		if parser.ExistsDouble(option) {
 			args = append(args, formattedOption)
 		}
 	}
@@ -454,12 +453,12 @@ func isArg(arg string) bool {
 	return true
 }
 
-func handleConfig(option, value string) bool {
+func handleConfig(config *Configuration, option, value string) bool {
 	switch option {
 	case "aururl":
 		config.AURURL = value
 	case "save":
-		shouldSaveConfig = true
+		config.Runtime.SaveConfig = true
 	case "afterclean", "cleanafter":
 		config.CleanAfter = true
 	case "noafterclean", "nocleanafter":
@@ -473,9 +472,9 @@ func handleConfig(option, value string) bool {
 	case "notimeupdate":
 		config.TimeUpdate = false
 	case "topdown":
-		config.SortMode = settings.TopDown
+		config.SortMode = TopDown
 	case "bottomup":
-		config.SortMode = settings.BottomUp
+		config.SortMode = BottomUp
 	case "completioninterval":
 		n, err := strconv.Atoi(value)
 		if err == nil {
@@ -595,9 +594,9 @@ func handleConfig(option, value string) bool {
 	case "nocombinedupgrade":
 		config.CombinedUpgrade = false
 	case "a", "aur":
-		mode = modeAUR
+		config.Runtime.Mode = ModeAUR
 	case "repo":
-		mode = modeRepo
+		config.Runtime.Mode = ModeRepo
 	case "removemake":
 		config.RemoveMake = "yes"
 	case "noremovemake":
@@ -705,9 +704,9 @@ func hasParam(arg string) bool {
 
 // Parses short hand options such as:
 // -Syu -b/some/path -
-func (parser *arguments) parseShortOption(arg, param string) (usedNext bool, err error) {
+func (parser *Arguments) parseShortOption(arg, param string) (usedNext bool, err error) {
 	if arg == "-" {
-		err = parser.addArg("-")
+		err = parser.AddArg("-")
 		return
 	}
 
@@ -726,7 +725,7 @@ func (parser *arguments) parseShortOption(arg, param string) (usedNext bool, err
 
 			break
 		} else {
-			err = parser.addArg(char)
+			err = parser.AddArg(char)
 
 			if err != nil {
 				return
@@ -739,9 +738,9 @@ func (parser *arguments) parseShortOption(arg, param string) (usedNext bool, err
 
 // Parses full length options such as:
 // --sync --refresh --sysupgrade --dbpath /some/path --
-func (parser *arguments) parseLongOption(arg, param string) (usedNext bool, err error) {
+func (parser *Arguments) parseLongOption(arg, param string) (usedNext bool, err error) {
 	if arg == "--" {
-		err = parser.addArg(arg)
+		err = parser.AddArg(arg)
 		return
 	}
 
@@ -754,24 +753,24 @@ func (parser *arguments) parseLongOption(arg, param string) (usedNext bool, err
 		err = parser.addParam(arg, param)
 		usedNext = true
 	default:
-		err = parser.addArg(arg)
+		err = parser.AddArg(arg)
 	}
 
 	return
 }
 
-func (parser *arguments) parseStdin() error {
+func (parser *Arguments) parseStdin() error {
 	scanner := bufio.NewScanner(os.Stdin)
 	scanner.Split(bufio.ScanLines)
 
 	for scanner.Scan() {
-		parser.addTarget(scanner.Text())
+		parser.AddTarget(scanner.Text())
 	}
 
 	return os.Stdin.Close()
 }
 
-func (parser *arguments) parseCommandLine() error {
+func (parser *Arguments) ParseCommandLine(config *Configuration) error {
 	args := os.Args[1:]
 	usedNext := false
 
@@ -794,14 +793,14 @@ func (parser *arguments) parseCommandLine() error {
 
 			var err error
 			switch {
-			case parser.existsArg("--"):
-				parser.addTarget(arg)
+			case parser.ExistsArg("--"):
+				parser.AddTarget(arg)
 			case strings.HasPrefix(arg, "--"):
 				usedNext, err = parser.parseLongOption(arg, nextArg)
 			case strings.HasPrefix(arg, "-"):
 				usedNext, err = parser.parseShortOption(arg, nextArg)
 			default:
-				parser.addTarget(arg)
+				parser.AddTarget(arg)
 			}
 
 			if err != nil {
@@ -810,15 +809,15 @@ func (parser *arguments) parseCommandLine() error {
 		}
 	}
 
-	if parser.op == "" {
-		parser.op = "Y"
+	if parser.Op == "" {
+		parser.Op = "Y"
 	}
 
-	if parser.existsArg("-") {
+	if parser.ExistsArg("-") {
 		if err := parser.parseStdin(); err != nil {
 			return err
 		}
-		parser.delArg("-")
+		parser.DelArg("-")
 
 		file, err := os.Open("/dev/tty")
 		if err != nil {
@@ -828,20 +827,20 @@ func (parser *arguments) parseCommandLine() error {
 		os.Stdin = file
 	}
 
-	cmdArgs.extractYayOptions()
+	parser.extractYayOptions(config)
 	return nil
 }
 
-func (parser *arguments) extractYayOptions() {
-	for option, value := range parser.options {
-		if handleConfig(option, value) {
-			parser.delArg(option)
+func (parser *Arguments) extractYayOptions(config *Configuration) {
+	for option, value := range parser.Options {
+		if handleConfig(config, option, value) {
+			parser.DelArg(option)
 		}
 	}
 
-	for option, value := range parser.globals {
-		if handleConfig(option, value) {
-			parser.delArg(option)
+	for option, value := range parser.Globals {
+		if handleConfig(config, option, value) {
+			parser.DelArg(option)
 		}
 	}
 

+ 14 - 0
pkg/settings/runtime.go

@@ -0,0 +1,14 @@
+package settings
+
+type TargetMode int
+
+const (
+	ModeAny TargetMode = iota
+	ModeAUR
+	ModeRepo
+)
+
+type Runtime struct {
+	Mode       TargetMode
+	SaveConfig bool
+}

+ 7 - 7
print.go

@@ -293,7 +293,7 @@ func PrintInfo(a *rpc.Pkg) {
 		text.PrintInfoValue(gotext.Get("Out-of-date"), "No")
 	}
 
-	if cmdArgs.existsDouble("i") {
+	if cmdArgs.ExistsDouble("i") {
 		text.PrintInfoValue("ID", fmt.Sprintf("%d", a.ID))
 		text.PrintInfoValue(gotext.Get("Package Base ID"), fmt.Sprintf("%d", a.PackageBaseID))
 		text.PrintInfoValue(gotext.Get("Package Base"), a.PackageBase)
@@ -367,8 +367,8 @@ func printNumberOfUpdates() error {
 }
 
 //TODO: Make it less hacky
-func printUpdateList(parser *arguments) error {
-	targets := stringset.FromSlice(parser.targets)
+func printUpdateList(parser *settings.Arguments) error {
+	targets := stringset.FromSlice(parser.Targets)
 	warnings := makeWarnings()
 	old := os.Stdout // keep backup of the real stdout
 	os.Stdout = nil
@@ -385,10 +385,10 @@ func printUpdateList(parser *arguments) error {
 
 	noTargets := len(targets) == 0
 
-	if !parser.existsArg("m", "foreign") {
+	if !parser.ExistsArg("m", "foreign") {
 		for _, pkg := range repoUp {
 			if noTargets || targets.Get(pkg.Name) {
-				if parser.existsArg("q", "quiet") {
+				if parser.ExistsArg("q", "quiet") {
 					fmt.Printf("%s\n", pkg.Name)
 				} else {
 					fmt.Printf("%s %s -> %s\n", bold(pkg.Name), green(pkg.LocalVersion), green(pkg.RemoteVersion))
@@ -398,10 +398,10 @@ func printUpdateList(parser *arguments) error {
 		}
 	}
 
-	if !parser.existsArg("n", "native") {
+	if !parser.ExistsArg("n", "native") {
 		for _, pkg := range aurUp {
 			if noTargets || targets.Get(pkg.Name) {
-				if parser.existsArg("q", "quiet") {
+				if parser.ExistsArg("q", "quiet") {
 					fmt.Printf("%s\n", pkg.Name)
 				} else {
 					fmt.Printf("%s %s -> %s\n", bold(pkg.Name), green(pkg.LocalVersion), green(pkg.RemoteVersion))

+ 11 - 11
query.go

@@ -160,10 +160,10 @@ func syncSearch(pkgS []string) (err error) {
 	var aq aurQuery
 	var pq repoQuery
 
-	if mode == modeAUR || mode == modeAny {
+	if config.Runtime.Mode == settings.ModeAUR || config.Runtime.Mode == settings.ModeAny {
 		aq, aurErr = narrowSearch(pkgS, true)
 	}
-	if mode == modeRepo || mode == modeAny {
+	if config.Runtime.Mode == settings.ModeRepo || config.Runtime.Mode == settings.ModeAny {
 		pq, repoErr = queryRepo(pkgS)
 		if repoErr != nil {
 			return err
@@ -172,17 +172,17 @@ func syncSearch(pkgS []string) (err error) {
 
 	switch config.SortMode {
 	case settings.TopDown:
-		if mode == modeRepo || mode == modeAny {
+		if config.Runtime.Mode == settings.ModeRepo || config.Runtime.Mode == settings.ModeAny {
 			pq.printSearch()
 		}
-		if mode == modeAUR || mode == modeAny {
+		if config.Runtime.Mode == settings.ModeAUR || config.Runtime.Mode == settings.ModeAny {
 			aq.printSearch(1)
 		}
 	case settings.BottomUp:
-		if mode == modeAUR || mode == modeAny {
+		if config.Runtime.Mode == settings.ModeAUR || config.Runtime.Mode == settings.ModeAny {
 			aq.printSearch(1)
 		}
-		if mode == modeRepo || mode == modeAny {
+		if config.Runtime.Mode == settings.ModeRepo || config.Runtime.Mode == settings.ModeAny {
 			pq.printSearch()
 		}
 	default:
@@ -224,9 +224,9 @@ func syncInfo(pkgS []string) error {
 
 	// Repo always goes first
 	if len(repoS) != 0 {
-		arguments := cmdArgs.copy()
-		arguments.clearTargets()
-		arguments.addTarget(repoS...)
+		arguments := cmdArgs.Copy()
+		arguments.ClearTargets()
+		arguments.AddTarget(repoS...)
 		err = show(passToPacman(arguments))
 
 		if err != nil {
@@ -289,10 +289,10 @@ func packageSlices(toCheck []string) (aur, repo []string, err error) {
 		db, name := splitDBFromName(_pkg)
 		found := false
 
-		if db == "aur" || mode == modeAUR {
+		if db == "aur" || config.Runtime.Mode == settings.ModeAUR {
 			aur = append(aur, _pkg)
 			continue
-		} else if db != "" || mode == modeRepo {
+		} else if db != "" || config.Runtime.Mode == settings.ModeRepo {
 			repo = append(repo, _pkg)
 			continue
 		}

+ 4 - 3
upgrade.go

@@ -11,6 +11,7 @@ import (
 
 	"github.com/Jguer/yay/v10/pkg/intrange"
 	"github.com/Jguer/yay/v10/pkg/query"
+	"github.com/Jguer/yay/v10/pkg/settings"
 	"github.com/Jguer/yay/v10/pkg/text"
 
 	rpc "github.com/mikkeloscar/aur"
@@ -135,7 +136,7 @@ func upList(warnings *aurWarnings) (aurUp, repoUp upSlice, err error) {
 		}
 	}
 
-	if mode == modeAny || mode == modeRepo {
+	if config.Runtime.Mode == settings.ModeAny || config.Runtime.Mode == settings.ModeRepo {
 		text.OperationInfoln(gotext.Get("Searching databases for updates..."))
 		wg.Add(1)
 		go func() {
@@ -145,7 +146,7 @@ func upList(warnings *aurWarnings) (aurUp, repoUp upSlice, err error) {
 		}()
 	}
 
-	if mode == modeAny || mode == modeAUR {
+	if config.Runtime.Mode == settings.ModeAny || config.Runtime.Mode == settings.ModeAUR {
 		text.OperationInfoln(gotext.Get("Searching AUR for updates..."))
 
 		var _aurdata []*rpc.Pkg
@@ -314,7 +315,7 @@ func upRepo() (upSlice, error) {
 		err = alpmHandle.TransRelease()
 	}()
 
-	err = alpmHandle.SyncSysupgrade(cmdArgs.existsDouble("u", "sysupgrade"))
+	err = alpmHandle.SyncSysupgrade(cmdArgs.ExistsDouble("u", "sysupgrade"))
 	if err != nil {
 		return slice, err
 	}

+ 3 - 2
utils.go

@@ -5,6 +5,7 @@ import (
 
 	"github.com/leonelquinteros/gotext"
 
+	"github.com/Jguer/yay/v10/pkg/settings"
 	"github.com/Jguer/yay/v10/pkg/text"
 )
 
@@ -38,12 +39,12 @@ func removeInvalidTargets(targets []string) []string {
 	for _, target := range targets {
 		db, _ := splitDBFromName(target)
 
-		if db == "aur" && mode == modeRepo {
+		if db == "aur" && config.Runtime.Mode == settings.ModeRepo {
 			text.Warnln(gotext.Get("%s: can't use target with option --repo -- skipping", cyan(target)))
 			continue
 		}
 
-		if db != "aur" && db != "" && mode == modeAUR {
+		if db != "aur" && db != "" && config.Runtime.Mode == settings.ModeAUR {
 			text.Warnln(gotext.Get("%s: can't use target with option --aur -- skipping", cyan(target)))
 			continue
 		}