2017-04-29 19:12:12 +02:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"bufio"
|
2017-08-02 19:24:03 +02:00
|
|
|
"encoding/json"
|
2017-04-29 19:12:12 +02:00
|
|
|
"fmt"
|
2017-07-10 19:10:51 +02:00
|
|
|
"io"
|
2017-04-29 19:12:12 +02:00
|
|
|
"os"
|
2017-10-16 16:38:51 +02:00
|
|
|
"path/filepath"
|
2017-04-29 19:12:12 +02:00
|
|
|
"strconv"
|
|
|
|
"strings"
|
2017-07-10 19:10:51 +02:00
|
|
|
"time"
|
2017-04-29 19:12:12 +02:00
|
|
|
)
|
|
|
|
|
|
|
|
func usage() {
|
2018-01-03 05:55:47 +01: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 04:30:37 +02:00
|
|
|
|
2018-01-03 05:55:47 +01:00
|
|
|
New operations:
|
|
|
|
yay {-Y --yay} [options] [package(s)]
|
|
|
|
yay {-G --getpkgbuild} [package(s)]
|
2017-10-19 04:30:37 +02:00
|
|
|
|
2018-01-03 05:55:47 +01: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 03:39:23 +01:00
|
|
|
|
2018-01-03 05:55:47 +01: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 19:12:12 +02:00
|
|
|
}
|
|
|
|
|
2017-08-02 19:24:03 +02:00
|
|
|
func init() {
|
2017-10-18 04:12:16 +02:00
|
|
|
var configHome string // configHome handles config directory home
|
|
|
|
var cacheHome string // cacheHome handles cache home
|
2017-08-02 19:24:03 +02:00
|
|
|
var err error
|
2017-10-18 04:12:16 +02: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 04:30:37 +02:00
|
|
|
if info, err := os.Stat(configHome); err == nil && info.IsDir() {
|
2017-10-18 04:12:16 +02:00
|
|
|
configHome = configHome + "/yay"
|
2017-10-16 16:38:51 +02:00
|
|
|
} else {
|
2017-10-18 04:12:16 +02:00
|
|
|
configHome = os.Getenv("HOME") + "/.config/yay"
|
2017-10-16 16:38:51 +02:00
|
|
|
}
|
|
|
|
} else {
|
2017-10-18 04:12:16 +02:00
|
|
|
configHome = os.Getenv("HOME") + "/.config/yay"
|
2017-10-16 16:38:51 +02:00
|
|
|
}
|
2017-08-02 19:24:03 +02:00
|
|
|
|
2017-10-18 04:12:16 +02:00
|
|
|
if cacheHome = os.Getenv("XDG_CACHE_HOME"); cacheHome != "" {
|
2017-10-19 04:30:37 +02:00
|
|
|
if info, err := os.Stat(cacheHome); err == nil && info.IsDir() {
|
2017-10-18 04:12:16 +02:00
|
|
|
cacheHome = cacheHome + "/yay"
|
|
|
|
} else {
|
|
|
|
cacheHome = os.Getenv("HOME") + "/.cache/yay"
|
|
|
|
}
|
|
|
|
} else {
|
2017-10-19 04:30:37 +02:00
|
|
|
cacheHome = os.Getenv("HOME") + "/.cache/yay"
|
2017-10-18 04:12:16 +02: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 04:56:19 +02:00
|
|
|
err = os.MkdirAll(filepath.Dir(configFile), 0755)
|
2017-10-16 16:38:51 +02:00
|
|
|
if err != nil {
|
2017-10-18 04:12:16 +02:00
|
|
|
fmt.Println("Unable to create config directory:", filepath.Dir(configFile), err)
|
2017-10-16 16:38:51 +02:00
|
|
|
os.Exit(2)
|
|
|
|
}
|
2017-08-02 19:24:03 +02:00
|
|
|
// Save the default config if nothing is found
|
|
|
|
config.saveConfig()
|
|
|
|
} else {
|
2017-12-04 07:24:20 +01:00
|
|
|
cfile, errf := os.OpenFile(configFile, os.O_RDWR|os.O_CREATE, 0644)
|
|
|
|
if errf != nil {
|
2017-08-02 19:24:03 +02:00
|
|
|
fmt.Println("Error reading config:", err)
|
|
|
|
} else {
|
2017-10-19 07:59:26 +02:00
|
|
|
defer cfile.Close()
|
|
|
|
decoder := json.NewDecoder(cfile)
|
2017-08-02 19:24:03 +02:00
|
|
|
err = decoder.Decode(&config)
|
|
|
|
if err != nil {
|
2017-10-18 04:12:16 +02:00
|
|
|
fmt.Println("Loading default Settings.\nError reading config:", err)
|
2017-08-02 19:24:03 +02:00
|
|
|
defaultSettings(&config)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-10-18 04:12:16 +02:00
|
|
|
/////////////////
|
|
|
|
// vcs config //
|
|
|
|
////////////////
|
2017-08-02 19:24:03 +02:00
|
|
|
updated = false
|
|
|
|
|
2017-10-19 07:59:26 +02:00
|
|
|
vfile, err := os.Open(vcsFile)
|
2017-10-19 04:30:37 +02:00
|
|
|
if err == nil {
|
2017-10-19 07:59:26 +02:00
|
|
|
defer vfile.Close()
|
|
|
|
decoder := json.NewDecoder(vfile)
|
2017-10-19 04:30:37 +02:00
|
|
|
_ = decoder.Decode(&savedInfo)
|
2017-08-02 19:24:03 +02:00
|
|
|
}
|
2017-10-18 04:12:16 +02:00
|
|
|
|
|
|
|
/////////////////
|
|
|
|
// alpm config //
|
|
|
|
/////////////////
|
2017-10-18 07:46:21 +02:00
|
|
|
alpmConf, err = readAlpmConfig(config.PacmanConf)
|
2017-10-18 04:12:16 +02:00
|
|
|
if err != nil {
|
|
|
|
fmt.Println("Unable to read Pacman conf", err)
|
|
|
|
os.Exit(1)
|
|
|
|
}
|
|
|
|
|
2017-10-18 07:46:21 +02:00
|
|
|
alpmHandle, err = alpmConf.CreateHandle()
|
2017-10-18 04:12:16 +02:00
|
|
|
if err != nil {
|
|
|
|
fmt.Println("Unable to CreateHandle", err)
|
|
|
|
os.Exit(1)
|
|
|
|
}
|
2017-08-02 19:24:03 +02:00
|
|
|
}
|
2017-04-29 19:12:12 +02:00
|
|
|
|
2017-12-31 16:18:12 +01:00
|
|
|
func main() {
|
|
|
|
var err error
|
|
|
|
var changedConfig bool
|
|
|
|
|
|
|
|
parser := makeArgParser();
|
|
|
|
err = parser.parseCommandLine();
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
fmt.Println(err)
|
|
|
|
os.Exit(1)
|
2017-04-29 19:12:12 +02:00
|
|
|
}
|
2017-12-31 16:18:12 +01:00
|
|
|
|
|
|
|
if parser.existsArg("-") {
|
|
|
|
err = parser.parseStdin();
|
2017-04-29 19:12:12 +02:00
|
|
|
|
2017-12-31 16:18:12 +01:00
|
|
|
if err != nil {
|
|
|
|
fmt.Println(err)
|
|
|
|
os.Exit(1)
|
2017-10-25 10:16:35 +02:00
|
|
|
}
|
2017-12-31 16:18:12 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
fmt.Println(parser)
|
|
|
|
|
|
|
|
changedConfig, err = handleCmd(parser)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
fmt.Println(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
if updated {
|
|
|
|
err = saveVCSInfo()
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
fmt.Println(err)
|
2017-04-29 19:12:12 +02:00
|
|
|
}
|
2017-12-31 16:18:12 +01:00
|
|
|
}
|
2017-04-29 19:12:12 +02:00
|
|
|
|
2017-12-31 16:18:12 +01:00
|
|
|
if changedConfig {
|
|
|
|
err = config.saveConfig()
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
fmt.Println(err)
|
2017-04-29 19:12:12 +02:00
|
|
|
}
|
2017-12-31 16:18:12 +01:00
|
|
|
|
2017-04-29 19:12:12 +02:00
|
|
|
}
|
|
|
|
|
2017-12-31 16:18:12 +01:00
|
|
|
err = alpmHandle.Release()
|
2017-04-29 19:12:12 +02:00
|
|
|
if err != nil {
|
|
|
|
fmt.Println(err)
|
|
|
|
}
|
2017-12-31 16:18:12 +01:00
|
|
|
}
|
2017-04-29 19:12:12 +02:00
|
|
|
|
2017-12-31 16:18:12 +01:00
|
|
|
func handleCmd(parser *argParser) (changedConfig bool, err error) {
|
|
|
|
var _changedConfig bool
|
|
|
|
|
|
|
|
for option, _ := range parser.options {
|
|
|
|
_changedConfig, err = handleConfig(option)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return
|
2017-04-29 19:12:12 +02:00
|
|
|
}
|
2017-12-31 16:18:12 +01:00
|
|
|
|
|
|
|
if _changedConfig {
|
|
|
|
changedConfig = true
|
2017-04-29 19:12:12 +02:00
|
|
|
}
|
2017-12-31 16:18:12 +01:00
|
|
|
}
|
2017-04-29 19:12:12 +02:00
|
|
|
|
2017-12-31 16:18:12 +01:00
|
|
|
switch parser.op {
|
|
|
|
case "V", "version":
|
|
|
|
handleVersion()
|
|
|
|
case "D", "database":
|
|
|
|
//passToPacman()
|
|
|
|
case "F", "files":
|
|
|
|
//passToPacman()
|
|
|
|
case "Q", "query":
|
|
|
|
//passToPacman()
|
|
|
|
case "R", "remove":
|
|
|
|
//
|
|
|
|
case "S", "sync":
|
|
|
|
err = handleSync(parser)
|
|
|
|
case "T", "deptest":
|
|
|
|
//passToPacman()
|
|
|
|
case "U", "upgrade":
|
|
|
|
//passToPacman()
|
|
|
|
case "Y", "--yay":
|
2018-01-03 05:55:47 +01:00
|
|
|
err = handleYay(parser)
|
2017-12-31 16:18:12 +01: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 11:32:11 +02:00
|
|
|
}
|
2017-12-31 16:18:12 +01: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 05:55:47 +01: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 16:18:12 +01: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 05:55:47 +01: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 16:18:12 +01:00
|
|
|
case "noconfirm":
|
|
|
|
config.NoConfirm = true
|
|
|
|
default:
|
|
|
|
return
|
2017-07-19 11:32:32 +02:00
|
|
|
}
|
2017-12-31 16:18:12 +01:00
|
|
|
|
|
|
|
changedConfig = true
|
|
|
|
return
|
|
|
|
}
|
2017-04-29 19:12:12 +02:00
|
|
|
|
2017-12-31 16:18:12 +01:00
|
|
|
func handleVersion() {
|
2018-01-03 05:55:47 +01:00
|
|
|
fmt.Printf("yay v%s\n", version)
|
|
|
|
}
|
|
|
|
|
|
|
|
func handleYay(parser *argParser) (err error) {
|
|
|
|
//_, options, targets := parser.formatArgs()
|
|
|
|
if parser.existsArg("h") || parser.existsArg("help") {
|
|
|
|
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") {
|
|
|
|
_,_,targets := parser.formatArgs()
|
|
|
|
err = cleanDependencies(targets)
|
|
|
|
} else {
|
|
|
|
err = handleYogurt(parser)
|
|
|
|
}
|
|
|
|
|
|
|
|
return
|
2017-12-31 16:18:12 +01:00
|
|
|
}
|
2017-05-09 03:09:43 +02:00
|
|
|
|
2017-12-31 16:18:12 +01:00
|
|
|
func handleYogurt(parser *argParser) (err error) {
|
|
|
|
_, options, targets := parser.formatArgs()
|
|
|
|
|
|
|
|
config.SearchMode = NumberMenu
|
|
|
|
err = numberMenu(targets, options)
|
|
|
|
|
|
|
|
return
|
|
|
|
}
|
2017-05-09 03:09:43 +02:00
|
|
|
|
2017-12-31 16:18:12 +01:00
|
|
|
func handleSync(parser *argParser) (err error) {
|
|
|
|
op, options, targets := parser.formatArgs()
|
|
|
|
|
|
|
|
fmt.Println("op", op)
|
|
|
|
fmt.Println("options", options)
|
|
|
|
fmt.Println("targets", targets)
|
|
|
|
|
|
|
|
if parser.existsArg("y") {
|
|
|
|
err = passToPacman("-Sy", nil, nil)
|
|
|
|
if err != nil {
|
|
|
|
return
|
2017-07-07 01:05:18 +02:00
|
|
|
}
|
|
|
|
}
|
2017-12-31 16:18:12 +01:00
|
|
|
|
|
|
|
if parser.existsArg("s") {
|
|
|
|
if parser.existsArg("i") {
|
|
|
|
config.SearchMode = Detailed
|
|
|
|
} else {
|
|
|
|
config.SortMode = Minimal
|
|
|
|
}
|
|
|
|
|
|
|
|
err = syncSearch(targets)
|
2017-04-29 19:12:12 +02:00
|
|
|
}
|
2017-12-31 16:18:12 +01:00
|
|
|
|
|
|
|
if len(targets) > 0 {
|
|
|
|
err = install(targets, options)
|
2017-04-29 19:12:12 +02:00
|
|
|
}
|
2017-12-31 16:18:12 +01:00
|
|
|
|
|
|
|
return
|
2017-04-29 19:12:12 +02:00
|
|
|
}
|
|
|
|
|
2017-12-31 16:18:12 +01:00
|
|
|
|
2017-04-29 19:12:12 +02:00
|
|
|
// NumberMenu presents a CLI for selecting packages to install.
|
|
|
|
func numberMenu(pkgS []string, flags []string) (err error) {
|
|
|
|
var num int
|
|
|
|
|
2017-08-02 19:24:03 +02:00
|
|
|
aq, err := narrowSearch(pkgS, true)
|
2017-04-29 19:12:12 +02:00
|
|
|
if err != nil {
|
|
|
|
fmt.Println("Error during AUR search:", err)
|
|
|
|
}
|
2017-05-02 17:46:14 +02:00
|
|
|
numaq := len(aq)
|
2017-08-04 11:26:53 +02:00
|
|
|
pq, numpq, err := queryRepo(pkgS)
|
2017-04-29 19:12:12 +02:00
|
|
|
if err != nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
if numpq == 0 && numaq == 0 {
|
|
|
|
return fmt.Errorf("no packages match search")
|
|
|
|
}
|
|
|
|
|
2017-08-02 19:24:03 +02:00
|
|
|
if config.SortMode == BottomUp {
|
|
|
|
aq.printSearch(numpq)
|
2017-08-04 11:26:53 +02:00
|
|
|
pq.printSearch()
|
2017-04-29 19:12:12 +02:00
|
|
|
} else {
|
2017-08-02 19:24:03 +02:00
|
|
|
pq.printSearch()
|
|
|
|
aq.printSearch(numpq)
|
2017-04-29 19:12:12 +02:00
|
|
|
}
|
|
|
|
|
2017-05-21 15:49:29 +02:00
|
|
|
fmt.Printf("\x1b[32m%s\x1b[0m\nNumbers: ", "Type numbers to install. Separate each number with a space.")
|
2017-04-29 19:12:12 +02: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 11:26:53 +02:00
|
|
|
var aurI []string
|
|
|
|
var repoI []string
|
2017-04-29 19:12:12 +02: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 19:24:03 +02:00
|
|
|
if config.SortMode == BottomUp {
|
2017-08-04 11:26:53 +02:00
|
|
|
aurI = append(aurI, aq[numaq+numpq-num-1].Name)
|
2017-04-29 19:12:12 +02:00
|
|
|
} else {
|
2017-08-04 11:26:53 +02:00
|
|
|
aurI = append(aurI, aq[num-numpq].Name)
|
2017-04-29 19:12:12 +02:00
|
|
|
}
|
|
|
|
} else {
|
2017-08-02 19:24:03 +02:00
|
|
|
if config.SortMode == BottomUp {
|
2017-08-04 11:26:53 +02:00
|
|
|
repoI = append(repoI, pq[numpq-num-1].Name())
|
2017-04-29 19:12:12 +02:00
|
|
|
} else {
|
2017-08-04 11:26:53 +02:00
|
|
|
repoI = append(repoI, pq[num].Name())
|
2017-04-29 19:12:12 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-08-04 11:26:53 +02:00
|
|
|
if len(repoI) != 0 {
|
|
|
|
err = passToPacman("-S", repoI, flags)
|
2017-04-29 19:12:12 +02:00
|
|
|
}
|
|
|
|
|
2017-08-04 11:26:53 +02:00
|
|
|
if len(aurI) != 0 {
|
|
|
|
err = aurInstall(aurI, flags)
|
2017-04-29 19:12:12 +02:00
|
|
|
}
|
|
|
|
|
2017-05-09 03:09:43 +02:00
|
|
|
return err
|
2017-04-29 19:12:12 +02:00
|
|
|
}
|
2017-07-10 19:10:51 +02:00
|
|
|
|
|
|
|
// Complete provides completion info for shells
|
2017-12-04 07:24:20 +01:00
|
|
|
func complete() error {
|
2017-10-18 04:12:16 +02:00
|
|
|
path := completionFile + config.Shell + ".cache"
|
2017-07-10 19:10:51 +02:00
|
|
|
|
|
|
|
if info, err := os.Stat(path); os.IsNotExist(err) || time.Since(info.ModTime()).Hours() > 48 {
|
2017-10-19 04:56:19 +02:00
|
|
|
os.MkdirAll(filepath.Dir(completionFile), 0755)
|
2017-12-04 07:24:20 +01:00
|
|
|
out, errf := os.Create(path)
|
|
|
|
if errf != nil {
|
|
|
|
return errf
|
2017-07-10 19:10:51 +02:00
|
|
|
}
|
|
|
|
|
2017-08-02 19:24:03 +02:00
|
|
|
if createAURList(out) != nil {
|
2017-07-10 19:10:51 +02:00
|
|
|
defer os.Remove(path)
|
|
|
|
}
|
2017-12-04 07:24:20 +01:00
|
|
|
erra := createRepoList(out)
|
2017-07-10 19:10:51 +02:00
|
|
|
|
|
|
|
out.Close()
|
2017-12-04 07:24:20 +01:00
|
|
|
return erra
|
2017-07-10 19:10:51 +02:00
|
|
|
}
|
|
|
|
|
2017-10-19 04:56:19 +02:00
|
|
|
in, err := os.OpenFile(path, os.O_RDWR|os.O_CREATE, 0644)
|
2017-07-10 19:10:51 +02:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
defer in.Close()
|
|
|
|
|
|
|
|
_, err = io.Copy(os.Stdout, in)
|
|
|
|
return err
|
|
|
|
}
|