2020-07-05 02:45:23 +02:00
|
|
|
package settings
|
2017-12-31 16:18:12 +01:00
|
|
|
|
|
|
|
import (
|
2018-07-30 02:16:36 +02:00
|
|
|
"bufio"
|
2018-01-19 15:51:18 +01:00
|
|
|
"os"
|
2018-03-09 03:03:04 +01:00
|
|
|
"strconv"
|
2018-01-19 15:51:18 +01:00
|
|
|
"strings"
|
2018-08-19 06:53:32 +02:00
|
|
|
|
2020-05-04 09:24:32 +02:00
|
|
|
"github.com/leonelquinteros/gotext"
|
2018-08-19 06:53:32 +02:00
|
|
|
rpc "github.com/mikkeloscar/aur"
|
2020-05-04 09:24:32 +02:00
|
|
|
"github.com/pkg/errors"
|
2020-05-02 16:17:20 +02:00
|
|
|
|
2020-06-13 19:29:50 +02:00
|
|
|
"github.com/Jguer/yay/v10/pkg/stringset"
|
2017-12-31 16:18:12 +01:00
|
|
|
)
|
|
|
|
|
2020-07-05 02:45:23 +02:00
|
|
|
// Arguments Parses command line arguments in a way we can interact with programmatically but
|
2018-03-03 03:45:16 +01:00
|
|
|
// also in a way that can easily be passed to pacman later on.
|
2020-07-05 02:45:23 +02:00
|
|
|
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
|
2017-12-31 16:18:12 +01:00
|
|
|
}
|
|
|
|
|
2020-07-05 02:45:23 +02:00
|
|
|
func MakeArguments() *Arguments {
|
|
|
|
return &Arguments{
|
2017-12-31 16:18:12 +01:00
|
|
|
"",
|
|
|
|
make(map[string]string),
|
2018-01-04 07:01:17 +01:00
|
|
|
make(map[string]string),
|
2019-10-16 23:25:40 +02:00
|
|
|
make(stringset.StringSet),
|
2018-06-02 16:01:39 +02:00
|
|
|
make([]string, 0),
|
2017-12-31 16:18:12 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-07-05 02:45:23 +02:00
|
|
|
func (parser *Arguments) CopyGlobal() (cp *Arguments) {
|
|
|
|
cp = MakeArguments()
|
|
|
|
for k, v := range parser.Globals {
|
|
|
|
cp.Globals[k] = v
|
2019-10-10 16:55:43 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2020-07-05 02:45:23 +02:00
|
|
|
func (parser *Arguments) Copy() (cp *Arguments) {
|
|
|
|
cp = MakeArguments()
|
2018-01-19 15:51:18 +01:00
|
|
|
|
2020-07-05 02:45:23 +02:00
|
|
|
cp.Op = parser.Op
|
2018-01-19 15:51:18 +01:00
|
|
|
|
2020-07-05 02:45:23 +02:00
|
|
|
for k, v := range parser.Options {
|
|
|
|
cp.Options[k] = v
|
2018-01-04 07:01:17 +01:00
|
|
|
}
|
2018-01-19 15:51:18 +01:00
|
|
|
|
2020-07-05 02:45:23 +02:00
|
|
|
for k, v := range parser.Globals {
|
|
|
|
cp.Globals[k] = v
|
2018-01-04 07:01:17 +01:00
|
|
|
}
|
2018-01-19 15:51:18 +01:00
|
|
|
|
2020-07-05 02:45:23 +02:00
|
|
|
cp.Targets = make([]string, len(parser.Targets))
|
|
|
|
copy(cp.Targets, parser.Targets)
|
2018-01-19 15:51:18 +01:00
|
|
|
|
2020-07-05 02:45:23 +02:00
|
|
|
for k, v := range parser.Doubles {
|
|
|
|
cp.Doubles[k] = v
|
2018-01-04 07:01:17 +01:00
|
|
|
}
|
2018-01-19 15:51:18 +01:00
|
|
|
|
2018-01-04 07:01:17 +01:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2020-07-05 02:45:23 +02:00
|
|
|
func (parser *Arguments) DelArg(options ...string) {
|
2018-01-04 01:59:57 +01:00
|
|
|
for _, option := range options {
|
2020-07-05 02:45:23 +02:00
|
|
|
delete(parser.Options, option)
|
|
|
|
delete(parser.Globals, option)
|
|
|
|
delete(parser.Doubles, option)
|
2018-01-04 01:59:57 +01:00
|
|
|
}
|
2017-12-31 16:18:12 +01:00
|
|
|
}
|
|
|
|
|
2020-07-05 02:45:23 +02:00
|
|
|
func (parser *Arguments) NeedRoot(runtime *Runtime) bool {
|
|
|
|
if parser.ExistsArg("h", "help") {
|
2018-01-03 19:42:40 +01:00
|
|
|
return false
|
|
|
|
}
|
2018-01-19 15:51:18 +01:00
|
|
|
|
2020-07-05 02:45:23 +02:00
|
|
|
switch parser.Op {
|
2018-01-03 19:42:40 +01:00
|
|
|
case "D", "database":
|
2020-07-05 02:45:23 +02:00
|
|
|
if parser.ExistsArg("k", "check") {
|
2018-07-21 18:36:16 +02:00
|
|
|
return false
|
|
|
|
}
|
2018-01-03 19:42:40 +01:00
|
|
|
return true
|
|
|
|
case "F", "files":
|
2020-07-05 02:45:23 +02:00
|
|
|
if parser.ExistsArg("y", "refresh") {
|
2018-01-03 19:42:40 +01:00
|
|
|
return true
|
|
|
|
}
|
|
|
|
return false
|
|
|
|
case "Q", "query":
|
2020-07-05 02:45:23 +02:00
|
|
|
if parser.ExistsArg("k", "check") {
|
2018-07-02 14:15:57 +02:00
|
|
|
return true
|
|
|
|
}
|
2018-01-03 19:42:40 +01:00
|
|
|
return false
|
|
|
|
case "R", "remove":
|
2020-07-05 02:45:23 +02:00
|
|
|
if parser.ExistsArg("p", "print", "print-format") {
|
2019-05-18 06:26:22 +02:00
|
|
|
return false
|
|
|
|
}
|
2018-01-03 19:42:40 +01:00
|
|
|
return true
|
|
|
|
case "S", "sync":
|
2020-07-05 02:45:23 +02:00
|
|
|
if parser.ExistsArg("y", "refresh") {
|
2018-07-25 04:45:34 +02:00
|
|
|
return true
|
|
|
|
}
|
2020-07-05 02:45:23 +02:00
|
|
|
if parser.ExistsArg("p", "print", "print-format") {
|
2018-07-25 04:45:34 +02:00
|
|
|
return false
|
|
|
|
}
|
2020-07-05 02:45:23 +02:00
|
|
|
if parser.ExistsArg("s", "search") {
|
2018-01-03 19:42:40 +01:00
|
|
|
return false
|
|
|
|
}
|
2020-07-05 02:45:23 +02:00
|
|
|
if parser.ExistsArg("l", "list") {
|
2018-01-03 19:42:40 +01:00
|
|
|
return false
|
|
|
|
}
|
2020-07-05 02:45:23 +02:00
|
|
|
if parser.ExistsArg("g", "groups") {
|
2018-07-21 17:18:19 +02:00
|
|
|
return false
|
|
|
|
}
|
2020-07-05 02:45:23 +02:00
|
|
|
if parser.ExistsArg("i", "info") {
|
2018-07-21 17:18:19 +02:00
|
|
|
return false
|
|
|
|
}
|
2020-07-05 02:45:23 +02:00
|
|
|
if parser.ExistsArg("c", "clean") && runtime.Mode == ModeAUR {
|
2018-07-24 03:49:45 +02:00
|
|
|
return false
|
|
|
|
}
|
2018-07-21 17:18:19 +02:00
|
|
|
return true
|
|
|
|
case "U", "upgrade":
|
|
|
|
return true
|
|
|
|
default:
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-07-05 02:45:23 +02:00
|
|
|
func (parser *Arguments) addOP(op string) (err error) {
|
|
|
|
if parser.Op != "" {
|
2020-05-04 09:24:32 +02:00
|
|
|
err = errors.New(gotext.Get("only one operation may be used at a time"))
|
2017-12-31 16:18:12 +01:00
|
|
|
return
|
|
|
|
}
|
2018-01-19 15:51:18 +01:00
|
|
|
|
2020-07-05 02:45:23 +02:00
|
|
|
parser.Op = op
|
2017-12-31 16:18:12 +01:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2020-07-05 02:45:23 +02:00
|
|
|
func (parser *Arguments) addParam(option, arg string) (err error) {
|
2018-07-30 05:38:06 +02:00
|
|
|
if !isArg(option) {
|
2020-05-04 09:24:32 +02:00
|
|
|
return errors.New(gotext.Get("invalid option '%s'", option))
|
2018-07-30 05:38:06 +02:00
|
|
|
}
|
|
|
|
|
2017-12-31 16:18:12 +01:00
|
|
|
if isOp(option) {
|
2018-01-04 01:59:57 +01:00
|
|
|
err = parser.addOP(option)
|
2017-12-31 16:18:12 +01:00
|
|
|
return
|
|
|
|
}
|
2018-01-19 15:51:18 +01:00
|
|
|
|
2019-03-07 21:02:44 +01:00
|
|
|
switch {
|
2020-07-05 02:45:23 +02:00
|
|
|
case parser.ExistsArg(option):
|
|
|
|
parser.Doubles[option] = struct{}{}
|
2019-03-07 21:02:44 +01:00
|
|
|
case isGlobal(option):
|
2020-07-05 02:45:23 +02:00
|
|
|
parser.Globals[option] = arg
|
2019-03-07 21:02:44 +01:00
|
|
|
default:
|
2020-07-05 02:45:23 +02:00
|
|
|
parser.Options[option] = arg
|
2017-12-31 16:18:12 +01:00
|
|
|
}
|
2018-01-19 15:51:18 +01:00
|
|
|
|
2017-12-31 16:18:12 +01:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2020-07-05 02:45:23 +02:00
|
|
|
func (parser *Arguments) AddArg(options ...string) (err error) {
|
2018-01-04 01:59:57 +01:00
|
|
|
for _, option := range options {
|
|
|
|
err = parser.addParam(option, "")
|
|
|
|
if err != nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
2018-01-04 07:01:17 +01:00
|
|
|
|
2017-12-31 16:18:12 +01:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2018-03-03 03:45:16 +01:00
|
|
|
// Multiple args acts as an OR operator
|
2020-07-05 02:45:23 +02:00
|
|
|
func (parser *Arguments) ExistsArg(options ...string) bool {
|
2018-01-04 01:59:57 +01:00
|
|
|
for _, option := range options {
|
2020-07-05 02:45:23 +02:00
|
|
|
_, exists := parser.Options[option]
|
2018-01-04 01:59:57 +01:00
|
|
|
if exists {
|
|
|
|
return true
|
|
|
|
}
|
2018-01-19 15:51:18 +01:00
|
|
|
|
2020-07-05 02:45:23 +02:00
|
|
|
_, exists = parser.Globals[option]
|
2018-01-04 07:01:17 +01:00
|
|
|
if exists {
|
|
|
|
return true
|
|
|
|
}
|
2018-01-04 01:59:57 +01:00
|
|
|
}
|
|
|
|
return false
|
2017-12-31 16:18:12 +01:00
|
|
|
}
|
|
|
|
|
2020-07-05 02:45:23 +02:00
|
|
|
func (parser *Arguments) GetArg(options ...string) (arg string, double, exists bool) {
|
2018-04-16 21:22:33 +02:00
|
|
|
existCount := 0
|
|
|
|
|
2018-01-04 22:21:39 +01:00
|
|
|
for _, option := range options {
|
2018-04-27 03:43:10 +02:00
|
|
|
var value string
|
|
|
|
|
2020-07-05 02:45:23 +02:00
|
|
|
value, exists = parser.Options[option]
|
2018-01-04 22:21:39 +01:00
|
|
|
|
|
|
|
if exists {
|
2018-04-27 03:43:10 +02:00
|
|
|
arg = value
|
2018-04-16 21:22:33 +02:00
|
|
|
existCount++
|
2020-07-05 02:45:23 +02:00
|
|
|
_, exists = parser.Doubles[option]
|
2018-04-16 21:22:33 +02:00
|
|
|
|
|
|
|
if exists {
|
|
|
|
existCount++
|
|
|
|
}
|
2018-01-04 22:21:39 +01:00
|
|
|
}
|
2018-01-04 07:01:17 +01:00
|
|
|
|
2020-07-05 02:45:23 +02:00
|
|
|
value, exists = parser.Globals[option]
|
2018-01-19 15:51:18 +01:00
|
|
|
|
2018-01-04 22:21:39 +01:00
|
|
|
if exists {
|
2018-04-27 03:43:10 +02:00
|
|
|
arg = value
|
2018-04-16 21:22:33 +02:00
|
|
|
existCount++
|
2020-07-05 02:45:23 +02:00
|
|
|
_, exists = parser.Doubles[option]
|
2018-04-16 21:22:33 +02:00
|
|
|
|
|
|
|
if exists {
|
|
|
|
existCount++
|
|
|
|
}
|
2018-01-04 22:21:39 +01:00
|
|
|
}
|
|
|
|
}
|
2018-01-19 15:51:18 +01:00
|
|
|
|
2018-04-16 21:22:33 +02:00
|
|
|
double = existCount >= 2
|
2018-04-17 19:24:39 +02:00
|
|
|
exists = existCount >= 1
|
2018-04-16 21:22:33 +02:00
|
|
|
|
2020-05-02 16:17:20 +02:00
|
|
|
return arg, double, exists
|
2017-12-31 16:18:12 +01:00
|
|
|
}
|
|
|
|
|
2020-07-05 02:45:23 +02:00
|
|
|
func (parser *Arguments) AddTarget(targets ...string) {
|
|
|
|
parser.Targets = append(parser.Targets, targets...)
|
2018-01-04 01:59:57 +01:00
|
|
|
}
|
|
|
|
|
2020-07-05 02:45:23 +02:00
|
|
|
func (parser *Arguments) ClearTargets() {
|
|
|
|
parser.Targets = make([]string, 0)
|
2017-12-31 16:18:12 +01:00
|
|
|
}
|
|
|
|
|
2018-03-03 03:45:16 +01:00
|
|
|
// Multiple args acts as an OR operator
|
2020-07-05 02:45:23 +02:00
|
|
|
func (parser *Arguments) ExistsDouble(options ...string) bool {
|
2018-01-04 01:59:57 +01:00
|
|
|
for _, option := range options {
|
2020-07-05 02:45:23 +02:00
|
|
|
_, exists := parser.Doubles[option]
|
2018-01-04 01:59:57 +01:00
|
|
|
if exists {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
}
|
2018-01-19 15:51:18 +01:00
|
|
|
|
2018-01-04 01:59:57 +01:00
|
|
|
return false
|
2017-12-31 16:18:12 +01:00
|
|
|
}
|
|
|
|
|
2020-07-05 02:45:23 +02:00
|
|
|
func (parser *Arguments) FormatArgs() (args []string) {
|
2018-01-21 12:48:09 +01:00
|
|
|
var op string
|
|
|
|
|
2020-07-05 02:45:23 +02:00
|
|
|
if parser.Op != "" {
|
|
|
|
op = formatArg(parser.Op)
|
2018-01-21 12:48:09 +01:00
|
|
|
}
|
|
|
|
|
2018-01-03 19:42:40 +01:00
|
|
|
args = append(args, op)
|
2018-01-19 15:51:18 +01:00
|
|
|
|
2020-07-05 02:45:23 +02:00
|
|
|
for option, arg := range parser.Options {
|
2018-02-20 18:03:50 +01:00
|
|
|
if option == "--" {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
2018-05-12 18:16:48 +02:00
|
|
|
formattedOption := formatArg(option)
|
|
|
|
args = append(args, formattedOption)
|
2018-01-19 15:51:18 +01:00
|
|
|
|
2018-01-04 07:01:17 +01:00
|
|
|
if hasParam(option) {
|
2018-01-03 19:42:40 +01:00
|
|
|
args = append(args, arg)
|
2017-12-31 16:18:12 +01:00
|
|
|
}
|
2018-01-19 15:51:18 +01:00
|
|
|
|
2020-07-05 02:45:23 +02:00
|
|
|
if parser.ExistsDouble(option) {
|
2018-05-12 18:16:48 +02:00
|
|
|
args = append(args, formattedOption)
|
2018-01-04 07:01:17 +01:00
|
|
|
}
|
|
|
|
}
|
2018-01-19 15:51:18 +01:00
|
|
|
|
2018-01-04 07:01:17 +01:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2020-07-05 02:45:23 +02:00
|
|
|
func (parser *Arguments) FormatGlobals() (args []string) {
|
|
|
|
for option, arg := range parser.Globals {
|
2018-05-12 18:16:48 +02:00
|
|
|
formattedOption := formatArg(option)
|
|
|
|
args = append(args, formattedOption)
|
2018-01-19 15:51:18 +01:00
|
|
|
|
2018-01-04 07:01:17 +01:00
|
|
|
if hasParam(option) {
|
|
|
|
args = append(args, arg)
|
|
|
|
}
|
2018-01-19 15:51:18 +01:00
|
|
|
|
2020-07-05 02:45:23 +02:00
|
|
|
if parser.ExistsDouble(option) {
|
2018-05-12 18:16:48 +02:00
|
|
|
args = append(args, formattedOption)
|
2017-12-31 16:18:12 +01:00
|
|
|
}
|
|
|
|
}
|
2018-01-19 15:51:18 +01:00
|
|
|
|
2017-12-31 16:18:12 +01:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
func formatArg(arg string) string {
|
|
|
|
if len(arg) > 1 {
|
|
|
|
arg = "--" + arg
|
|
|
|
} else {
|
|
|
|
arg = "-" + arg
|
|
|
|
}
|
2018-01-19 15:51:18 +01:00
|
|
|
|
2017-12-31 16:18:12 +01:00
|
|
|
return arg
|
|
|
|
}
|
|
|
|
|
2018-07-30 05:38:06 +02:00
|
|
|
func isArg(arg string) bool {
|
|
|
|
switch arg {
|
2018-08-02 17:51:33 +02:00
|
|
|
case "-", "--":
|
2018-10-13 02:31:16 +02:00
|
|
|
case "ask":
|
2018-07-30 05:38:06 +02:00
|
|
|
case "D", "database":
|
|
|
|
case "Q", "query":
|
|
|
|
case "R", "remove":
|
|
|
|
case "S", "sync":
|
|
|
|
case "T", "deptest":
|
|
|
|
case "U", "upgrade":
|
|
|
|
case "F", "files":
|
|
|
|
case "V", "version":
|
|
|
|
case "h", "help":
|
|
|
|
case "Y", "yay":
|
2018-08-02 22:58:03 +02:00
|
|
|
case "P", "show":
|
2018-07-30 05:38:06 +02:00
|
|
|
case "G", "getpkgbuild":
|
|
|
|
case "b", "dbpath":
|
|
|
|
case "r", "root":
|
|
|
|
case "v", "verbose":
|
|
|
|
case "arch":
|
|
|
|
case "cachedir":
|
|
|
|
case "color":
|
|
|
|
case "config":
|
|
|
|
case "debug":
|
|
|
|
case "gpgdir":
|
|
|
|
case "hookdir":
|
|
|
|
case "logfile":
|
|
|
|
case "noconfirm":
|
|
|
|
case "confirm":
|
2018-10-09 16:59:17 +02:00
|
|
|
case "disable-download-timeout":
|
2018-07-30 05:38:06 +02:00
|
|
|
case "sysroot":
|
|
|
|
case "d", "nodeps":
|
2018-09-23 23:08:45 +02:00
|
|
|
case "assume-installed":
|
2018-07-30 05:38:06 +02:00
|
|
|
case "dbonly":
|
2019-10-23 13:31:29 +02:00
|
|
|
case "absdir":
|
2018-07-30 05:38:06 +02:00
|
|
|
case "noprogressbar":
|
|
|
|
case "noscriptlet":
|
2018-10-09 17:13:40 +02:00
|
|
|
case "p", "print":
|
2018-10-09 16:59:17 +02:00
|
|
|
case "print-format":
|
2018-07-30 05:38:06 +02:00
|
|
|
case "asdeps":
|
|
|
|
case "asexplicit":
|
|
|
|
case "ignore":
|
|
|
|
case "ignoregroup":
|
|
|
|
case "needed":
|
|
|
|
case "overwrite":
|
2018-08-30 16:30:52 +02:00
|
|
|
case "f", "force":
|
2018-07-30 05:38:06 +02:00
|
|
|
case "c", "changelog":
|
|
|
|
case "deps":
|
|
|
|
case "e", "explicit":
|
|
|
|
case "g", "groups":
|
|
|
|
case "i", "info":
|
|
|
|
case "k", "check":
|
|
|
|
case "l", "list":
|
|
|
|
case "m", "foreign":
|
|
|
|
case "n", "native":
|
|
|
|
case "o", "owns":
|
|
|
|
case "file":
|
|
|
|
case "q", "quiet":
|
|
|
|
case "s", "search":
|
|
|
|
case "t", "unrequired":
|
|
|
|
case "u", "upgrades":
|
|
|
|
case "cascade":
|
|
|
|
case "nosave":
|
|
|
|
case "recursive":
|
|
|
|
case "unneeded":
|
|
|
|
case "clean":
|
|
|
|
case "sysupgrade":
|
|
|
|
case "w", "downloadonly":
|
|
|
|
case "y", "refresh":
|
|
|
|
case "x", "regex":
|
|
|
|
case "machinereadable":
|
2020-05-02 16:17:20 +02:00
|
|
|
// yay options
|
2018-08-19 06:05:16 +02:00
|
|
|
case "aururl":
|
2018-07-30 05:38:06 +02:00
|
|
|
case "save":
|
2018-09-27 17:12:43 +02:00
|
|
|
case "afterclean", "cleanafter":
|
|
|
|
case "noafterclean", "nocleanafter":
|
2018-07-30 05:38:06 +02:00
|
|
|
case "devel":
|
|
|
|
case "nodevel":
|
|
|
|
case "timeupdate":
|
|
|
|
case "notimeupdate":
|
|
|
|
case "topdown":
|
|
|
|
case "bottomup":
|
|
|
|
case "completioninterval":
|
|
|
|
case "sortby":
|
2019-10-10 18:40:38 +02:00
|
|
|
case "searchby":
|
2018-07-30 05:38:06 +02:00
|
|
|
case "redownload":
|
|
|
|
case "redownloadall":
|
|
|
|
case "noredownload":
|
|
|
|
case "rebuild":
|
|
|
|
case "rebuildall":
|
|
|
|
case "rebuildtree":
|
|
|
|
case "norebuild":
|
2019-10-10 16:55:43 +02:00
|
|
|
case "batchinstall":
|
|
|
|
case "nobatchinstall":
|
2018-07-30 05:38:06 +02:00
|
|
|
case "answerclean":
|
|
|
|
case "noanswerclean":
|
|
|
|
case "answerdiff":
|
|
|
|
case "noanswerdiff":
|
|
|
|
case "answeredit":
|
|
|
|
case "noansweredit":
|
|
|
|
case "answerupgrade":
|
|
|
|
case "noanswerupgrade":
|
|
|
|
case "gpgflags":
|
|
|
|
case "mflags":
|
|
|
|
case "gitflags":
|
|
|
|
case "builddir":
|
|
|
|
case "editor":
|
|
|
|
case "editorflags":
|
|
|
|
case "makepkg":
|
|
|
|
case "makepkgconf":
|
|
|
|
case "nomakepkgconf":
|
|
|
|
case "pacman":
|
|
|
|
case "git":
|
|
|
|
case "gpg":
|
2019-03-19 22:10:58 +01:00
|
|
|
case "sudo":
|
|
|
|
case "sudoflags":
|
2018-07-30 05:38:06 +02:00
|
|
|
case "requestsplitn":
|
|
|
|
case "sudoloop":
|
|
|
|
case "nosudoloop":
|
|
|
|
case "provides":
|
|
|
|
case "noprovides":
|
|
|
|
case "pgpfetch":
|
|
|
|
case "nopgpfetch":
|
|
|
|
case "upgrademenu":
|
|
|
|
case "noupgrademenu":
|
|
|
|
case "cleanmenu":
|
|
|
|
case "nocleanmenu":
|
|
|
|
case "diffmenu":
|
|
|
|
case "nodiffmenu":
|
|
|
|
case "editmenu":
|
|
|
|
case "noeditmenu":
|
|
|
|
case "useask":
|
|
|
|
case "nouseask":
|
|
|
|
case "combinedupgrade":
|
|
|
|
case "nocombinedupgrade":
|
|
|
|
case "a", "aur":
|
|
|
|
case "repo":
|
|
|
|
case "removemake":
|
|
|
|
case "noremovemake":
|
|
|
|
case "askremovemake":
|
2018-08-02 22:58:03 +02:00
|
|
|
case "complete":
|
|
|
|
case "stats":
|
|
|
|
case "news":
|
|
|
|
case "gendb":
|
|
|
|
case "currentconfig":
|
2018-07-30 05:38:06 +02:00
|
|
|
default:
|
|
|
|
return false
|
|
|
|
}
|
2018-07-30 05:49:17 +02:00
|
|
|
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
2020-07-05 02:45:23 +02:00
|
|
|
func handleConfig(config *Configuration, option, value string) bool {
|
2018-07-30 05:49:17 +02:00
|
|
|
switch option {
|
2018-08-19 06:05:16 +02:00
|
|
|
case "aururl":
|
|
|
|
config.AURURL = value
|
2018-07-30 05:49:17 +02:00
|
|
|
case "save":
|
2020-07-05 02:45:23 +02:00
|
|
|
config.Runtime.SaveConfig = true
|
2018-09-27 17:12:43 +02:00
|
|
|
case "afterclean", "cleanafter":
|
2018-07-30 05:49:17 +02:00
|
|
|
config.CleanAfter = true
|
2018-09-27 17:12:43 +02:00
|
|
|
case "noafterclean", "nocleanafter":
|
2018-07-30 05:49:17 +02:00
|
|
|
config.CleanAfter = false
|
|
|
|
case "devel":
|
|
|
|
config.Devel = true
|
|
|
|
case "nodevel":
|
|
|
|
config.Devel = false
|
|
|
|
case "timeupdate":
|
|
|
|
config.TimeUpdate = true
|
|
|
|
case "notimeupdate":
|
|
|
|
config.TimeUpdate = false
|
|
|
|
case "topdown":
|
2020-07-05 02:45:23 +02:00
|
|
|
config.SortMode = TopDown
|
2018-07-30 05:49:17 +02:00
|
|
|
case "bottomup":
|
2020-07-05 02:45:23 +02:00
|
|
|
config.SortMode = BottomUp
|
2018-07-30 05:49:17 +02:00
|
|
|
case "completioninterval":
|
|
|
|
n, err := strconv.Atoi(value)
|
|
|
|
if err == nil {
|
|
|
|
config.CompletionInterval = n
|
|
|
|
}
|
|
|
|
case "sortby":
|
|
|
|
config.SortBy = value
|
2019-10-10 18:40:38 +02:00
|
|
|
case "searchby":
|
|
|
|
config.SearchBy = value
|
2018-07-30 05:49:17 +02:00
|
|
|
case "noconfirm":
|
|
|
|
config.NoConfirm = true
|
|
|
|
case "config":
|
|
|
|
config.PacmanConf = value
|
|
|
|
case "redownload":
|
|
|
|
config.ReDownload = "yes"
|
|
|
|
case "redownloadall":
|
|
|
|
config.ReDownload = "all"
|
|
|
|
case "noredownload":
|
|
|
|
config.ReDownload = "no"
|
|
|
|
case "rebuild":
|
|
|
|
config.ReBuild = "yes"
|
|
|
|
case "rebuildall":
|
|
|
|
config.ReBuild = "all"
|
|
|
|
case "rebuildtree":
|
|
|
|
config.ReBuild = "tree"
|
|
|
|
case "norebuild":
|
|
|
|
config.ReBuild = "no"
|
2019-10-10 16:55:43 +02:00
|
|
|
case "batchinstall":
|
|
|
|
config.BatchInstall = true
|
|
|
|
case "nobatchinstall":
|
|
|
|
config.BatchInstall = false
|
2018-07-30 05:49:17 +02:00
|
|
|
case "answerclean":
|
|
|
|
config.AnswerClean = value
|
|
|
|
case "noanswerclean":
|
|
|
|
config.AnswerClean = ""
|
|
|
|
case "answerdiff":
|
|
|
|
config.AnswerDiff = value
|
|
|
|
case "noanswerdiff":
|
|
|
|
config.AnswerDiff = ""
|
|
|
|
case "answeredit":
|
|
|
|
config.AnswerEdit = value
|
|
|
|
case "noansweredit":
|
|
|
|
config.AnswerEdit = ""
|
|
|
|
case "answerupgrade":
|
|
|
|
config.AnswerUpgrade = value
|
|
|
|
case "noanswerupgrade":
|
|
|
|
config.AnswerUpgrade = ""
|
|
|
|
case "gpgflags":
|
|
|
|
config.GpgFlags = value
|
|
|
|
case "mflags":
|
|
|
|
config.MFlags = value
|
|
|
|
case "gitflags":
|
|
|
|
config.GitFlags = value
|
|
|
|
case "builddir":
|
|
|
|
config.BuildDir = value
|
2019-10-18 09:39:37 +02:00
|
|
|
case "absdir":
|
|
|
|
config.ABSDir = value
|
2018-07-30 05:49:17 +02:00
|
|
|
case "editor":
|
|
|
|
config.Editor = value
|
|
|
|
case "editorflags":
|
|
|
|
config.EditorFlags = value
|
|
|
|
case "makepkg":
|
|
|
|
config.MakepkgBin = value
|
|
|
|
case "makepkgconf":
|
|
|
|
config.MakepkgConf = value
|
|
|
|
case "nomakepkgconf":
|
|
|
|
config.MakepkgConf = ""
|
|
|
|
case "pacman":
|
|
|
|
config.PacmanBin = value
|
|
|
|
case "git":
|
|
|
|
config.GitBin = value
|
|
|
|
case "gpg":
|
|
|
|
config.GpgBin = value
|
2019-03-19 22:10:58 +01:00
|
|
|
case "sudo":
|
|
|
|
config.SudoBin = value
|
|
|
|
case "sudoflags":
|
|
|
|
config.SudoFlags = value
|
2018-07-30 05:49:17 +02:00
|
|
|
case "requestsplitn":
|
|
|
|
n, err := strconv.Atoi(value)
|
|
|
|
if err == nil && n > 0 {
|
|
|
|
config.RequestSplitN = n
|
|
|
|
}
|
|
|
|
case "sudoloop":
|
|
|
|
config.SudoLoop = true
|
|
|
|
case "nosudoloop":
|
|
|
|
config.SudoLoop = false
|
|
|
|
case "provides":
|
|
|
|
config.Provides = true
|
|
|
|
case "noprovides":
|
|
|
|
config.Provides = false
|
|
|
|
case "pgpfetch":
|
|
|
|
config.PGPFetch = true
|
|
|
|
case "nopgpfetch":
|
|
|
|
config.PGPFetch = false
|
|
|
|
case "upgrademenu":
|
|
|
|
config.UpgradeMenu = true
|
|
|
|
case "noupgrademenu":
|
|
|
|
config.UpgradeMenu = false
|
|
|
|
case "cleanmenu":
|
|
|
|
config.CleanMenu = true
|
|
|
|
case "nocleanmenu":
|
|
|
|
config.CleanMenu = false
|
|
|
|
case "diffmenu":
|
|
|
|
config.DiffMenu = true
|
|
|
|
case "nodiffmenu":
|
|
|
|
config.DiffMenu = false
|
|
|
|
case "editmenu":
|
|
|
|
config.EditMenu = true
|
|
|
|
case "noeditmenu":
|
|
|
|
config.EditMenu = false
|
|
|
|
case "useask":
|
|
|
|
config.UseAsk = true
|
|
|
|
case "nouseask":
|
|
|
|
config.UseAsk = false
|
|
|
|
case "combinedupgrade":
|
|
|
|
config.CombinedUpgrade = true
|
|
|
|
case "nocombinedupgrade":
|
|
|
|
config.CombinedUpgrade = false
|
|
|
|
case "a", "aur":
|
2020-07-05 02:45:23 +02:00
|
|
|
config.Runtime.Mode = ModeAUR
|
2018-07-30 05:49:17 +02:00
|
|
|
case "repo":
|
2020-07-05 02:45:23 +02:00
|
|
|
config.Runtime.Mode = ModeRepo
|
2018-07-30 05:49:17 +02:00
|
|
|
case "removemake":
|
|
|
|
config.RemoveMake = "yes"
|
|
|
|
case "noremovemake":
|
|
|
|
config.RemoveMake = "no"
|
|
|
|
case "askremovemake":
|
|
|
|
config.RemoveMake = "ask"
|
|
|
|
default:
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
return true
|
2018-07-30 05:38:06 +02:00
|
|
|
}
|
|
|
|
|
2017-12-31 16:18:12 +01:00
|
|
|
func isOp(op string) bool {
|
|
|
|
switch op {
|
|
|
|
case "V", "version":
|
|
|
|
case "D", "database":
|
|
|
|
case "F", "files":
|
|
|
|
case "Q", "query":
|
|
|
|
case "R", "remove":
|
|
|
|
case "S", "sync":
|
|
|
|
case "T", "deptest":
|
|
|
|
case "U", "upgrade":
|
2018-07-30 05:49:17 +02:00
|
|
|
// yay specific
|
2017-12-31 16:18:12 +01:00
|
|
|
case "Y", "yay":
|
2018-08-02 22:58:03 +02:00
|
|
|
case "P", "show":
|
2018-01-03 05:55:47 +01:00
|
|
|
case "G", "getpkgbuild":
|
|
|
|
default:
|
|
|
|
return false
|
|
|
|
}
|
2018-07-30 05:49:17 +02:00
|
|
|
|
|
|
|
return true
|
2018-01-03 05:55:47 +01:00
|
|
|
}
|
|
|
|
|
2018-01-04 07:01:17 +01:00
|
|
|
func isGlobal(op string) bool {
|
|
|
|
switch op {
|
|
|
|
case "b", "dbpath":
|
|
|
|
case "r", "root":
|
|
|
|
case "v", "verbose":
|
|
|
|
case "arch":
|
|
|
|
case "cachedir":
|
|
|
|
case "color":
|
|
|
|
case "config":
|
|
|
|
case "debug":
|
|
|
|
case "gpgdir":
|
|
|
|
case "hookdir":
|
|
|
|
case "logfile":
|
|
|
|
case "noconfirm":
|
|
|
|
case "confirm":
|
|
|
|
default:
|
|
|
|
return false
|
|
|
|
}
|
2018-07-30 05:49:17 +02:00
|
|
|
|
|
|
|
return true
|
2018-01-04 07:01:17 +01:00
|
|
|
}
|
|
|
|
|
2017-12-31 16:18:12 +01:00
|
|
|
func hasParam(arg string) bool {
|
|
|
|
switch arg {
|
|
|
|
case "dbpath", "b":
|
|
|
|
case "root", "r":
|
|
|
|
case "sysroot":
|
|
|
|
case "config":
|
|
|
|
case "ignore":
|
|
|
|
case "assume-installed":
|
|
|
|
case "overwrite":
|
|
|
|
case "ask":
|
|
|
|
case "cachedir":
|
|
|
|
case "hookdir":
|
|
|
|
case "logfile":
|
|
|
|
case "ignoregroup":
|
|
|
|
case "arch":
|
|
|
|
case "print-format":
|
|
|
|
case "gpgdir":
|
|
|
|
case "color":
|
2020-05-02 16:17:20 +02:00
|
|
|
// yay params
|
2018-08-19 06:05:16 +02:00
|
|
|
case "aururl":
|
2018-03-07 18:12:30 +01:00
|
|
|
case "mflags":
|
2018-03-17 21:40:24 +01:00
|
|
|
case "gpgflags":
|
2018-03-29 01:36:53 +02:00
|
|
|
case "gitflags":
|
2018-03-08 02:36:06 +01:00
|
|
|
case "builddir":
|
2019-10-18 09:39:37 +02:00
|
|
|
case "absdir":
|
2018-03-08 02:36:06 +01:00
|
|
|
case "editor":
|
2018-04-09 21:50:18 +02:00
|
|
|
case "editorflags":
|
2018-03-08 02:36:06 +01:00
|
|
|
case "makepkg":
|
2018-07-18 01:53:53 +02:00
|
|
|
case "makepkgconf":
|
2018-03-08 02:36:06 +01:00
|
|
|
case "pacman":
|
|
|
|
case "git":
|
2018-03-17 21:40:24 +01:00
|
|
|
case "gpg":
|
2019-03-19 22:10:58 +01:00
|
|
|
case "sudo":
|
|
|
|
case "sudoflags":
|
2018-03-08 02:36:06 +01:00
|
|
|
case "requestsplitn":
|
2018-04-04 22:26:07 +02:00
|
|
|
case "answerclean":
|
2018-06-11 20:13:40 +02:00
|
|
|
case "answerdiff":
|
2018-04-04 22:26:07 +02:00
|
|
|
case "answeredit":
|
|
|
|
case "answerupgrade":
|
2018-07-24 15:42:43 +02:00
|
|
|
case "completioninterval":
|
2018-04-04 22:26:07 +02:00
|
|
|
case "sortby":
|
2019-10-10 18:40:38 +02:00
|
|
|
case "searchby":
|
2017-12-31 16:18:12 +01:00
|
|
|
default:
|
|
|
|
return false
|
|
|
|
}
|
2018-07-30 05:49:17 +02:00
|
|
|
|
|
|
|
return true
|
2017-12-31 16:18:12 +01:00
|
|
|
}
|
|
|
|
|
2018-03-03 03:45:16 +01:00
|
|
|
// Parses short hand options such as:
|
|
|
|
// -Syu -b/some/path -
|
2020-07-05 02:45:23 +02:00
|
|
|
func (parser *Arguments) parseShortOption(arg, param string) (usedNext bool, err error) {
|
2017-12-31 16:18:12 +01:00
|
|
|
if arg == "-" {
|
2020-07-05 02:45:23 +02:00
|
|
|
err = parser.AddArg("-")
|
2017-12-31 16:18:12 +01:00
|
|
|
return
|
|
|
|
}
|
2018-01-19 15:51:18 +01:00
|
|
|
|
2017-12-31 16:18:12 +01:00
|
|
|
arg = arg[1:]
|
2018-01-19 15:51:18 +01:00
|
|
|
|
2017-12-31 16:18:12 +01:00
|
|
|
for k, _char := range arg {
|
|
|
|
char := string(_char)
|
2018-01-19 15:51:18 +01:00
|
|
|
|
2018-08-02 15:43:54 +02:00
|
|
|
if hasParam(char) {
|
|
|
|
if k < len(arg)-1 {
|
|
|
|
err = parser.addParam(char, arg[k+1:])
|
2017-12-31 16:18:12 +01:00
|
|
|
} else {
|
|
|
|
usedNext = true
|
|
|
|
err = parser.addParam(char, param)
|
|
|
|
}
|
2018-01-19 15:51:18 +01:00
|
|
|
|
2017-12-31 16:18:12 +01:00
|
|
|
break
|
|
|
|
} else {
|
2020-07-05 02:45:23 +02:00
|
|
|
err = parser.AddArg(char)
|
2018-01-19 15:51:18 +01:00
|
|
|
|
2017-12-31 16:18:12 +01:00
|
|
|
if err != nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2018-03-03 03:45:16 +01:00
|
|
|
// Parses full length options such as:
|
|
|
|
// --sync --refresh --sysupgrade --dbpath /some/path --
|
2020-07-05 02:45:23 +02:00
|
|
|
func (parser *Arguments) parseLongOption(arg, param string) (usedNext bool, err error) {
|
2017-12-31 16:18:12 +01:00
|
|
|
if arg == "--" {
|
2020-07-05 02:45:23 +02:00
|
|
|
err = parser.AddArg(arg)
|
2017-12-31 16:18:12 +01:00
|
|
|
return
|
|
|
|
}
|
2018-01-19 15:51:18 +01:00
|
|
|
|
2017-12-31 16:18:12 +01:00
|
|
|
arg = arg[2:]
|
2018-01-19 15:51:18 +01:00
|
|
|
|
2019-03-07 21:02:44 +01:00
|
|
|
switch split := strings.SplitN(arg, "=", 2); {
|
|
|
|
case len(split) == 2:
|
2018-08-08 17:03:39 +02:00
|
|
|
err = parser.addParam(split[0], split[1])
|
2019-03-07 21:02:44 +01:00
|
|
|
case hasParam(arg):
|
2017-12-31 16:18:12 +01:00
|
|
|
err = parser.addParam(arg, param)
|
|
|
|
usedNext = true
|
2019-03-07 21:02:44 +01:00
|
|
|
default:
|
2020-07-05 02:45:23 +02:00
|
|
|
err = parser.AddArg(arg)
|
2017-12-31 16:18:12 +01:00
|
|
|
}
|
2018-01-19 15:51:18 +01:00
|
|
|
|
2017-12-31 16:18:12 +01:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2020-07-05 02:45:23 +02:00
|
|
|
func (parser *Arguments) parseStdin() error {
|
2018-07-30 02:16:36 +02:00
|
|
|
scanner := bufio.NewScanner(os.Stdin)
|
|
|
|
scanner.Split(bufio.ScanLines)
|
2018-01-19 15:51:18 +01:00
|
|
|
|
2018-07-30 02:16:36 +02:00
|
|
|
for scanner.Scan() {
|
2020-07-05 02:45:23 +02:00
|
|
|
parser.AddTarget(scanner.Text())
|
2017-12-31 16:18:12 +01:00
|
|
|
}
|
2018-07-30 02:16:36 +02:00
|
|
|
|
|
|
|
return os.Stdin.Close()
|
2017-12-31 16:18:12 +01:00
|
|
|
}
|
|
|
|
|
2020-07-05 02:45:23 +02:00
|
|
|
func (parser *Arguments) ParseCommandLine(config *Configuration) error {
|
2017-12-31 16:18:12 +01:00
|
|
|
args := os.Args[1:]
|
|
|
|
usedNext := false
|
2018-01-19 15:51:18 +01:00
|
|
|
|
2017-12-31 16:18:12 +01:00
|
|
|
if len(args) < 1 {
|
2020-05-02 16:17:20 +02:00
|
|
|
if _, err := parser.parseShortOption("-Syu", ""); err != nil {
|
|
|
|
return err
|
2019-10-13 13:15:51 +02:00
|
|
|
}
|
2018-03-31 22:55:15 +02:00
|
|
|
} else {
|
|
|
|
for k, arg := range args {
|
|
|
|
var nextArg string
|
2018-01-19 15:51:18 +01:00
|
|
|
|
2018-03-31 22:55:15 +02:00
|
|
|
if usedNext {
|
|
|
|
usedNext = false
|
|
|
|
continue
|
|
|
|
}
|
2018-01-19 15:51:18 +01:00
|
|
|
|
2018-03-31 22:55:15 +02:00
|
|
|
if k+1 < len(args) {
|
|
|
|
nextArg = args[k+1]
|
|
|
|
}
|
2018-01-19 15:51:18 +01:00
|
|
|
|
2020-05-02 16:17:20 +02:00
|
|
|
var err error
|
2019-03-07 21:02:44 +01:00
|
|
|
switch {
|
2020-07-05 02:45:23 +02:00
|
|
|
case parser.ExistsArg("--"):
|
|
|
|
parser.AddTarget(arg)
|
2019-03-07 21:02:44 +01:00
|
|
|
case strings.HasPrefix(arg, "--"):
|
2018-03-31 22:55:15 +02:00
|
|
|
usedNext, err = parser.parseLongOption(arg, nextArg)
|
2019-03-07 21:02:44 +01:00
|
|
|
case strings.HasPrefix(arg, "-"):
|
2018-03-31 22:55:15 +02:00
|
|
|
usedNext, err = parser.parseShortOption(arg, nextArg)
|
2019-03-07 21:02:44 +01:00
|
|
|
default:
|
2020-07-05 02:45:23 +02:00
|
|
|
parser.AddTarget(arg)
|
2018-03-31 22:55:15 +02:00
|
|
|
}
|
2018-01-19 15:51:18 +01:00
|
|
|
|
2018-03-31 22:55:15 +02:00
|
|
|
if err != nil {
|
2020-05-02 16:17:20 +02:00
|
|
|
return err
|
2018-03-31 22:55:15 +02:00
|
|
|
}
|
2017-12-31 16:18:12 +01:00
|
|
|
}
|
|
|
|
}
|
2018-01-19 15:51:18 +01:00
|
|
|
|
2020-07-05 02:45:23 +02:00
|
|
|
if parser.Op == "" {
|
|
|
|
parser.Op = "Y"
|
2017-12-31 16:18:12 +01:00
|
|
|
}
|
2018-01-19 15:51:18 +01:00
|
|
|
|
2020-07-05 02:45:23 +02:00
|
|
|
if parser.ExistsArg("-") {
|
2020-05-02 16:17:20 +02:00
|
|
|
if err := parser.parseStdin(); err != nil {
|
|
|
|
return err
|
2018-01-04 22:21:39 +01:00
|
|
|
}
|
2020-07-05 02:45:23 +02:00
|
|
|
parser.DelArg("-")
|
2018-03-12 01:04:50 +01:00
|
|
|
|
2020-05-02 16:17:20 +02:00
|
|
|
file, err := os.Open("/dev/tty")
|
2018-03-12 01:04:50 +01:00
|
|
|
if err != nil {
|
2020-05-02 16:17:20 +02:00
|
|
|
return err
|
2018-03-12 01:04:50 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
os.Stdin = file
|
2018-01-04 22:21:39 +01:00
|
|
|
}
|
2018-01-19 15:51:18 +01:00
|
|
|
|
2020-07-05 02:45:23 +02:00
|
|
|
parser.extractYayOptions(config)
|
2020-05-02 16:17:20 +02:00
|
|
|
return nil
|
2018-01-19 15:51:18 +01:00
|
|
|
}
|
2018-03-09 03:03:04 +01:00
|
|
|
|
2020-07-05 02:45:23 +02:00
|
|
|
func (parser *Arguments) extractYayOptions(config *Configuration) {
|
|
|
|
for option, value := range parser.Options {
|
|
|
|
if handleConfig(config, option, value) {
|
|
|
|
parser.DelArg(option)
|
2018-07-28 20:51:19 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-07-05 02:45:23 +02:00
|
|
|
for option, value := range parser.Globals {
|
|
|
|
if handleConfig(config, option, value) {
|
|
|
|
parser.DelArg(option)
|
2018-07-28 20:51:19 +02:00
|
|
|
}
|
|
|
|
}
|
2018-08-19 06:53:32 +02:00
|
|
|
|
|
|
|
rpc.AURURL = strings.TrimRight(config.AURURL, "/") + "/rpc.php?"
|
|
|
|
config.AURURL = strings.TrimRight(config.AURURL, "/")
|
2018-07-28 20:51:19 +02:00
|
|
|
}
|