mirror of
https://github.com/Jguer/yay.git
synced 2024-11-06 09:07:21 +01:00
Merge pull request #227 from Morganamilo/numbermenu
Use numbermenu for cleanBuilds and editPkgbuilds
This commit is contained in:
commit
c072146190
159
cmd.go
159
cmd.go
@ -4,7 +4,6 @@ import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
@ -525,72 +524,8 @@ func handleRemove() (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
// BuildIntRange build the range from start to end
|
||||
func BuildIntRange(rangeStart, rangeEnd int) []int {
|
||||
if rangeEnd-rangeStart == 0 {
|
||||
// rangeEnd == rangeStart, which means no range
|
||||
return []int{rangeStart}
|
||||
}
|
||||
if rangeEnd < rangeStart {
|
||||
swap := rangeEnd
|
||||
rangeEnd = rangeStart
|
||||
rangeStart = swap
|
||||
}
|
||||
|
||||
final := make([]int, 0)
|
||||
for i := rangeStart; i <= rangeEnd; i++ {
|
||||
final = append(final, i)
|
||||
}
|
||||
return final
|
||||
}
|
||||
|
||||
// BuildRange construct a range of ints from the format 1-10
|
||||
func BuildRange(input string) ([]int, error) {
|
||||
multipleNums := strings.Split(input, "-")
|
||||
if len(multipleNums) != 2 {
|
||||
return nil, errors.New("Invalid range")
|
||||
}
|
||||
|
||||
rangeStart, err := strconv.Atoi(multipleNums[0])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
rangeEnd, err := strconv.Atoi(multipleNums[1])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return BuildIntRange(rangeStart, rangeEnd), err
|
||||
}
|
||||
|
||||
// Contains returns whether e is present in s
|
||||
func contains(s []string, e string) bool {
|
||||
for _, a := range s {
|
||||
if a == e {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// RemoveIntListFromList removes all src's elements that are present in target
|
||||
func removeListFromList(src, target []string) []string {
|
||||
max := len(target)
|
||||
for i := 0; i < max; i++ {
|
||||
if contains(src, target[i]) {
|
||||
target = append(target[:i], target[i+1:]...)
|
||||
max--
|
||||
i--
|
||||
}
|
||||
}
|
||||
return target
|
||||
}
|
||||
|
||||
// NumberMenu presents a CLI for selecting packages to install.
|
||||
func numberMenu(pkgS []string, flags []string) (err error) {
|
||||
//func numberMenu(cmdArgs *arguments) (err error) {
|
||||
var num int
|
||||
|
||||
aurQ, err := narrowSearch(pkgS, true)
|
||||
if err != nil {
|
||||
fmt.Println("Error during AUR search:", err)
|
||||
@ -615,83 +550,55 @@ func numberMenu(pkgS []string, flags []string) (err error) {
|
||||
|
||||
fmt.Println(bold(green(arrow + " Packages to install (eg: 1 2 3, 1-3 or ^4)")))
|
||||
fmt.Print(bold(green(arrow + " ")))
|
||||
|
||||
reader := bufio.NewReader(os.Stdin)
|
||||
numberBuf, overflow, err := reader.ReadLine()
|
||||
if err != nil || overflow {
|
||||
fmt.Println(err)
|
||||
return
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
numberString := string(numberBuf)
|
||||
var aurI, aurNI, repoNI, repoI []string
|
||||
result := strings.Fields(numberString)
|
||||
for _, numS := range result {
|
||||
negate := numS[0] == '^'
|
||||
if negate {
|
||||
numS = numS[1:]
|
||||
}
|
||||
var numbers []int
|
||||
num, err = strconv.Atoi(numS)
|
||||
if err != nil {
|
||||
numbers, err = BuildRange(numS)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
} else {
|
||||
numbers = []int{num}
|
||||
if overflow {
|
||||
return fmt.Errorf("Input too long")
|
||||
}
|
||||
|
||||
include, exclude, _, otherExclude := parseNumberMenu(string(numberBuf))
|
||||
arguments := makeArguments()
|
||||
|
||||
isInclude := len(exclude) == 0 && len(otherExclude) == 0
|
||||
|
||||
for i, pkg := range repoQ {
|
||||
target := len(repoQ) - i
|
||||
if config.SortMode == TopDown {
|
||||
target = i + 1
|
||||
}
|
||||
|
||||
// Install package
|
||||
for _, x := range numbers {
|
||||
var target string
|
||||
if x > numaq+numpq || x <= 0 {
|
||||
continue
|
||||
} else if x > numpq {
|
||||
if config.SortMode == BottomUp {
|
||||
target = aurQ[numaq+numpq-x].Name
|
||||
} else {
|
||||
target = aurQ[x-numpq-1].Name
|
||||
}
|
||||
if negate {
|
||||
aurNI = append(aurNI, target)
|
||||
} else {
|
||||
aurI = append(aurI, target)
|
||||
}
|
||||
} else {
|
||||
if config.SortMode == BottomUp {
|
||||
target = repoQ[numpq-x].Name()
|
||||
} else {
|
||||
target = repoQ[x-1].Name()
|
||||
}
|
||||
if negate {
|
||||
repoNI = append(repoNI, target)
|
||||
} else {
|
||||
repoI = append(repoI, target)
|
||||
}
|
||||
}
|
||||
if isInclude && include.get(target) {
|
||||
arguments.addTarget(pkg.Name())
|
||||
}
|
||||
if !isInclude && !exclude.get(target) {
|
||||
arguments.addTarget(pkg.Name())
|
||||
}
|
||||
}
|
||||
|
||||
if len(repoI) == 0 && len(aurI) == 0 &&
|
||||
(len(aurNI) > 0 || len(repoNI) > 0) {
|
||||
// If no package was specified, only exclusions, exclude from all the
|
||||
// packages
|
||||
for _, pack := range aurQ {
|
||||
aurI = append(aurI, pack.Name)
|
||||
for i, pkg := range aurQ {
|
||||
target := len(aurQ) - i + len(repoQ)
|
||||
if config.SortMode == TopDown {
|
||||
target = i + 1 + len(repoQ)
|
||||
}
|
||||
for _, pack := range repoQ {
|
||||
repoI = append(repoI, pack.Name())
|
||||
|
||||
if isInclude && include.get(target) {
|
||||
arguments.addTarget(pkg.Name)
|
||||
}
|
||||
if !isInclude && !exclude.get(target) {
|
||||
arguments.addTarget(pkg.Name)
|
||||
}
|
||||
}
|
||||
aurI = removeListFromList(aurNI, aurI)
|
||||
repoI = removeListFromList(repoNI, repoI)
|
||||
|
||||
if config.SudoLoop {
|
||||
sudoLoopBackground()
|
||||
}
|
||||
arguments := makeArguments()
|
||||
arguments.addTarget(repoI...)
|
||||
arguments.addTarget(aurI...)
|
||||
|
||||
err = install(arguments)
|
||||
|
||||
return err
|
||||
|
208
install.go
208
install.go
@ -1,6 +1,7 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
@ -118,6 +119,13 @@ func install(parser *arguments) error {
|
||||
printDepCatagories(dc)
|
||||
hasAur = len(dc.Aur) != 0
|
||||
fmt.Println()
|
||||
|
||||
if !parser.existsArg("gendb") {
|
||||
err = checkForConflicts(dc)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if !parser.existsArg("gendb") && len(arguments.targets) > 0 {
|
||||
@ -145,36 +153,31 @@ func install(parser *arguments) error {
|
||||
}
|
||||
|
||||
if hasAur {
|
||||
if !parser.existsArg("gendb") {
|
||||
err = checkForConflicts(dc)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if len(dc.MakeOnly) > 0 {
|
||||
if !continueTask("Remove make dependencies after install?", "yY") {
|
||||
removeMake = true
|
||||
}
|
||||
}
|
||||
|
||||
askCleanBuilds(dc.Aur, dc.Bases)
|
||||
|
||||
if !continueTask("Proceed with Download?", "nN") {
|
||||
return fmt.Errorf("Aborting due to user")
|
||||
toClean, toEdit, err := cleanEditNumberMenu(dc.Aur, dc.Bases, remoteNamesCache)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cleanBuilds(toClean)
|
||||
|
||||
err = downloadPkgBuilds(dc.Aur, parser.targets, dc.Bases)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = askEditPkgBuilds(dc.Aur, dc.Bases)
|
||||
if err != nil {
|
||||
return err
|
||||
if len(toEdit) > 0 {
|
||||
err = editPkgBuilds(toEdit)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if !continueTask("Proceed with install?", "nN") {
|
||||
if len(toEdit) > 0 && !continueTask("Proceed with install?", "nN") {
|
||||
return fmt.Errorf("Aborting due to user")
|
||||
}
|
||||
|
||||
@ -244,6 +247,154 @@ func install(parser *arguments) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func cleanEditNumberMenu(pkgs []*rpc.Pkg, bases map[string][]*rpc.Pkg, installed stringSet) ([]*rpc.Pkg, []*rpc.Pkg, error) {
|
||||
toPrint := ""
|
||||
askClean := false
|
||||
|
||||
toClean := make([]*rpc.Pkg, 0)
|
||||
toEdit := make([]*rpc.Pkg, 0)
|
||||
|
||||
if config.NoConfirm {
|
||||
return toClean, toEdit, nil
|
||||
}
|
||||
|
||||
for n, pkg := range pkgs {
|
||||
dir := config.BuildDir + pkg.PackageBase + "/"
|
||||
|
||||
toPrint += magenta(strconv.Itoa(len(pkgs)-n)) + " " + bold(formatPkgbase(pkg, bases))
|
||||
if installed.get(pkg.Name) {
|
||||
toPrint += bold(green(" (Installed)"))
|
||||
}
|
||||
|
||||
if _, err := os.Stat(dir); !os.IsNotExist(err) {
|
||||
toPrint += bold(green(" (Build Files Exist)"))
|
||||
askClean = true
|
||||
}
|
||||
|
||||
toPrint += "\n"
|
||||
}
|
||||
|
||||
fmt.Print(toPrint)
|
||||
|
||||
if askClean {
|
||||
fmt.Println(bold(green(arrow+" Packages to cleanBuild?")))
|
||||
fmt.Println(bold(green(arrow) + cyan(" [N]one ") + green("[A]ll [Ab]ort [I]nstalled [No]tInstalled or (1 2 3, 1-3, ^4)")))
|
||||
fmt.Print(bold(green(arrow + " ")))
|
||||
reader := bufio.NewReader(os.Stdin)
|
||||
|
||||
numberBuf, overflow, err := reader.ReadLine()
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
if overflow {
|
||||
return nil, nil, fmt.Errorf("Input too long")
|
||||
}
|
||||
|
||||
cleanInput := string(numberBuf)
|
||||
|
||||
cInclude, cExclude, cOtherInclude, cOtherExclude := parseNumberMenu(cleanInput)
|
||||
cIsInclude := len(cExclude) == 0 && len(cOtherExclude) == 0
|
||||
|
||||
if cOtherInclude.get("abort") || cOtherInclude.get("ab") {
|
||||
return nil, nil, fmt.Errorf("Aborting due to user")
|
||||
}
|
||||
|
||||
if !cOtherInclude.get("n") && !cOtherInclude.get("none") {
|
||||
for i, pkg := range pkgs {
|
||||
dir := config.BuildDir + pkg.PackageBase + "/"
|
||||
if _, err := os.Stat(dir); os.IsNotExist(err) {
|
||||
continue
|
||||
}
|
||||
|
||||
if !cIsInclude && cExclude.get(len(pkgs)-i) {
|
||||
continue
|
||||
}
|
||||
|
||||
if installed.get(pkg.Name) && (cOtherInclude.get("i") || cOtherInclude.get("installed")) {
|
||||
toClean = append(toClean, pkg)
|
||||
continue
|
||||
}
|
||||
|
||||
if !installed.get(pkg.Name) && (cOtherInclude.get("no") || cOtherInclude.get("notinstalled")) {
|
||||
toClean = append(toClean, pkg)
|
||||
continue
|
||||
}
|
||||
|
||||
if cOtherInclude.get("a") || cOtherInclude.get("all") {
|
||||
toClean = append(toClean, pkg)
|
||||
continue
|
||||
}
|
||||
|
||||
if cIsInclude && cInclude.get(len(pkgs)-i) {
|
||||
toClean = append(toClean, pkg)
|
||||
}
|
||||
|
||||
if !cIsInclude && !cExclude.get(len(pkgs)-i) {
|
||||
toClean = append(toClean, pkg)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Println(bold(green(arrow+" PKGBUILDs to edit?")))
|
||||
fmt.Println(bold(green(arrow) +cyan(" [N]one ") + green("[A]ll [Ab]ort [I]nstalled [No]tInstalled or (1 2 3, 1-3, ^4)")))
|
||||
|
||||
fmt.Print(bold(green(arrow + " ")))
|
||||
reader := bufio.NewReader(os.Stdin)
|
||||
|
||||
numberBuf, overflow, err := reader.ReadLine()
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
if overflow {
|
||||
return nil, nil, fmt.Errorf("Input too long")
|
||||
}
|
||||
|
||||
editInput := string(numberBuf)
|
||||
|
||||
eInclude, eExclude, eOtherInclude, eOtherExclude := parseNumberMenu(editInput)
|
||||
eIsInclude := len(eExclude) == 0 && len(eOtherExclude) == 0
|
||||
|
||||
if eOtherInclude.get("abort") || eOtherInclude.get("ab") {
|
||||
return nil, nil, fmt.Errorf("Aborting due to user")
|
||||
}
|
||||
|
||||
if !eOtherInclude.get("n") && !eOtherInclude.get("none") {
|
||||
for i, pkg := range pkgs {
|
||||
if !eIsInclude && eExclude.get(len(pkgs)-i) {
|
||||
continue
|
||||
}
|
||||
|
||||
if installed.get(pkg.Name) && (eOtherInclude.get("i") || eOtherInclude.get("installed")) {
|
||||
toEdit = append(toEdit, pkg)
|
||||
continue
|
||||
}
|
||||
|
||||
if !installed.get(pkg.Name) && (eOtherInclude.get("no") || eOtherInclude.get("notinstalled")) {
|
||||
toEdit = append(toEdit, pkg)
|
||||
continue
|
||||
}
|
||||
|
||||
if eOtherInclude.get("a") || eOtherInclude.get("all") {
|
||||
toEdit = append(toEdit, pkg)
|
||||
continue
|
||||
}
|
||||
|
||||
if eIsInclude && eInclude.get(len(pkgs)-i) {
|
||||
toEdit = append(toEdit, pkg)
|
||||
}
|
||||
|
||||
if !eIsInclude && !eExclude.get(len(pkgs)-i) {
|
||||
toEdit = append(toEdit, pkg)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return toClean, toEdit, nil
|
||||
}
|
||||
|
||||
func askCleanBuilds(pkgs []*rpc.Pkg, bases map[string][]*rpc.Pkg) {
|
||||
for _, pkg := range pkgs {
|
||||
dir := config.BuildDir + pkg.PackageBase + "/"
|
||||
@ -265,6 +416,14 @@ func askCleanBuilds(pkgs []*rpc.Pkg, bases map[string][]*rpc.Pkg) {
|
||||
}
|
||||
}
|
||||
|
||||
func cleanBuilds(pkgs []*rpc.Pkg) {
|
||||
for i, pkg := range pkgs {
|
||||
dir := config.BuildDir + pkg.PackageBase
|
||||
fmt.Printf(bold(cyan("::")+" Deleting (%d/%d): %s\n"), i+1, len(pkgs), dir)
|
||||
os.RemoveAll(dir)
|
||||
}
|
||||
}
|
||||
|
||||
func checkForConflicts(dc *depCatagories) error {
|
||||
localDb, err := alpmHandle.LocalDb()
|
||||
if err != nil {
|
||||
@ -308,6 +467,8 @@ func checkForConflicts(dc *depCatagories) error {
|
||||
|
||||
fmt.Println(str)
|
||||
}
|
||||
|
||||
fmt.Println()
|
||||
}
|
||||
|
||||
return nil
|
||||
@ -339,6 +500,23 @@ func askEditPkgBuilds(pkgs []*rpc.Pkg, bases map[string][]*rpc.Pkg) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func editPkgBuilds(pkgs []*rpc.Pkg) error {
|
||||
pkgbuilds := make([]string, 0, len(pkgs))
|
||||
for _, pkg := range pkgs {
|
||||
dir := config.BuildDir + pkg.PackageBase + "/"
|
||||
pkgbuilds = append(pkgbuilds, dir+"PKGBUILD")
|
||||
}
|
||||
|
||||
editcmd := exec.Command(editor(), pkgbuilds...)
|
||||
editcmd.Stdin, editcmd.Stdout, editcmd.Stderr = os.Stdin, os.Stdout, os.Stderr
|
||||
err := editcmd.Run()
|
||||
if err != nil {
|
||||
return fmt.Errorf("Editor did not exit successfully, Abotring: %s", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func parsesrcinfosFile(pkgs []*rpc.Pkg, srcinfos map[string]*gopkg.PKGBUILD, bases map[string][]*rpc.Pkg) error {
|
||||
for k, pkg := range pkgs {
|
||||
dir := config.BuildDir + pkg.PackageBase + "/"
|
||||
|
105
parser.go
105
parser.go
@ -4,6 +4,7 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
@ -38,6 +39,20 @@ func (set stringSet) toSlice() []string {
|
||||
return slice
|
||||
}
|
||||
|
||||
func SliceToStringSet(in []string) stringSet {
|
||||
set := make(stringSet)
|
||||
|
||||
for _, v := range in {
|
||||
set.set(v)
|
||||
}
|
||||
|
||||
return set
|
||||
}
|
||||
|
||||
func makeStringSet(in ...string) stringSet {
|
||||
return SliceToStringSet(in)
|
||||
}
|
||||
|
||||
// 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 {
|
||||
@ -554,3 +569,93 @@ func (parser *arguments) parseCommandLine() (err error) {
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
type intRange struct {
|
||||
min int
|
||||
max int
|
||||
}
|
||||
|
||||
func makeIntRange(min, max int) intRange {
|
||||
return intRange{
|
||||
min,
|
||||
max,
|
||||
}
|
||||
}
|
||||
|
||||
func (r intRange) get(n int) bool {
|
||||
return n >= r.min && n <= r.max
|
||||
}
|
||||
|
||||
type intRanges []intRange
|
||||
|
||||
func (rs intRanges) get(n int) bool {
|
||||
for _, r := range rs {
|
||||
if r.get(n) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
//parses input for number menus
|
||||
//supports individual selection: 1 2 3 4
|
||||
//supports range selections: 1-4 10-20
|
||||
//supports negation: ^1 ^1-4
|
||||
//
|
||||
//include and excule holds numbers that should be added and should not be added
|
||||
//respectively. other holds anythign 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
|
||||
func parseNumberMenu(input string) (intRanges, intRanges, stringSet, stringSet) {
|
||||
include := make(intRanges, 0, 0)
|
||||
exclude := make(intRanges, 0, 0)
|
||||
otherInclude := make(stringSet)
|
||||
otherExclude := make(stringSet)
|
||||
|
||||
words := strings.Fields(input)
|
||||
|
||||
for _, word := range words {
|
||||
var num1 int
|
||||
var num2 int
|
||||
var err error
|
||||
invert := false
|
||||
other := otherInclude
|
||||
|
||||
if word[0] == '^' {
|
||||
invert = true
|
||||
other = otherExclude
|
||||
word = word[1:]
|
||||
}
|
||||
|
||||
ranges := strings.SplitN(word, "-", 2)
|
||||
|
||||
num1, err = strconv.Atoi(ranges[0])
|
||||
if err != nil {
|
||||
other.set(strings.ToLower(word))
|
||||
continue
|
||||
}
|
||||
|
||||
if len(ranges) == 2 {
|
||||
num2, err = strconv.Atoi(ranges[1])
|
||||
if err != nil {
|
||||
other.set(strings.ToLower(word))
|
||||
continue
|
||||
}
|
||||
} else {
|
||||
num2 = num1
|
||||
}
|
||||
|
||||
mi := min(num1, num2)
|
||||
ma := max(num1, num2)
|
||||
|
||||
if !invert {
|
||||
include = append(include, makeIntRange(mi, ma))
|
||||
} else {
|
||||
exclude = append(exclude, makeIntRange(mi, ma))
|
||||
}
|
||||
}
|
||||
|
||||
return include, exclude, otherInclude, otherExclude
|
||||
}
|
||||
|
99
parser_test.go
Normal file
99
parser_test.go
Normal file
@ -0,0 +1,99 @@
|
||||
package main
|
||||
|
||||
import "testing"
|
||||
|
||||
func intRangesEqual(a, b intRanges) bool {
|
||||
if a == nil && b == nil {
|
||||
return true
|
||||
}
|
||||
|
||||
if a == nil || b == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
if len(a) != len(b) {
|
||||
return false
|
||||
}
|
||||
|
||||
for n := range a {
|
||||
r1 := a[n]
|
||||
r2 := b[n]
|
||||
|
||||
if r1.min != r1.min || r1.max != r2.max {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func stringSetEqual(a, b stringSet) bool {
|
||||
if a == nil && b == nil {
|
||||
return true
|
||||
}
|
||||
|
||||
if a == nil || b == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
if len(a) != len(b) {
|
||||
return false
|
||||
}
|
||||
|
||||
for n := range a {
|
||||
if !b.get(n) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func TestParseNumberMenu(t *testing.T) {
|
||||
type result struct {
|
||||
Include intRanges
|
||||
Exclude intRanges
|
||||
OtherInclude stringSet
|
||||
OtherExclude stringSet
|
||||
}
|
||||
|
||||
inputs := []string{
|
||||
"1 2 3 4 5",
|
||||
"1-10 5-15",
|
||||
"10-5 90-85",
|
||||
"1 ^2 ^10-5 99 ^40-38 ^123 60-62",
|
||||
"abort all none",
|
||||
"a-b ^a-b ^abort",
|
||||
"1\t2 3 4\t\t \t 5",
|
||||
"",
|
||||
" \t ",
|
||||
"A B C D E",
|
||||
}
|
||||
|
||||
expected := []result{
|
||||
{intRanges{makeIntRange(1, 1), makeIntRange(2, 2), makeIntRange(3, 3), makeIntRange(4, 4), makeIntRange(5, 5)}, intRanges{}, make(stringSet), make(stringSet)},
|
||||
{intRanges{makeIntRange(1, 10), makeIntRange(5, 15)}, intRanges{}, make(stringSet), make(stringSet)},
|
||||
{intRanges{makeIntRange(5, 10), makeIntRange(85, 90)}, intRanges{}, make(stringSet), make(stringSet)},
|
||||
{intRanges{makeIntRange(1, 1), makeIntRange(99, 99), makeIntRange(60, 62)}, intRanges{makeIntRange(2, 2), makeIntRange(5, 10), makeIntRange(38, 40), makeIntRange(123, 123)}, make(stringSet), make(stringSet)},
|
||||
{intRanges{}, intRanges{}, makeStringSet("abort", "all", "none"), make(stringSet)},
|
||||
{intRanges{}, intRanges{}, makeStringSet("a-b"), makeStringSet("abort", "a-b")},
|
||||
{intRanges{makeIntRange(1, 1), makeIntRange(2, 2), makeIntRange(3, 3), makeIntRange(4, 4), makeIntRange(5, 5)}, intRanges{}, make(stringSet), make(stringSet)},
|
||||
{intRanges{}, intRanges{}, make(stringSet), make(stringSet)},
|
||||
{intRanges{}, intRanges{}, make(stringSet), make(stringSet)},
|
||||
{intRanges{}, intRanges{}, makeStringSet("a", "b", "c", "d", "e"), make(stringSet)},
|
||||
}
|
||||
|
||||
for n, in := range inputs {
|
||||
res := expected[n]
|
||||
include, exclude, otherInclude, otherExclude := parseNumberMenu(in)
|
||||
|
||||
if !intRangesEqual(include, res.Include) ||
|
||||
!intRangesEqual(exclude, res.Exclude) ||
|
||||
!stringSetEqual(otherInclude, res.OtherInclude) ||
|
||||
!stringSetEqual(otherExclude, res.OtherExclude) {
|
||||
|
||||
t.Fatalf("Test %d Failed: Expected: include=%+v exclude=%+v otherInclude=%+v otherExclude=%+v got include=%+v excluive=%+v otherInclude=%+v otherExclude=%+v",
|
||||
n+1, res.Include, res.Exclude, res.OtherInclude, res.OtherExclude, include, exclude, otherInclude, otherExclude)
|
||||
}
|
||||
}
|
||||
}
|
6
print.go
6
print.go
@ -147,16 +147,16 @@ func printDepCatagories(dc *depCatagories) {
|
||||
|
||||
for _, pkg := range dc.Repo {
|
||||
if dc.MakeOnly.get(pkg.Name()) {
|
||||
repoMake += " " + pkg.Name()
|
||||
repoMake += " " + pkg.Name() + "-" + pkg.Version()
|
||||
repoMakeLen++
|
||||
} else {
|
||||
repo += " " + pkg.Name()
|
||||
repo += " " + pkg.Name() + "-" + pkg.Version()
|
||||
repoLen++
|
||||
}
|
||||
}
|
||||
|
||||
for _, pkg := range dc.Aur {
|
||||
pkgStr := " " + pkg.PackageBase
|
||||
pkgStr := " " + pkg.PackageBase + "-" + pkg.Version
|
||||
pkgStrMake := pkgStr
|
||||
|
||||
push := false
|
||||
|
7
query.go
7
query.go
@ -317,6 +317,13 @@ func min(a, b int) int {
|
||||
return b
|
||||
}
|
||||
|
||||
func max(a, b int) int {
|
||||
if a < b {
|
||||
return b
|
||||
}
|
||||
return a
|
||||
}
|
||||
|
||||
// Queries the aur for information about specified packages.
|
||||
// All packages should be queried in a single rpc request except when the number
|
||||
// of packages exceeds the number set in config.RequestSplitN.
|
||||
|
128
upgrade.go
128
upgrade.go
@ -5,8 +5,6 @@ import (
|
||||
"fmt"
|
||||
"os"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"unicode"
|
||||
|
||||
alpm "github.com/jguer/go-alpm"
|
||||
@ -266,8 +264,6 @@ func removeIntListFromList(src, target []int) []int {
|
||||
|
||||
// upgradePkgs handles updating the cache and installing updates.
|
||||
func upgradePkgs(dt *depTree) (stringSet, stringSet, error) {
|
||||
var repoNums []int
|
||||
var aurNums []int
|
||||
repoNames := make(stringSet)
|
||||
aurNames := make(stringSet)
|
||||
|
||||
@ -283,89 +279,61 @@ func upgradePkgs(dt *depTree) (stringSet, stringSet, error) {
|
||||
repoUp.Print(len(aurUp) + 1)
|
||||
aurUp.Print(1)
|
||||
|
||||
if !config.NoConfirm {
|
||||
fmt.Println(bold(green(arrow + " Packages to not upgrade (eg: 1 2 3, 1-3 or ^4)")))
|
||||
fmt.Print(bold(green(arrow + " ")))
|
||||
reader := bufio.NewReader(os.Stdin)
|
||||
|
||||
numberBuf, overflow, err := reader.ReadLine()
|
||||
if err != nil || overflow {
|
||||
fmt.Println(err)
|
||||
return repoNames, aurNames, err
|
||||
if config.NoConfirm {
|
||||
for _, up := range repoUp {
|
||||
repoNames.set(up.Name)
|
||||
}
|
||||
|
||||
result := strings.Fields(string(numberBuf))
|
||||
excludeAur := make([]int, 0)
|
||||
excludeRepo := make([]int, 0)
|
||||
for _, numS := range result {
|
||||
negate := numS[0] == '^'
|
||||
if negate {
|
||||
numS = numS[1:]
|
||||
}
|
||||
var numbers []int
|
||||
num, err := strconv.Atoi(numS)
|
||||
if err != nil {
|
||||
numbers, err = BuildRange(numS)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
} else {
|
||||
numbers = []int{num}
|
||||
}
|
||||
for _, target := range numbers {
|
||||
if target > len(aurUp)+len(repoUp) || target <= 0 {
|
||||
continue
|
||||
} else if target <= len(aurUp) {
|
||||
target = len(aurUp) - target
|
||||
if negate {
|
||||
excludeAur = append(excludeAur, target)
|
||||
} else {
|
||||
aurNums = append(aurNums, target)
|
||||
}
|
||||
} else {
|
||||
target = len(aurUp) + len(repoUp) - target
|
||||
if negate {
|
||||
excludeRepo = append(excludeRepo, target)
|
||||
} else {
|
||||
repoNums = append(repoNums, target)
|
||||
}
|
||||
}
|
||||
}
|
||||
for _, up := range aurUp {
|
||||
aurNames.set(up.Name)
|
||||
}
|
||||
if len(repoNums) == 0 && len(aurNums) == 0 &&
|
||||
(len(excludeRepo) > 0 || len(excludeAur) > 0) {
|
||||
if len(repoUp) > 0 {
|
||||
repoNums = BuildIntRange(0, len(repoUp)-1)
|
||||
}
|
||||
if len(aurUp) > 0 {
|
||||
aurNums = BuildIntRange(0, len(aurUp)-1)
|
||||
}
|
||||
}
|
||||
aurNums = removeIntListFromList(excludeAur, aurNums)
|
||||
repoNums = removeIntListFromList(excludeRepo, repoNums)
|
||||
return repoNames, aurNames, nil
|
||||
}
|
||||
|
||||
if len(repoUp) != 0 {
|
||||
repoloop:
|
||||
for i, k := range repoUp {
|
||||
for _, j := range repoNums {
|
||||
if j == i {
|
||||
continue repoloop
|
||||
}
|
||||
}
|
||||
repoNames.set(k.Name)
|
||||
fmt.Println(bold(green(arrow + " Packages to not upgrade (eg: 1 2 3, 1-3, ^4 or repo name)")))
|
||||
fmt.Print(bold(green(arrow + " ")))
|
||||
reader := bufio.NewReader(os.Stdin)
|
||||
|
||||
numberBuf, overflow, err := reader.ReadLine()
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
if overflow {
|
||||
return nil, nil, fmt.Errorf("Input too long")
|
||||
}
|
||||
|
||||
//upgrade menu asks you which packages to NOT upgrade so in this case
|
||||
//include and exclude are kind of swaped
|
||||
//include, exclude, other := parseNumberMenu(string(numberBuf))
|
||||
include, exclude, otherInclude, otherExclude := parseNumberMenu(string(numberBuf))
|
||||
|
||||
isInclude := len(exclude) == 0 && len(otherExclude) == 0
|
||||
|
||||
for i, pkg := range repoUp {
|
||||
if isInclude && otherInclude.get(pkg.Repository) {
|
||||
continue
|
||||
}
|
||||
|
||||
if isInclude && !include.get(len(repoUp)-i+len(aurUp)) {
|
||||
repoNames.set(pkg.Name)
|
||||
}
|
||||
|
||||
if !isInclude && (exclude.get(len(repoUp)-i+len(aurUp)) || otherExclude.get(pkg.Repository)) {
|
||||
repoNames.set(pkg.Name)
|
||||
}
|
||||
}
|
||||
|
||||
if len(aurUp) != 0 {
|
||||
aurloop:
|
||||
for i, k := range aurUp {
|
||||
for _, j := range aurNums {
|
||||
if j == i {
|
||||
continue aurloop
|
||||
}
|
||||
}
|
||||
aurNames.set(k.Name)
|
||||
for i, pkg := range aurUp {
|
||||
if isInclude && otherInclude.get(pkg.Repository) {
|
||||
continue
|
||||
}
|
||||
|
||||
if isInclude && !include.get(len(aurUp)-i) {
|
||||
aurNames.set(pkg.Name)
|
||||
}
|
||||
|
||||
if !isInclude && (exclude.get(len(aurUp)-i) || otherExclude.get(pkg.Repository)) {
|
||||
aurNames.set(pkg.Name)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -60,7 +60,7 @@ func TestParsing(t *testing.T) {
|
||||
branch != compare.Branch ||
|
||||
!isEqual(protocols, compare.Protocols) {
|
||||
|
||||
t.Fatalf("Expected url=%+v branch=%+v protocols=%+v\ngot url=%+v branch=%+v protocols=%+v", url, branch, protocols, compare.URL, compare.Branch, compare.Protocols)
|
||||
t.Fatalf("Test %d failed: Expected: url=%+v branch=%+v protocols=%+v\ngot url=%+v branch=%+v protocols=%+v", n+1, url, branch, protocols, compare.URL, compare.Branch, compare.Protocols)
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user