mirror of
https://github.com/Jguer/yay
synced 2024-09-16 06:39:53 +00:00
765b767333
Some of the yay specific operations such as: '-Qstats' '-Cd' Break the standard pacamn has set. Most yay specific specific options have been moved into their own operator: '-Y' '--yay' '-Qstats' -> '-Y --stats' '--Cd' -> '-Y --cleandeps' '--gendb' -> '-Y --gendb' Although: '-G' has been kepts and and alias has been added for is: '--getpkgbuild' This shouldnt feel too different for most people given that yay will default to: '-Y' when no operator has been specified. So calls like: 'yay --gendb' will still work as they did. Internally handleConfig has been partially refactored. Now all that remians in setters for config. All flags that did anything beond setting config have been moved to handleYay(). This means less nasty os.Exit()'s and nicer flow control. The usage has also been updated. The options changes have been added but the layout has also been tweaked a bit. Lastly on the things not done: Man page has not been updated Shell completion has not been updated This will be done in further commits as the usage is not guaranteed to stay the same between now the completion of the argument system.
322 lines
5.4 KiB
Go
322 lines
5.4 KiB
Go
package main
|
|
|
|
import (
|
|
"os"
|
|
"fmt"
|
|
"strings"
|
|
"io"
|
|
)
|
|
|
|
type argParser struct {
|
|
op string
|
|
options map[string]string
|
|
doubles map[string]struct{} //tracks args passed twice such as -yy and -dd
|
|
targets map[string]struct{}
|
|
}
|
|
|
|
func makeArgParser() *argParser {
|
|
return &argParser {
|
|
"",
|
|
make(map[string]string),
|
|
make(map[string]struct{}),
|
|
make(map[string]struct{}),
|
|
}
|
|
}
|
|
|
|
func (praser *argParser) delArg(option string) {
|
|
delete(praser.options, option)
|
|
delete(praser.doubles, option)
|
|
}
|
|
|
|
func (praser *argParser) addOP(op string) (err error) {
|
|
if praser.op != "" {
|
|
err = fmt.Errorf("only one operation may be used at a time")
|
|
return
|
|
}
|
|
|
|
praser.op = op
|
|
return
|
|
}
|
|
|
|
func (praser *argParser) addParam(option string, arg string) (err error) {
|
|
if isOp(option) {
|
|
err = praser.addOP(option)
|
|
return
|
|
}
|
|
|
|
if praser.existsArg(option) {
|
|
praser.doubles[option] = struct{}{}
|
|
} else {
|
|
praser.options[option] = arg
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
func (praser *argParser) addArg(option string) (err error) {
|
|
err = praser.addParam(option, "")
|
|
return
|
|
}
|
|
|
|
func (praser *argParser) existsArg(option string) (ok bool) {
|
|
_, ok = praser.options[option]
|
|
return ok
|
|
}
|
|
|
|
func (praser *argParser) getArg(option string) (arg string, double bool, exists bool) {
|
|
arg, exists = praser.options[option]
|
|
_, double = praser.doubles[option]
|
|
return
|
|
}
|
|
|
|
func (praser *argParser) addTarget(target string) {
|
|
praser.targets[target] = struct{}{}
|
|
}
|
|
|
|
func (praser *argParser) delTarget(target string) {
|
|
delete(praser.targets, target)
|
|
}
|
|
|
|
func (parser *argParser) existsDouble(option string) bool {
|
|
_, ok := parser.doubles[option]
|
|
return ok
|
|
}
|
|
|
|
func (parser *argParser) formatArgs() (op string, options []string, targets []string) {
|
|
op = formatArg(parser.op)
|
|
|
|
for option, arg := range parser.options {
|
|
option = formatArg(option)
|
|
options = append(options, option)
|
|
|
|
if arg != "" {
|
|
options = append(options, arg)
|
|
}
|
|
|
|
if parser.existsDouble(option) {
|
|
options = append(options, option)
|
|
}
|
|
}
|
|
|
|
for target := range parser.targets {
|
|
targets = append(targets, target)
|
|
}
|
|
|
|
return
|
|
|
|
}
|
|
|
|
func formatArg(arg string) string {
|
|
if len(arg) > 1 {
|
|
arg = "--" + arg
|
|
} else {
|
|
arg = "-" + arg
|
|
}
|
|
|
|
return arg
|
|
}
|
|
|
|
func isOp(op string) bool {
|
|
switch op {
|
|
case "V", "version":
|
|
return true
|
|
case "D", "database":
|
|
return true
|
|
case "F", "files":
|
|
return true
|
|
case "Q", "query":
|
|
return true
|
|
case "R", "remove":
|
|
return true
|
|
case "S", "sync":
|
|
return true
|
|
case "T", "deptest":
|
|
return true
|
|
case "U", "upgrade":
|
|
return true
|
|
|
|
//yay specific
|
|
case "Y", "yay":
|
|
return true
|
|
case "G", "getpkgbuild":
|
|
return true
|
|
default:
|
|
return false
|
|
}
|
|
}
|
|
|
|
func isYayParam(arg string) bool {
|
|
switch arg {
|
|
case "afterclean":
|
|
return true
|
|
case "noafterclean":
|
|
return true
|
|
case "devel":
|
|
return true
|
|
case "nodevel":
|
|
return true
|
|
case "timeupdate":
|
|
return true
|
|
case "notimeupdate":
|
|
return true
|
|
case "topdown":
|
|
return true
|
|
default:
|
|
return false
|
|
}
|
|
}
|
|
|
|
func hasParam(arg string) bool {
|
|
switch arg {
|
|
case "dbpath", "b":
|
|
return true
|
|
case "root", "r":
|
|
return true
|
|
case "sysroot":
|
|
return true
|
|
case "config":
|
|
return true
|
|
case "ignore":
|
|
return true
|
|
case "assume-installed":
|
|
return true
|
|
case "overwrite":
|
|
return true
|
|
case "ask":
|
|
return true
|
|
case "cachedir":
|
|
return true
|
|
case "hookdir":
|
|
return true
|
|
case "logfile":
|
|
return true
|
|
case "ignoregroup":
|
|
return true
|
|
case "arch":
|
|
return true
|
|
case "print-format":
|
|
return true
|
|
case "gpgdir":
|
|
return true
|
|
case "color":
|
|
return true
|
|
default:
|
|
return false
|
|
}
|
|
}
|
|
|
|
//parses short hand options such as:
|
|
//-Syu -b/some/path -
|
|
func (parser *argParser) parseShortOption(arg string, param string) (usedNext bool, err error) {
|
|
if arg == "-" {
|
|
err = parser.addArg("-")
|
|
return
|
|
}
|
|
|
|
arg = arg[1:]
|
|
|
|
for k, _char := range arg {
|
|
char := string(_char)
|
|
|
|
if hasParam(char) {
|
|
if k < len(arg) - 2 {
|
|
err = parser.addParam(char, arg[k+2:])
|
|
} else {
|
|
usedNext = true
|
|
err = parser.addParam(char, param)
|
|
}
|
|
|
|
break
|
|
} else {
|
|
err = parser.addArg(char)
|
|
|
|
if err != nil {
|
|
return
|
|
}
|
|
}
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
//parses full length options such as:
|
|
//--sync --refresh --sysupgrade --dbpath /some/path --
|
|
func (parser *argParser) parseLongOption(arg string, param string) (usedNext bool, err error){
|
|
if arg == "--" {
|
|
err = parser.addArg(arg)
|
|
return
|
|
}
|
|
|
|
arg = arg[2:]
|
|
|
|
if hasParam(arg) {
|
|
err = parser.addParam(arg, param)
|
|
usedNext = true
|
|
} else {
|
|
err = parser.addArg(arg)
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
func (parser *argParser) parseStdin() (err error) {
|
|
for true {
|
|
var target string
|
|
_, err = fmt.Scan(&target)
|
|
|
|
if err != nil {
|
|
if err == io.EOF {
|
|
err = nil
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
parser.addTarget(target)
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
func (parser *argParser)parseCommandLine() (err error) {
|
|
args := os.Args[1:]
|
|
usedNext := false
|
|
|
|
if len(args) < 1 {
|
|
err = fmt.Errorf("no operation specified (use -h for help)")
|
|
return
|
|
}
|
|
|
|
for k, arg := range args {
|
|
var nextArg string
|
|
|
|
if usedNext {
|
|
usedNext = false
|
|
continue
|
|
}
|
|
|
|
if k + 1 < len(args) {
|
|
nextArg = args[k + 1]
|
|
}
|
|
|
|
if parser.existsArg("--") {
|
|
parser.addTarget(arg)
|
|
} else if strings.HasPrefix(arg, "--") {
|
|
usedNext, err = parser.parseLongOption(arg, nextArg)
|
|
} else if strings.HasPrefix(arg, "-") {
|
|
usedNext, err = parser.parseShortOption(arg, nextArg)
|
|
} else {
|
|
parser.addTarget(arg)
|
|
}
|
|
|
|
if err != nil {
|
|
return
|
|
}
|
|
}
|
|
|
|
if parser.op == "" {
|
|
parser.op = "Y"
|
|
}
|
|
|
|
return
|
|
} |