yay/main.go

201 lines
5.0 KiB
Go
Raw Normal View History

2018-09-15 19:17:03 +02:00
package main // import "github.com/Jguer/yay"
2018-03-22 16:46:48 +01:00
import (
2018-03-22 17:39:27 +01:00
"encoding/json"
"errors"
2018-03-22 17:39:27 +01:00
"fmt"
2018-03-22 16:46:48 +01:00
"os"
2019-04-23 17:53:20 +02:00
alpm "github.com/Jguer/go-alpm"
pacmanconf "github.com/Morganamilo/go-pacmanconf"
"github.com/leonelquinteros/gotext"
"github.com/Jguer/yay/v10/pkg/db"
"github.com/Jguer/yay/v10/pkg/settings"
"github.com/Jguer/yay/v10/pkg/text"
2018-03-22 16:46:48 +01:00
)
func initGotext() {
2020-05-08 18:13:51 +02:00
if envLocalePath := os.Getenv("LOCALE_PATH"); envLocalePath != "" {
localePath = envLocalePath
}
gotext.Configure(localePath, os.Getenv("LANG"), "yay")
}
func initConfig(configPath string) error {
cfile, err := os.Open(configPath)
if !os.IsNotExist(err) && err != nil {
return errors.New(gotext.Get("failed to open config file '%s': %s", configPath, err))
}
2018-03-22 16:46:48 +01:00
defer cfile.Close()
if !os.IsNotExist(err) {
decoder := json.NewDecoder(cfile)
if err = decoder.Decode(&config); err != nil {
return errors.New(gotext.Get("failed to read config file '%s': %s", configPath, err))
2018-03-22 16:46:48 +01:00
}
}
aurdest := os.Getenv("AURDEST")
if aurdest != "" {
config.BuildDir = aurdest
}
return nil
}
2020-07-05 03:26:00 +02:00
func initVCS(vcsFilePath string) error {
vfile, err := os.Open(vcsFilePath)
if !os.IsNotExist(err) && err != nil {
2020-07-05 03:26:00 +02:00
return errors.New(gotext.Get("failed to open vcs file '%s': %s", vcsFilePath, err))
}
defer vfile.Close()
if !os.IsNotExist(err) {
decoder := json.NewDecoder(vfile)
if err = decoder.Decode(&savedInfo); err != nil {
2020-07-05 03:26:00 +02:00
return errors.New(gotext.Get("failed to read vcs file '%s': %s", vcsFilePath, err))
2018-03-22 16:46:48 +01:00
}
}
return nil
2018-03-22 16:46:48 +01:00
}
func initBuildDir() error {
if _, err := os.Stat(config.BuildDir); os.IsNotExist(err) {
2020-07-08 03:40:50 +02:00
if err = os.MkdirAll(config.BuildDir, 0o755); err != nil {
return errors.New(gotext.Get("failed to create BuildDir directory '%s': %s", config.BuildDir, err))
}
} else if err != nil {
return err
}
return nil
2018-03-22 16:46:48 +01:00
}
2020-07-08 03:31:35 +02:00
func initAlpm(cmdArgs *settings.Arguments, pacmanConfigPath string) (*alpm.Handle, *pacmanconf.Config, error) {
root := "/"
2020-07-05 02:45:23 +02:00
if value, _, exists := cmdArgs.GetArg("root", "r"); exists {
root = value
2018-03-22 16:46:48 +01:00
}
pacmanConf, stderr, err := pacmanconf.PacmanConf("--config", pacmanConfigPath, "--root", root)
if err != nil {
return nil, nil, fmt.Errorf("%s", stderr)
2018-03-22 16:46:48 +01:00
}
2020-07-26 23:08:47 +02:00
if dbPath, _, exists := cmdArgs.GetArg("dbpath", "b"); exists {
pacmanConf.DBPath = dbPath
2018-03-22 16:46:48 +01:00
}
2020-07-26 23:08:47 +02:00
if arch, _, exists := cmdArgs.GetArg("arch"); exists {
pacmanConf.Architecture = arch
2018-03-22 16:46:48 +01:00
}
if ignoreArray := cmdArgs.GetArgs("ignore"); ignoreArray != nil {
pacmanConf.IgnorePkg = append(pacmanConf.IgnorePkg, ignoreArray...)
2018-03-22 16:46:48 +01:00
}
2020-07-26 23:08:47 +02:00
if ignoreGroupsArray := cmdArgs.GetArgs("ignoregroup"); ignoreGroupsArray != nil {
pacmanConf.IgnoreGroup = append(pacmanConf.IgnoreGroup, ignoreGroupsArray...)
2018-03-22 16:46:48 +01:00
}
2020-07-26 23:08:47 +02:00
if cacheArray := cmdArgs.GetArgs("cachedir"); cacheArray != nil {
pacmanConf.CacheDir = cacheArray
2018-03-22 16:46:48 +01:00
}
2020-07-26 23:08:47 +02:00
if gpgDir, _, exists := cmdArgs.GetArg("gpgdir"); exists {
pacmanConf.GPGDir = gpgDir
2018-03-22 16:46:48 +01:00
}
alpmHandle, err := initAlpmHandle(pacmanConf, nil)
if err != nil {
return nil, nil, err
2018-03-22 16:46:48 +01:00
}
2020-07-05 02:45:23 +02:00
switch value, _, _ := cmdArgs.GetArg("color"); value {
2019-03-04 17:07:04 +01:00
case "always":
text.UseColor = true
2019-03-04 17:07:04 +01:00
case "auto":
text.UseColor = isTty()
2019-03-04 17:07:04 +01:00
case "never":
text.UseColor = false
2019-03-04 17:07:04 +01:00
default:
text.UseColor = pacmanConf.Color && isTty()
2018-03-22 16:46:48 +01:00
}
return alpmHandle, pacmanConf, nil
Separate Pacman upgrade and AUR Upgrade by default Currently When performing a system upgrade, Yay will first refresh the database then perform the repo and AUR upgrade. This allows Yay to add some features such as better batch interaction, showing potential dependency problems before the upgrade starts and combined menus showing AUR and repo upgrades together. There has been discussion that this approach is a bad idea. The main issue people have is that the separation of the database refresh and the upgrade could lead to a partial upgrade if Yay fails between the two stages. Personally I do not like this argument, there are valid reasons to Yay to fail between these points. For example there may be dependency or conflict issues during the AUR upgrade. Yay can detect these before any installing actually starts and exit, just like how pacman will when there are dependency problems. If Yay does fail between these points, for the previously mentioned reasons or even a crash then a simple refresh will not cause a partial upgrade by itself. It is then the user's responsibility to either resolve these issues or instead perform an upgrade using pacman directly. My opinions aside, The discussions on the Arch wiki has reached a decision, this method is not recommended. So to follow the decided best practises this behaviour has been disabled by default. This behaviour can be toggled using the --[no]combinedupgrade flag It should be noted that Yay's upgrade menu will not show repo packages unless --combinedupgrade is used.
2018-06-22 15:44:38 +02:00
}
func initAlpmHandle(pacmanConf *pacmanconf.Config, oldAlpmHandle *alpm.Handle) (*alpm.Handle, error) {
if oldAlpmHandle != nil {
if errRelease := oldAlpmHandle.Release(); errRelease != nil {
return nil, errRelease
Separate Pacman upgrade and AUR Upgrade by default Currently When performing a system upgrade, Yay will first refresh the database then perform the repo and AUR upgrade. This allows Yay to add some features such as better batch interaction, showing potential dependency problems before the upgrade starts and combined menus showing AUR and repo upgrades together. There has been discussion that this approach is a bad idea. The main issue people have is that the separation of the database refresh and the upgrade could lead to a partial upgrade if Yay fails between the two stages. Personally I do not like this argument, there are valid reasons to Yay to fail between these points. For example there may be dependency or conflict issues during the AUR upgrade. Yay can detect these before any installing actually starts and exit, just like how pacman will when there are dependency problems. If Yay does fail between these points, for the previously mentioned reasons or even a crash then a simple refresh will not cause a partial upgrade by itself. It is then the user's responsibility to either resolve these issues or instead perform an upgrade using pacman directly. My opinions aside, The discussions on the Arch wiki has reached a decision, this method is not recommended. So to follow the decided best practises this behaviour has been disabled by default. This behaviour can be toggled using the --[no]combinedupgrade flag It should be noted that Yay's upgrade menu will not show repo packages unless --combinedupgrade is used.
2018-06-22 15:44:38 +02:00
}
}
2018-03-22 16:46:48 +01:00
alpmHandle, err := alpm.Initialize(pacmanConf.RootDir, pacmanConf.DBPath)
if err != nil {
return nil, errors.New(gotext.Get("unable to CreateHandle: %s", err))
Separate Pacman upgrade and AUR Upgrade by default Currently When performing a system upgrade, Yay will first refresh the database then perform the repo and AUR upgrade. This allows Yay to add some features such as better batch interaction, showing potential dependency problems before the upgrade starts and combined menus showing AUR and repo upgrades together. There has been discussion that this approach is a bad idea. The main issue people have is that the separation of the database refresh and the upgrade could lead to a partial upgrade if Yay fails between the two stages. Personally I do not like this argument, there are valid reasons to Yay to fail between these points. For example there may be dependency or conflict issues during the AUR upgrade. Yay can detect these before any installing actually starts and exit, just like how pacman will when there are dependency problems. If Yay does fail between these points, for the previously mentioned reasons or even a crash then a simple refresh will not cause a partial upgrade by itself. It is then the user's responsibility to either resolve these issues or instead perform an upgrade using pacman directly. My opinions aside, The discussions on the Arch wiki has reached a decision, this method is not recommended. So to follow the decided best practises this behaviour has been disabled by default. This behaviour can be toggled using the --[no]combinedupgrade flag It should be noted that Yay's upgrade menu will not show repo packages unless --combinedupgrade is used.
2018-06-22 15:44:38 +02:00
}
if err := configureAlpm(pacmanConf, alpmHandle); err != nil {
return nil, err
}
Separate Pacman upgrade and AUR Upgrade by default Currently When performing a system upgrade, Yay will first refresh the database then perform the repo and AUR upgrade. This allows Yay to add some features such as better batch interaction, showing potential dependency problems before the upgrade starts and combined menus showing AUR and repo upgrades together. There has been discussion that this approach is a bad idea. The main issue people have is that the separation of the database refresh and the upgrade could lead to a partial upgrade if Yay fails between the two stages. Personally I do not like this argument, there are valid reasons to Yay to fail between these points. For example there may be dependency or conflict issues during the AUR upgrade. Yay can detect these before any installing actually starts and exit, just like how pacman will when there are dependency problems. If Yay does fail between these points, for the previously mentioned reasons or even a crash then a simple refresh will not cause a partial upgrade by itself. It is then the user's responsibility to either resolve these issues or instead perform an upgrade using pacman directly. My opinions aside, The discussions on the Arch wiki has reached a decision, this method is not recommended. So to follow the decided best practises this behaviour has been disabled by default. This behaviour can be toggled using the --[no]combinedupgrade flag It should be noted that Yay's upgrade menu will not show repo packages unless --combinedupgrade is used.
2018-06-22 15:44:38 +02:00
alpmHandle.SetQuestionCallback(questionCallback)
return alpmHandle, nil
2018-03-22 16:46:48 +01:00
}
func exitOnError(err error) {
2018-03-22 16:46:48 +01:00
if err != nil {
if str := err.Error(); str != "" {
fmt.Fprintln(os.Stderr, str)
}
cleanup(config.Runtime.AlpmHandle)
os.Exit(1)
2018-03-22 16:46:48 +01:00
}
}
2018-03-22 16:46:48 +01:00
func cleanup(alpmHandle *alpm.Handle) int {
if alpmHandle != nil {
if err := alpmHandle.Release(); err != nil {
fmt.Fprintln(os.Stderr, err)
return 1
}
2018-03-22 16:46:48 +01:00
}
return 0
}
2018-03-22 16:46:48 +01:00
func main() {
initGotext()
2019-03-05 09:08:37 +01:00
if os.Geteuid() == 0 {
text.Warnln(gotext.Get("Avoid running yay as root/sudo."))
2018-03-22 16:46:48 +01:00
}
2020-07-08 03:22:01 +02:00
cmdArgs := settings.MakeArguments()
runtime, err := settings.MakeRuntime()
exitOnError(err)
config = settings.MakeConfig()
config.Runtime = runtime
exitOnError(initConfig(runtime.ConfigPath))
2020-07-05 02:45:23 +02:00
exitOnError(cmdArgs.ParseCommandLine(config))
if config.Runtime.SaveConfig {
errS := config.SaveConfig(runtime.ConfigPath)
if errS != nil {
fmt.Fprintln(os.Stderr, err)
}
2018-09-05 00:05:35 +02:00
}
config.ExpandEnv()
exitOnError(initBuildDir())
2020-07-05 03:26:00 +02:00
exitOnError(initVCS(runtime.VCSPath))
2020-07-08 03:31:35 +02:00
config.Runtime.AlpmHandle, config.Runtime.PacmanConf, err = initAlpm(cmdArgs, config.PacmanConf)
exitOnError(err)
config.Runtime.DBExecutor, err = db.NewAlpmExecutor(config.Runtime.AlpmHandle, runtime.PacmanConf, questionCallback)
exitOnError(err)
2020-07-08 03:31:35 +02:00
exitOnError(handleCmd(cmdArgs, config.Runtime.AlpmHandle))
os.Exit(cleanup(config.Runtime.AlpmHandle))
2018-03-22 16:46:48 +01:00
}