2017-04-29 17:12:12 +00:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"bufio"
|
2017-08-02 17:24:03 +00:00
|
|
|
"encoding/json"
|
2017-04-29 17:12:12 +00:00
|
|
|
"fmt"
|
2017-07-10 17:10:51 +00:00
|
|
|
"io"
|
2017-04-29 17:12:12 +00:00
|
|
|
"os"
|
2018-01-03 19:01:34 +00:00
|
|
|
"os/exec"
|
2017-10-16 14:38:51 +00:00
|
|
|
"path/filepath"
|
2017-04-29 17:12:12 +00:00
|
|
|
"strconv"
|
|
|
|
"strings"
|
2017-07-10 17:10:51 +00:00
|
|
|
"time"
|
2017-04-29 17:12:12 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
func usage() {
|
2018-01-03 04:55:47 +00:00
|
|
|
fmt.Println(`Usage:
|
|
|
|
yay <operation> [...]
|
|
|
|
yay <package(s)>
|
|
|
|
|
|
|
|
operations:
|
|
|
|
yay {-h --help}
|
|
|
|
yay {-V --version}
|
|
|
|
yay {-D --database} <options> <package(s)>
|
|
|
|
yay {-F --files} [options] [package(s)]
|
|
|
|
yay {-Q --query} [options] [package(s)]
|
|
|
|
yay {-R --remove} [options] <package(s)>
|
|
|
|
yay {-S --sync} [options] [package(s)]
|
|
|
|
yay {-T --deptest} [options] [package(s)]
|
|
|
|
yay {-U --upgrade} [options] <file(s)>
|
2017-10-19 02:30:37 +00:00
|
|
|
|
2018-01-03 04:55:47 +00:00
|
|
|
New operations:
|
|
|
|
yay {-Y --yay} [options] [package(s)]
|
|
|
|
yay {-G --getpkgbuild} [package(s)]
|
2017-10-19 02:30:37 +00:00
|
|
|
|
2018-01-03 04:55:47 +00:00
|
|
|
Permanent configuration options:
|
|
|
|
--topdown Shows repository's packages first and then aur's
|
|
|
|
--bottomup Shows aur's packages first and then repository's
|
|
|
|
--devel Check -git/-svn/-hg development version
|
|
|
|
--nodevel Disable development version checking
|
|
|
|
--afterclean Clean package sources after successful build
|
|
|
|
--noafterclean Disable package sources cleaning after successful build
|
|
|
|
--timeupdate Check package's modification date and version
|
|
|
|
--notimeupdate Check only package version change
|
2017-12-04 02:39:23 +00:00
|
|
|
|
2018-01-03 04:55:47 +00:00
|
|
|
Yay specific options:
|
|
|
|
--printconfig Prints current yay configuration
|
|
|
|
--stats Displays system information
|
|
|
|
--cleandeps Remove unneeded dependencies
|
|
|
|
--gendb Generates development package DB used for updating.
|
|
|
|
|
|
|
|
If no operation is provided -Y will be assumed
|
|
|
|
`)
|
2017-04-29 17:12:12 +00:00
|
|
|
}
|
|
|
|
|
2017-08-02 17:24:03 +00:00
|
|
|
func init() {
|
2017-10-18 02:12:16 +00:00
|
|
|
var configHome string // configHome handles config directory home
|
|
|
|
var cacheHome string // cacheHome handles cache home
|
2017-08-02 17:24:03 +00:00
|
|
|
var err error
|
2017-10-18 02:12:16 +00:00
|
|
|
|
|
|
|
if 0 == os.Geteuid() {
|
|
|
|
fmt.Println("Please avoid running yay as root/sudo.")
|
|
|
|
}
|
|
|
|
|
|
|
|
if configHome = os.Getenv("XDG_CONFIG_HOME"); configHome != "" {
|
2017-10-19 02:30:37 +00:00
|
|
|
if info, err := os.Stat(configHome); err == nil && info.IsDir() {
|
2017-10-18 02:12:16 +00:00
|
|
|
configHome = configHome + "/yay"
|
2017-10-16 14:38:51 +00:00
|
|
|
} else {
|
2017-10-18 02:12:16 +00:00
|
|
|
configHome = os.Getenv("HOME") + "/.config/yay"
|
2017-10-16 14:38:51 +00:00
|
|
|
}
|
|
|
|
} else {
|
2017-10-18 02:12:16 +00:00
|
|
|
configHome = os.Getenv("HOME") + "/.config/yay"
|
2017-10-16 14:38:51 +00:00
|
|
|
}
|
2017-08-02 17:24:03 +00:00
|
|
|
|
2017-10-18 02:12:16 +00:00
|
|
|
if cacheHome = os.Getenv("XDG_CACHE_HOME"); cacheHome != "" {
|
2017-10-19 02:30:37 +00:00
|
|
|
if info, err := os.Stat(cacheHome); err == nil && info.IsDir() {
|
2017-10-18 02:12:16 +00:00
|
|
|
cacheHome = cacheHome + "/yay"
|
|
|
|
} else {
|
|
|
|
cacheHome = os.Getenv("HOME") + "/.cache/yay"
|
|
|
|
}
|
|
|
|
} else {
|
2017-10-19 02:30:37 +00:00
|
|
|
cacheHome = os.Getenv("HOME") + "/.cache/yay"
|
2017-10-18 02:12:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
configFile = configHome + "/config.json"
|
|
|
|
vcsFile = configHome + "/yay_vcs.json"
|
|
|
|
completionFile = cacheHome + "/aur_"
|
|
|
|
|
|
|
|
////////////////
|
|
|
|
// yay config //
|
|
|
|
////////////////
|
|
|
|
defaultSettings(&config)
|
|
|
|
|
|
|
|
if _, err = os.Stat(configFile); os.IsNotExist(err) {
|
2017-10-19 02:56:19 +00:00
|
|
|
err = os.MkdirAll(filepath.Dir(configFile), 0755)
|
2017-10-16 14:38:51 +00:00
|
|
|
if err != nil {
|
2017-10-18 02:12:16 +00:00
|
|
|
fmt.Println("Unable to create config directory:", filepath.Dir(configFile), err)
|
2017-10-16 14:38:51 +00:00
|
|
|
os.Exit(2)
|
|
|
|
}
|
2017-08-02 17:24:03 +00:00
|
|
|
// Save the default config if nothing is found
|
|
|
|
config.saveConfig()
|
|
|
|
} else {
|
2017-12-04 06:24:20 +00:00
|
|
|
cfile, errf := os.OpenFile(configFile, os.O_RDWR|os.O_CREATE, 0644)
|
|
|
|
if errf != nil {
|
2017-08-02 17:24:03 +00:00
|
|
|
fmt.Println("Error reading config:", err)
|
|
|
|
} else {
|
2017-10-19 05:59:26 +00:00
|
|
|
defer cfile.Close()
|
|
|
|
decoder := json.NewDecoder(cfile)
|
2017-08-02 17:24:03 +00:00
|
|
|
err = decoder.Decode(&config)
|
|
|
|
if err != nil {
|
2017-10-18 02:12:16 +00:00
|
|
|
fmt.Println("Loading default Settings.\nError reading config:", err)
|
2017-08-02 17:24:03 +00:00
|
|
|
defaultSettings(&config)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-10-18 02:12:16 +00:00
|
|
|
/////////////////
|
|
|
|
// vcs config //
|
|
|
|
////////////////
|
2017-08-02 17:24:03 +00:00
|
|
|
updated = false
|
|
|
|
|
2017-10-19 05:59:26 +00:00
|
|
|
vfile, err := os.Open(vcsFile)
|
2017-10-19 02:30:37 +00:00
|
|
|
if err == nil {
|
2017-10-19 05:59:26 +00:00
|
|
|
defer vfile.Close()
|
|
|
|
decoder := json.NewDecoder(vfile)
|
2017-10-19 02:30:37 +00:00
|
|
|
_ = decoder.Decode(&savedInfo)
|
2017-08-02 17:24:03 +00:00
|
|
|
}
|
2017-10-18 02:12:16 +00:00
|
|
|
|
|
|
|
/////////////////
|
|
|
|
// alpm config //
|
|
|
|
/////////////////
|
2017-10-18 05:46:21 +00:00
|
|
|
alpmConf, err = readAlpmConfig(config.PacmanConf)
|
2017-10-18 02:12:16 +00:00
|
|
|
if err != nil {
|
|
|
|
fmt.Println("Unable to read Pacman conf", err)
|
|
|
|
os.Exit(1)
|
|
|
|
}
|
|
|
|
|
2017-10-18 05:46:21 +00:00
|
|
|
alpmHandle, err = alpmConf.CreateHandle()
|
2017-10-18 02:12:16 +00:00
|
|
|
if err != nil {
|
|
|
|
fmt.Println("Unable to CreateHandle", err)
|
|
|
|
os.Exit(1)
|
|
|
|
}
|
2017-08-02 17:24:03 +00:00
|
|
|
}
|
2017-04-29 17:12:12 +00:00
|
|
|
|
2017-12-31 15:18:12 +00:00
|
|
|
func main() {
|
2018-01-03 05:55:12 +00:00
|
|
|
status := run()
|
|
|
|
|
|
|
|
err := alpmHandle.Release()
|
|
|
|
if err != nil {
|
|
|
|
fmt.Println(err)
|
|
|
|
status = 1
|
|
|
|
}
|
|
|
|
|
|
|
|
os.Exit(status)
|
|
|
|
}
|
|
|
|
|
|
|
|
func run() (status int) {
|
2017-12-31 15:18:12 +00:00
|
|
|
var err error
|
|
|
|
var changedConfig bool
|
|
|
|
|
2018-01-04 00:59:57 +00:00
|
|
|
parser := makeArguments();
|
2017-12-31 15:18:12 +00:00
|
|
|
err = parser.parseCommandLine();
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
fmt.Println(err)
|
2018-01-03 05:55:12 +00:00
|
|
|
status = 1
|
|
|
|
return
|
2017-04-29 17:12:12 +00:00
|
|
|
}
|
2017-12-31 15:18:12 +00:00
|
|
|
|
|
|
|
if parser.existsArg("-") {
|
|
|
|
err = parser.parseStdin();
|
2017-04-29 17:12:12 +00:00
|
|
|
|
2017-12-31 15:18:12 +00:00
|
|
|
if err != nil {
|
|
|
|
fmt.Println(err)
|
2018-01-03 05:55:12 +00:00
|
|
|
status = 1
|
|
|
|
return
|
2017-10-25 08:16:35 +00:00
|
|
|
}
|
2017-12-31 15:18:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
changedConfig, err = handleCmd(parser)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
fmt.Println(err)
|
2018-01-03 05:55:12 +00:00
|
|
|
status = 1
|
|
|
|
//try continue onward
|
2017-12-31 15:18:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if updated {
|
|
|
|
err = saveVCSInfo()
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
fmt.Println(err)
|
2018-01-03 05:55:12 +00:00
|
|
|
status = 1
|
2017-04-29 17:12:12 +00:00
|
|
|
}
|
2017-12-31 15:18:12 +00:00
|
|
|
}
|
2017-04-29 17:12:12 +00:00
|
|
|
|
2017-12-31 15:18:12 +00:00
|
|
|
if changedConfig {
|
|
|
|
err = config.saveConfig()
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
fmt.Println(err)
|
2018-01-03 05:55:12 +00:00
|
|
|
status = 1
|
2017-04-29 17:12:12 +00:00
|
|
|
}
|
2017-12-31 15:18:12 +00:00
|
|
|
|
2017-04-29 17:12:12 +00:00
|
|
|
}
|
2018-01-03 05:55:12 +00:00
|
|
|
|
|
|
|
return
|
|
|
|
|
2017-12-31 15:18:12 +00:00
|
|
|
}
|
2017-04-29 17:12:12 +00:00
|
|
|
|
2018-01-03 05:55:12 +00:00
|
|
|
|
2018-01-04 00:59:57 +00:00
|
|
|
func handleCmd(parser *arguments) (changedConfig bool, err error) {
|
2017-12-31 15:18:12 +00:00
|
|
|
var _changedConfig bool
|
|
|
|
|
|
|
|
for option, _ := range parser.options {
|
|
|
|
_changedConfig, err = handleConfig(option)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return
|
2017-04-29 17:12:12 +00:00
|
|
|
}
|
2017-12-31 15:18:12 +00:00
|
|
|
|
|
|
|
if _changedConfig {
|
|
|
|
changedConfig = true
|
2017-04-29 17:12:12 +00:00
|
|
|
}
|
2017-12-31 15:18:12 +00:00
|
|
|
}
|
2017-04-29 17:12:12 +00:00
|
|
|
|
2017-12-31 15:18:12 +00:00
|
|
|
switch parser.op {
|
|
|
|
case "V", "version":
|
2018-01-03 18:42:40 +00:00
|
|
|
handleVersion(parser)
|
2017-12-31 15:18:12 +00:00
|
|
|
case "D", "database":
|
2018-01-03 18:42:40 +00:00
|
|
|
passToPacman(parser)
|
2017-12-31 15:18:12 +00:00
|
|
|
case "F", "files":
|
2018-01-03 18:42:40 +00:00
|
|
|
passToPacman(parser)
|
2017-12-31 15:18:12 +00:00
|
|
|
case "Q", "query":
|
2018-01-03 18:42:40 +00:00
|
|
|
passToPacman(parser)
|
2017-12-31 15:18:12 +00:00
|
|
|
case "R", "remove":
|
2018-01-04 00:59:57 +00:00
|
|
|
handleRemove(parser)
|
2017-12-31 15:18:12 +00:00
|
|
|
case "S", "sync":
|
|
|
|
err = handleSync(parser)
|
|
|
|
case "T", "deptest":
|
2018-01-03 18:42:40 +00:00
|
|
|
passToPacman(parser)
|
2017-12-31 15:18:12 +00:00
|
|
|
case "U", "upgrade":
|
2018-01-03 18:42:40 +00:00
|
|
|
passToPacman(parser)
|
2018-01-03 19:17:57 +00:00
|
|
|
case "G", "getpkgbuild":
|
|
|
|
err = handleGetpkgbuild(parser)
|
2017-12-31 15:18:12 +00:00
|
|
|
case "Y", "--yay":
|
2018-01-03 04:55:47 +00:00
|
|
|
err = handleYay(parser)
|
2017-12-31 15:18:12 +00:00
|
|
|
default:
|
|
|
|
//this means we allowed an op but not implement it
|
|
|
|
//if this happens it an error in the code and not the usage
|
|
|
|
err = fmt.Errorf("unhandled operation")
|
2017-07-24 09:32:11 +00:00
|
|
|
}
|
2017-12-31 15:18:12 +00:00
|
|
|
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
//this function should only set config options
|
|
|
|
//but currently still uses the switch left over from old code
|
|
|
|
//eventuall this should be refactored out futher
|
|
|
|
//my current plan is to have yay specific operations in its own operator
|
|
|
|
//e.g. yay -Y --gendb
|
|
|
|
//e.g yay -Yg
|
|
|
|
func handleConfig(option string) (changedConfig bool, err error) {
|
|
|
|
switch option {
|
|
|
|
case "afterclean":
|
|
|
|
config.CleanAfter = true
|
|
|
|
case "noafterclean":
|
|
|
|
config.CleanAfter = false
|
2018-01-03 04:55:47 +00:00
|
|
|
// case "printconfig":
|
|
|
|
// fmt.Printf("%#v", config)
|
|
|
|
// os.Exit(0)
|
|
|
|
// case "gendb":
|
|
|
|
// err = createDevelDB()
|
|
|
|
// if err != nil {
|
|
|
|
// fmt.Println(err)
|
|
|
|
// }
|
|
|
|
// err = saveVCSInfo()
|
|
|
|
// if err != nil {
|
|
|
|
// fmt.Println(err)
|
|
|
|
// }
|
|
|
|
// os.Exit(0)
|
2017-12-31 15:18:12 +00:00
|
|
|
case "devel":
|
|
|
|
config.Devel = true
|
|
|
|
case "nodevel":
|
|
|
|
config.Devel = false
|
|
|
|
case "timeupdate":
|
|
|
|
config.TimeUpdate = true
|
|
|
|
case "notimeupdate":
|
|
|
|
config.TimeUpdate = false
|
|
|
|
case "topdown":
|
|
|
|
config.SortMode = TopDown
|
2018-01-03 04:55:47 +00:00
|
|
|
// case "complete":
|
|
|
|
// config.Shell = "sh"
|
|
|
|
// complete()
|
|
|
|
// os.Exit(0)
|
|
|
|
// case "fcomplete":
|
|
|
|
// config.Shell = fishShell
|
|
|
|
// complete()
|
|
|
|
// os.Exit(0)
|
|
|
|
// case "help":
|
|
|
|
// usage()
|
|
|
|
// os.Exit(0)
|
|
|
|
// case "version":
|
|
|
|
// fmt.Printf("yay v%s\n", version)
|
|
|
|
// os.Exit(0)
|
2017-12-31 15:18:12 +00:00
|
|
|
case "noconfirm":
|
|
|
|
config.NoConfirm = true
|
|
|
|
default:
|
|
|
|
return
|
2017-07-19 09:32:32 +00:00
|
|
|
}
|
2017-12-31 15:18:12 +00:00
|
|
|
|
|
|
|
changedConfig = true
|
|
|
|
return
|
|
|
|
}
|
2017-04-29 17:12:12 +00:00
|
|
|
|
2018-01-04 00:59:57 +00:00
|
|
|
func handleVersion(parser *arguments) {
|
2018-01-03 04:55:47 +00:00
|
|
|
fmt.Printf("yay v%s\n", version)
|
|
|
|
}
|
|
|
|
|
2018-01-04 00:59:57 +00:00
|
|
|
func handleYay(parser *arguments) (err error) {
|
2018-01-03 04:55:47 +00:00
|
|
|
//_, options, targets := parser.formatArgs()
|
2018-01-04 00:59:57 +00:00
|
|
|
if parser.existsArg("h", "help") {
|
2018-01-03 04:55:47 +00:00
|
|
|
usage()
|
|
|
|
} else if parser.existsArg("printconfig") {
|
|
|
|
fmt.Printf("%#v", config)
|
|
|
|
} else if parser.existsArg("gendb") {
|
|
|
|
err = createDevelDB()
|
|
|
|
if err != nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
err = saveVCSInfo()
|
|
|
|
if err != nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
} else if parser.existsArg("complete") {
|
|
|
|
config.Shell = "sh"
|
|
|
|
complete()
|
|
|
|
} else if parser.existsArg("fcomplete") {
|
|
|
|
config.Shell = "fish"
|
|
|
|
complete()
|
|
|
|
} else if parser.existsArg("stats") {
|
|
|
|
err = localStatistics()
|
|
|
|
} else if parser.existsArg("cleandeps") {
|
2018-01-04 00:59:57 +00:00
|
|
|
err = cleanDependencies()
|
2018-01-03 04:55:47 +00:00
|
|
|
} else {
|
|
|
|
err = handleYogurt(parser)
|
|
|
|
}
|
|
|
|
|
|
|
|
return
|
2017-12-31 15:18:12 +00:00
|
|
|
}
|
2017-05-09 01:09:43 +00:00
|
|
|
|
2018-01-04 00:59:57 +00:00
|
|
|
func handleGetpkgbuild(parser *arguments) (err error) {
|
2018-01-03 19:17:57 +00:00
|
|
|
for pkg := range parser.targets {
|
|
|
|
err = getPkgbuild(pkg)
|
|
|
|
if err != nil {
|
|
|
|
//we print the error instead of returning it
|
|
|
|
//seems as we can handle multiple errors without stoping
|
|
|
|
//theres no easy way arround this right now
|
|
|
|
fmt.Println(pkg + ":", err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2018-01-04 00:59:57 +00:00
|
|
|
func handleYogurt(parser *arguments) (err error) {
|
|
|
|
options := parser.formatArgs()
|
|
|
|
targets := parser.formatTargets()
|
|
|
|
|
|
|
|
config.SearchMode = NumberMenu
|
|
|
|
err = numberMenu(targets, options)
|
|
|
|
|
2017-12-31 15:18:12 +00:00
|
|
|
return
|
|
|
|
}
|
2017-05-09 01:09:43 +00:00
|
|
|
|
2018-01-04 00:59:57 +00:00
|
|
|
func handleSync(parser *arguments) (err error) {
|
|
|
|
targets := parser.formatTargets()
|
|
|
|
options := parser.formatArgs()
|
|
|
|
|
|
|
|
if parser.existsArg("y", "refresh") {
|
|
|
|
arguments := makeArguments()
|
|
|
|
arguments.addArg("S", "y")
|
|
|
|
err = passToPacman(arguments)
|
|
|
|
if err != nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if parser.existsArg("s", "search") {
|
|
|
|
if parser.existsArg("q", "quiet") {
|
|
|
|
config.SearchMode = Minimal
|
|
|
|
} else {
|
|
|
|
config.SearchMode = Detailed
|
|
|
|
}
|
|
|
|
|
|
|
|
err = syncSearch(targets)
|
|
|
|
} else if parser.existsArg("c", "clean") {
|
|
|
|
err = passToPacman(parser)
|
|
|
|
} else if parser.existsArg("u", "sysupgrade") {
|
|
|
|
err = upgradePkgs(make([]string,0))
|
|
|
|
} else if parser.existsArg("i", "info") {
|
|
|
|
err = syncInfo(targets, options)
|
|
|
|
} else if len(parser.targets) > 0 {
|
|
|
|
err = install(parser)
|
|
|
|
}
|
2017-12-31 15:18:12 +00:00
|
|
|
|
|
|
|
return
|
2017-04-29 17:12:12 +00:00
|
|
|
}
|
|
|
|
|
2018-01-04 00:59:57 +00:00
|
|
|
func handleRemove(parser *arguments) (err error){
|
|
|
|
removeVCSPackage(parser.formatTargets())
|
|
|
|
err = passToPacman(parser)
|
|
|
|
return
|
|
|
|
}
|
2017-12-31 15:18:12 +00:00
|
|
|
|
2017-04-29 17:12:12 +00:00
|
|
|
// NumberMenu presents a CLI for selecting packages to install.
|
|
|
|
func numberMenu(pkgS []string, flags []string) (err error) {
|
2018-01-04 00:59:57 +00:00
|
|
|
//func numberMenu(parser *arguments) (err error) {
|
2017-04-29 17:12:12 +00:00
|
|
|
var num int
|
|
|
|
|
2017-08-02 17:24:03 +00:00
|
|
|
aq, err := narrowSearch(pkgS, true)
|
2017-04-29 17:12:12 +00:00
|
|
|
if err != nil {
|
|
|
|
fmt.Println("Error during AUR search:", err)
|
|
|
|
}
|
2017-05-02 15:46:14 +00:00
|
|
|
numaq := len(aq)
|
2018-01-04 00:59:57 +00:00
|
|
|
|
2017-08-04 09:26:53 +00:00
|
|
|
pq, numpq, err := queryRepo(pkgS)
|
2017-04-29 17:12:12 +00:00
|
|
|
if err != nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
if numpq == 0 && numaq == 0 {
|
|
|
|
return fmt.Errorf("no packages match search")
|
|
|
|
}
|
|
|
|
|
2017-08-02 17:24:03 +00:00
|
|
|
if config.SortMode == BottomUp {
|
|
|
|
aq.printSearch(numpq)
|
2017-08-04 09:26:53 +00:00
|
|
|
pq.printSearch()
|
2017-04-29 17:12:12 +00:00
|
|
|
} else {
|
2017-08-02 17:24:03 +00:00
|
|
|
pq.printSearch()
|
|
|
|
aq.printSearch(numpq)
|
2017-04-29 17:12:12 +00:00
|
|
|
}
|
|
|
|
|
2017-05-21 13:49:29 +00:00
|
|
|
fmt.Printf("\x1b[32m%s\x1b[0m\nNumbers: ", "Type numbers to install. Separate each number with a space.")
|
2017-04-29 17:12:12 +00:00
|
|
|
reader := bufio.NewReader(os.Stdin)
|
|
|
|
numberBuf, overflow, err := reader.ReadLine()
|
|
|
|
if err != nil || overflow {
|
|
|
|
fmt.Println(err)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
numberString := string(numberBuf)
|
2017-08-04 09:26:53 +00:00
|
|
|
var aurI []string
|
|
|
|
var repoI []string
|
2017-04-29 17:12:12 +00:00
|
|
|
result := strings.Fields(numberString)
|
|
|
|
for _, numS := range result {
|
|
|
|
num, err = strconv.Atoi(numS)
|
|
|
|
if err != nil {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
|
|
|
// Install package
|
|
|
|
if num > numaq+numpq-1 || num < 0 {
|
|
|
|
continue
|
|
|
|
} else if num > numpq-1 {
|
2017-08-02 17:24:03 +00:00
|
|
|
if config.SortMode == BottomUp {
|
2017-08-04 09:26:53 +00:00
|
|
|
aurI = append(aurI, aq[numaq+numpq-num-1].Name)
|
2017-04-29 17:12:12 +00:00
|
|
|
} else {
|
2017-08-04 09:26:53 +00:00
|
|
|
aurI = append(aurI, aq[num-numpq].Name)
|
2017-04-29 17:12:12 +00:00
|
|
|
}
|
|
|
|
} else {
|
2017-08-02 17:24:03 +00:00
|
|
|
if config.SortMode == BottomUp {
|
2017-08-04 09:26:53 +00:00
|
|
|
repoI = append(repoI, pq[numpq-num-1].Name())
|
2017-04-29 17:12:12 +00:00
|
|
|
} else {
|
2017-08-04 09:26:53 +00:00
|
|
|
repoI = append(repoI, pq[num].Name())
|
2017-04-29 17:12:12 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-08-04 09:26:53 +00:00
|
|
|
if len(repoI) != 0 {
|
2018-01-04 00:59:57 +00:00
|
|
|
arguments := makeArguments()
|
|
|
|
arguments.addArg("S")
|
|
|
|
arguments.addTarget(repoI...)
|
|
|
|
err = passToPacman(arguments)
|
2017-04-29 17:12:12 +00:00
|
|
|
}
|
|
|
|
|
2017-08-04 09:26:53 +00:00
|
|
|
if len(aurI) != 0 {
|
2018-01-04 00:59:57 +00:00
|
|
|
err = aurInstall(aurI, make([]string,0))
|
2017-04-29 17:12:12 +00:00
|
|
|
}
|
|
|
|
|
2017-05-09 01:09:43 +00:00
|
|
|
return err
|
2017-04-29 17:12:12 +00:00
|
|
|
}
|
2017-07-10 17:10:51 +00:00
|
|
|
|
|
|
|
// Complete provides completion info for shells
|
2017-12-04 06:24:20 +00:00
|
|
|
func complete() error {
|
2017-10-18 02:12:16 +00:00
|
|
|
path := completionFile + config.Shell + ".cache"
|
2017-07-10 17:10:51 +00:00
|
|
|
|
|
|
|
if info, err := os.Stat(path); os.IsNotExist(err) || time.Since(info.ModTime()).Hours() > 48 {
|
2017-10-19 02:56:19 +00:00
|
|
|
os.MkdirAll(filepath.Dir(completionFile), 0755)
|
2017-12-04 06:24:20 +00:00
|
|
|
out, errf := os.Create(path)
|
|
|
|
if errf != nil {
|
|
|
|
return errf
|
2017-07-10 17:10:51 +00:00
|
|
|
}
|
|
|
|
|
2017-08-02 17:24:03 +00:00
|
|
|
if createAURList(out) != nil {
|
2017-07-10 17:10:51 +00:00
|
|
|
defer os.Remove(path)
|
|
|
|
}
|
2017-12-04 06:24:20 +00:00
|
|
|
erra := createRepoList(out)
|
2017-07-10 17:10:51 +00:00
|
|
|
|
|
|
|
out.Close()
|
2017-12-04 06:24:20 +00:00
|
|
|
return erra
|
2017-07-10 17:10:51 +00:00
|
|
|
}
|
|
|
|
|
2017-10-19 02:56:19 +00:00
|
|
|
in, err := os.OpenFile(path, os.O_RDWR|os.O_CREATE, 0644)
|
2017-07-10 17:10:51 +00:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
defer in.Close()
|
|
|
|
|
|
|
|
_, err = io.Copy(os.Stdout, in)
|
|
|
|
return err
|
|
|
|
}
|
2018-01-03 19:01:34 +00:00
|
|
|
|
2018-01-04 02:53:19 +00:00
|
|
|
// passToPacman outsorces execution to pacman binary without modifications.
|
2018-01-04 00:59:57 +00:00
|
|
|
func passToPacman(parser *arguments) error {
|
2018-01-03 19:01:34 +00:00
|
|
|
var cmd *exec.Cmd
|
|
|
|
args := make([]string, 0)
|
|
|
|
|
|
|
|
if parser.needRoot() {
|
|
|
|
args = append(args, "sudo")
|
|
|
|
}
|
|
|
|
|
|
|
|
args = append(args, "pacman")
|
|
|
|
args = append(args, parser.formatArgs()...)
|
2018-01-04 00:59:57 +00:00
|
|
|
args = append(args, parser.formatTargets()...)
|
2018-01-03 19:01:34 +00:00
|
|
|
|
|
|
|
cmd = exec.Command(args[0], args[1:]...)
|
|
|
|
|
2018-01-04 00:59:57 +00:00
|
|
|
|
2018-01-03 19:01:34 +00:00
|
|
|
cmd.Stdin, cmd.Stdout, cmd.Stderr = os.Stdin, os.Stdout, os.Stderr
|
|
|
|
err := cmd.Run()
|
|
|
|
return err
|
|
|
|
}
|
2018-01-04 02:53:19 +00:00
|
|
|
|
|
|
|
// passToMakepkg outsorces execution to makepkg binary without modifications.
|
|
|
|
func passToMakepkg(dir string, args ...string) (err error) {
|
|
|
|
cmd := exec.Command(config.MakepkgBin, args...)
|
|
|
|
cmd.Stdin, cmd.Stdout, cmd.Stderr = os.Stdin, os.Stdout, os.Stderr
|
|
|
|
cmd.Dir = dir
|
|
|
|
err = cmd.Run()
|
|
|
|
if err == nil {
|
|
|
|
_ = saveVCSInfo()
|
|
|
|
if config.CleanAfter {
|
|
|
|
fmt.Println("\x1b[1;32m==> CleanAfter enabled. Deleting source folder.\x1b[0m")
|
|
|
|
os.RemoveAll(dir)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return
|
|
|
|
}
|