mirror of
https://github.com/Jguer/yay
synced 2024-10-31 04:12:51 +00:00
f20fbd25c1
diff viewing can be toggled via --[no]showdiffs. When enabled diffs will be shown for packages between the current HEAD and upstream's HEAD. Packages downloaded via tarballs will be shown in full using the editor git diff is used to show diffs. Therefore the pager for diffs can be set via the PAGER and GIT_PAGER enviroment variables.
285 lines
6.5 KiB
Go
285 lines
6.5 KiB
Go
package main
|
|
|
|
import (
|
|
"bufio"
|
|
"bytes"
|
|
"encoding/json"
|
|
"fmt"
|
|
"os"
|
|
"os/exec"
|
|
"strings"
|
|
|
|
alpm "github.com/jguer/go-alpm"
|
|
)
|
|
|
|
// Verbosity settings for search
|
|
const (
|
|
NumberMenu = iota
|
|
Detailed
|
|
Minimal
|
|
)
|
|
|
|
// Describes Sorting method for numberdisplay
|
|
const (
|
|
BottomUp = iota
|
|
TopDown
|
|
)
|
|
|
|
type targetMode int
|
|
|
|
const (
|
|
ModeAUR targetMode = iota
|
|
ModeRepo
|
|
ModeAny
|
|
)
|
|
|
|
// Configuration stores yay's config.
|
|
type Configuration struct {
|
|
BuildDir string `json:"buildDir"`
|
|
Editor string `json:"editor"`
|
|
EditorFlags string `json:"editorflags"`
|
|
MakepkgBin string `json:"makepkgbin"`
|
|
PacmanBin string `json:"pacmanbin"`
|
|
PacmanConf string `json:"pacmanconf"`
|
|
TarBin string `json:"tarbin"`
|
|
ReDownload string `json:"redownload"`
|
|
ReBuild string `json:"rebuild"`
|
|
AnswerClean string `json:"answerclean"`
|
|
AnswerEdit string `json:"answeredit"`
|
|
AnswerUpgrade string `json:"answerupgrade"`
|
|
GitBin string `json:"gitbin"`
|
|
GpgBin string `json:"gpgbin"`
|
|
GpgFlags string `json:"gpgflags"`
|
|
MFlags string `json:"mflags"`
|
|
SortBy string `json:"sortby"`
|
|
GitFlags string `json:"gitflags"`
|
|
RequestSplitN int `json:"requestsplitn"`
|
|
SearchMode int `json:"-"`
|
|
SortMode int `json:"sortmode"`
|
|
SudoLoop bool `json:"sudoloop"`
|
|
TimeUpdate bool `json:"timeupdate"`
|
|
NoConfirm bool `json:"-"`
|
|
Devel bool `json:"devel"`
|
|
CleanAfter bool `json:"cleanAfter"`
|
|
GitClone bool `json:"gitclone"`
|
|
Provides bool `json:"provides"`
|
|
PGPFetch bool `json:"pgpfetch"`
|
|
ShowDiffs bool `json:"showdifs"`
|
|
}
|
|
|
|
var version = "5.688"
|
|
|
|
// configFileName holds the name of the config file.
|
|
const configFileName string = "config.json"
|
|
|
|
// vcsFileName holds the name of the vcs file.
|
|
const vcsFileName string = "vcs.json"
|
|
|
|
// baseURL givers the AUR default address.
|
|
const baseURL string = "https://aur.archlinux.org"
|
|
|
|
// useColor enables/disables colored printing
|
|
var useColor bool
|
|
|
|
// configHome handles config directory home
|
|
var configHome string
|
|
|
|
// cacheHome handles cache home
|
|
var cacheHome string
|
|
|
|
// savedInfo holds the current vcs info
|
|
var savedInfo vcsInfo
|
|
|
|
// configfile holds yay config file path.
|
|
var configFile string
|
|
|
|
// vcsfile holds yay vcs info file path.
|
|
var vcsFile string
|
|
|
|
// shouldSaveConfig holds whether or not the config should be saved
|
|
var shouldSaveConfig bool
|
|
|
|
// YayConf holds the current config values for yay.
|
|
var config Configuration
|
|
|
|
// AlpmConf holds the current config values for pacman.
|
|
var alpmConf alpm.PacmanConfig
|
|
|
|
// AlpmHandle is the alpm handle used by yay.
|
|
var alpmHandle *alpm.Handle
|
|
|
|
// Mode is used to restrict yay to AUR or repo only modes
|
|
var mode targetMode = ModeAny
|
|
|
|
func readAlpmConfig(pacmanconf string) (conf alpm.PacmanConfig, err error) {
|
|
file, err := os.Open(pacmanconf)
|
|
if err != nil {
|
|
return
|
|
}
|
|
conf, err = alpm.ParseConfig(file)
|
|
if err != nil {
|
|
return
|
|
}
|
|
return
|
|
}
|
|
|
|
// SaveConfig writes yay config to file.
|
|
func (config *Configuration) saveConfig() error {
|
|
marshalledinfo, _ := json.MarshalIndent(config, "", "\t")
|
|
in, err := os.OpenFile(configFile, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0644)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer in.Close()
|
|
_, err = in.Write(marshalledinfo)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
err = in.Sync()
|
|
return err
|
|
}
|
|
|
|
func defaultSettings(config *Configuration) {
|
|
config.BuildDir = cacheHome
|
|
config.CleanAfter = false
|
|
config.Editor = ""
|
|
config.EditorFlags = ""
|
|
config.Devel = false
|
|
config.MakepkgBin = "makepkg"
|
|
config.NoConfirm = false
|
|
config.PacmanBin = "pacman"
|
|
config.PGPFetch = true
|
|
config.PacmanConf = "/etc/pacman.conf"
|
|
config.GpgFlags = ""
|
|
config.MFlags = ""
|
|
config.GitFlags = ""
|
|
config.SortMode = BottomUp
|
|
config.SortBy = "votes"
|
|
config.SudoLoop = false
|
|
config.TarBin = "bsdtar"
|
|
config.GitBin = "git"
|
|
config.GpgBin = "gpg"
|
|
config.TimeUpdate = false
|
|
config.RequestSplitN = 150
|
|
config.ReDownload = "no"
|
|
config.ReBuild = "no"
|
|
config.AnswerClean = ""
|
|
config.AnswerEdit = ""
|
|
config.AnswerUpgrade = ""
|
|
config.GitClone = true
|
|
config.Provides = true
|
|
config.ShowDiffs = true
|
|
}
|
|
|
|
// Editor returns the preferred system editor.
|
|
func editor() (string, []string) {
|
|
switch {
|
|
case config.Editor != "":
|
|
editor, err := exec.LookPath(config.Editor)
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
} else {
|
|
return editor, strings.Fields(config.EditorFlags)
|
|
}
|
|
fallthrough
|
|
case os.Getenv("EDITOR") != "":
|
|
editorArgs := strings.Fields(os.Getenv("EDITOR"))
|
|
editor, err := exec.LookPath(editorArgs[0])
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
} else {
|
|
return editor, editorArgs[1:]
|
|
}
|
|
fallthrough
|
|
case os.Getenv("VISUAL") != "":
|
|
editorArgs := strings.Fields(os.Getenv("VISUAL"))
|
|
editor, err := exec.LookPath(editorArgs[0])
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
} else {
|
|
return editor, editorArgs[1:]
|
|
}
|
|
fallthrough
|
|
default:
|
|
fmt.Println()
|
|
fmt.Println(bold(red(arrow)), bold(cyan("$EDITOR")), bold("is not set"))
|
|
fmt.Println(bold(red(arrow)) + bold(" Please add ") + bold(cyan("$EDITOR")) + bold(" or ") + bold(cyan("$VISUAL")) + bold(" to your environment variables."))
|
|
|
|
for {
|
|
fmt.Print(green(bold(arrow + " Edit PKGBUILD with: ")))
|
|
editorInput, err := getInput("")
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
continue
|
|
}
|
|
|
|
editorArgs := strings.Fields(editorInput)
|
|
|
|
editor, err := exec.LookPath(editorArgs[0])
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
continue
|
|
}
|
|
return editor, editorArgs[1:]
|
|
}
|
|
}
|
|
}
|
|
|
|
// ContinueTask prompts if user wants to continue task.
|
|
//If NoConfirm is set the action will continue without user input.
|
|
func continueTask(s string, def string) (cont bool) {
|
|
if config.NoConfirm {
|
|
return true
|
|
}
|
|
var postFix string
|
|
|
|
if def == "nN" {
|
|
postFix = " [Y/n] "
|
|
} else {
|
|
postFix = " [y/N] "
|
|
}
|
|
|
|
var response string
|
|
fmt.Print(bold(green(arrow)+" "+s), bold(postFix))
|
|
|
|
n, err := fmt.Scanln(&response)
|
|
if err != nil || n == 0 {
|
|
return true
|
|
}
|
|
|
|
if response == string(def[0]) || response == string(def[1]) {
|
|
return false
|
|
}
|
|
|
|
return true
|
|
}
|
|
|
|
func getInput(defaultValue string) (string, error) {
|
|
if defaultValue != "" || config.NoConfirm {
|
|
fmt.Println(defaultValue)
|
|
return defaultValue, nil
|
|
}
|
|
|
|
reader := bufio.NewReader(os.Stdin)
|
|
|
|
buf, overflow, err := reader.ReadLine()
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
if overflow {
|
|
return "", fmt.Errorf("Input too long")
|
|
}
|
|
|
|
return string(buf), nil
|
|
}
|
|
|
|
func (config Configuration) String() string {
|
|
var buf bytes.Buffer
|
|
enc := json.NewEncoder(&buf)
|
|
enc.SetIndent("", "\t")
|
|
if err := enc.Encode(config); err != nil {
|
|
fmt.Println(err)
|
|
}
|
|
return buf.String()
|
|
}
|