diff --git a/clean.go b/clean.go index 8b2d3a67..9c5c50bf 100644 --- a/clean.go +++ b/clean.go @@ -50,11 +50,8 @@ func cleanRemove(pkgNames []string) error { return nil } - arguments := makeArguments() - err := arguments.addArg("R") - if err != nil { - return err - } + arguments := cmdArgs.copyGlobal() + _ = arguments.addArg("R") arguments.addTarget(pkgNames...) return show(passToPacman(arguments)) diff --git a/cmd.go b/cmd.go index da5b9fd1..4933ef5e 100644 --- a/cmd.go +++ b/cmd.go @@ -356,7 +356,7 @@ func displayNumberMenu(pkgS []string) (err error) { } include, exclude, _, otherExclude := types.ParseNumberMenu(string(numberBuf)) - arguments := makeArguments() + arguments := cmdArgs.copyGlobal() isInclude := len(exclude) == 0 && len(otherExclude) == 0 diff --git a/config.go b/config.go index fa854df1..2189d555 100644 --- a/config.go +++ b/config.go @@ -47,6 +47,7 @@ type Configuration struct { TarBin string `json:"tarbin"` ReDownload string `json:"redownload"` ReBuild string `json:"rebuild"` + BatchInstall bool `json:"batchinstall"` AnswerClean string `json:"answerclean"` AnswerDiff string `json:"answerdiff"` AnswerEdit string `json:"answeredit"` @@ -167,6 +168,7 @@ func defaultSettings() *Configuration { RequestSplitN: 150, ReDownload: "no", ReBuild: "no", + BatchInstall: false, AnswerClean: "", AnswerDiff: "", AnswerEdit: "", diff --git a/install.go b/install.go index d1530dda..18b93b66 100644 --- a/install.go +++ b/install.go @@ -15,6 +15,38 @@ import ( gosrc "github.com/Morganamilo/go-srcinfo" ) +func asdeps(parser *arguments, pkgs []string) error { + if len(pkgs) == 0 { + return nil + } + + parser = parser.copyGlobal() + _ = parser.addArg("D", "asdeps") + parser.addTarget(pkgs...) + _, stderr, err := capture(passToPacman(parser)) + if err != nil { + return fmt.Errorf("%s%s", stderr, err) + } + + return nil +} + +func asexp(parser *arguments, pkgs []string) error { + if len(pkgs) == 0 { + return nil + } + + parser = parser.copyGlobal() + _ = parser.addArg("D", "asexplicit") + parser.addTarget(pkgs...) + _, stderr, err := capture(passToPacman(parser)) + if err != nil { + return fmt.Errorf("%s%s", stderr, err) + } + + return nil +} + // Install handles package installs func install(parser *arguments) (err error) { var incompatible types.StringSet @@ -295,42 +327,27 @@ func install(parser *arguments) (err error) { return fmt.Errorf("Error installing repo packages") } - depArguments := makeArguments() - err = depArguments.addArg("D", "asdeps") - if err != nil { - return err - } - expArguments := makeArguments() - err = expArguments.addArg("D", "asexplicit") - if err != nil { - return err - } + deps := make([]string, 0) + exp := make([]string, 0) for _, pkg := range do.Repo { if !dp.Explicit.Get(pkg.Name()) && !localNamesCache.Get(pkg.Name()) && !remoteNamesCache.Get(pkg.Name()) { - depArguments.addTarget(pkg.Name()) + deps = append(deps, pkg.Name()) continue } if parser.existsArg("asdeps", "asdep") && dp.Explicit.Get(pkg.Name()) { - depArguments.addTarget(pkg.Name()) + deps = append(deps, pkg.Name()) } else if parser.existsArg("asexp", "asexplicit") && dp.Explicit.Get(pkg.Name()) { - expArguments.addTarget(pkg.Name()) + exp = append(exp, pkg.Name()) } } - if len(depArguments.targets) > 0 { - _, stderr, err := capture(passToPacman(depArguments)) - if err != nil { - return fmt.Errorf("%s%s", stderr, err) - } + if err = asdeps(parser, deps); err != nil { + return err } - - if len(expArguments.targets) > 0 { - _, stderr, err := capture(passToPacman(expArguments)) - if err != nil { - return fmt.Errorf("%s%s", stderr, err) - } + if err = asexp(parser, exp); err != nil { + return err } } @@ -943,11 +960,92 @@ func downloadPkgbuildsSources(bases []Base, incompatible types.StringSet) (err e } func buildInstallPkgbuilds(dp *depPool, do *depOrder, srcinfos map[string]*gosrc.Srcinfo, parser *arguments, incompatible types.StringSet, conflicts types.MapStringSet) error { + arguments := parser.copy() + arguments.clearTargets() + arguments.op = "U" + arguments.delArg("confirm") + arguments.delArg("noconfirm") + arguments.delArg("c", "clean") + arguments.delArg("q", "quiet") + arguments.delArg("q", "quiet") + arguments.delArg("y", "refresh") + arguments.delArg("u", "sysupgrade") + arguments.delArg("w", "downloadonly") + + deps := make([]string, 0) + exp := make([]string, 0) + oldConfirm := config.NoConfirm + config.NoConfirm = true + + //remotenames: names of all non repo packages on the system + _, _, localNames, remoteNames, err := filterPackages() + if err != nil { + return err + } + + //cache as a stringset. maybe make it return a string set in the first + //place + remoteNamesCache := types.SliceToStringSet(remoteNames) + localNamesCache := types.SliceToStringSet(localNames) + + doInstall := func() error { + if len(arguments.targets) == 0 { + return nil + } + + err := show(passToPacman(arguments)) + if err != nil { + return err + } + + err = saveVCSInfo() + if err != nil { + fmt.Fprintln(os.Stderr, err) + } + + if err = asdeps(parser, deps); err != nil { + return err + } + if err = asexp(parser, exp); err != nil { + return err + } + + config.NoConfirm = oldConfirm + + arguments.clearTargets() + deps = make([]string, 0) + exp = make([]string, 0) + config.NoConfirm = true + return nil + } + for _, base := range do.Aur { + var err error pkg := base.Pkgbase() dir := filepath.Join(config.BuildDir, pkg) built := true + satisfied := true + all: + for _, pkg := range base { + for _, deps := range [3][]string{pkg.Depends, pkg.MakeDepends, pkg.CheckDepends} { + for _, dep := range deps { + if _, err := dp.LocalDB.PkgCache().FindSatisfier(dep); err != nil { + satisfied = false + fmt.Printf("%s not satisfied, flushing install queue\n", dep) + break all + } + } + } + } + + if !satisfied || !config.BatchInstall { + err = doInstall() + if err != nil { + return err + } + } + srcinfo := srcinfos[pkg] args := []string{"--nobuild", "-fC"} @@ -957,7 +1055,7 @@ func buildInstallPkgbuilds(dp *depPool, do *depOrder, srcinfos map[string]*gosrc } //pkgver bump - err := show(passToMakepkg(dir, args...)) + err = show(passToMakepkg(dir, args...)) if err != nil { return fmt.Errorf("Error making: %s", base.String()) } @@ -1029,60 +1127,20 @@ func buildInstallPkgbuilds(dp *depPool, do *depOrder, srcinfos map[string]*gosrc } } - arguments := parser.copy() - arguments.clearTargets() - arguments.op = "U" - arguments.delArg("confirm") - arguments.delArg("noconfirm") - arguments.delArg("c", "clean") - arguments.delArg("q", "quiet") - arguments.delArg("q", "quiet") - arguments.delArg("y", "refresh") - arguments.delArg("u", "sysupgrade") - arguments.delArg("w", "downloadonly") - - oldConfirm := config.NoConfirm - //conflicts have been checked so answer y for them if config.UseAsk { ask, _ := strconv.Atoi(cmdArgs.globals["ask"]) uask := alpm.QuestionType(ask) | alpm.QuestionTypeConflictPkg cmdArgs.globals["ask"] = fmt.Sprint(uask) } else { - conflict := false for _, split := range base { if _, ok := conflicts[split.Name]; ok { - conflict = true + config.NoConfirm = false + break } } - - if !conflict { - config.NoConfirm = true - } } - depArguments := makeArguments() - err = depArguments.addArg("D", "asdeps") - if err != nil { - return err - } - expArguments := makeArguments() - err = expArguments.addArg("D", "asexplicit") - if err != nil { - return err - } - - //remotenames: names of all non repo packages on the system - _, _, localNames, remoteNames, err := filterPackages() - if err != nil { - return err - } - - //cache as a stringset. maybe make it return a string set in the first - //place - remoteNamesCache := types.SliceToStringSet(remoteNames) - localNamesCache := types.SliceToStringSet(localNames) - for _, split := range base { pkgdest, ok := pkgdests[split.Name] if !ok { @@ -1090,22 +1148,13 @@ func buildInstallPkgbuilds(dp *depPool, do *depOrder, srcinfos map[string]*gosrc } arguments.addTarget(pkgdest) - if !dp.Explicit.Get(split.Name) && !localNamesCache.Get(split.Name) && !remoteNamesCache.Get(split.Name) { - depArguments.addTarget(split.Name) + if parser.existsArg("asdeps", "asdep") { + deps = append(deps, split.Name) + } else if parser.existsArg("asexplicit", "asexp") { + exp = append(exp, split.Name) + } else if !dp.Explicit.Get(split.Name) && !localNamesCache.Get(split.Name) && !remoteNamesCache.Get(split.Name) { + deps = append(deps, split.Name) } - - if dp.Explicit.Get(split.Name) { - if parser.existsArg("asdeps", "asdep") { - depArguments.addTarget(split.Name) - } else if parser.existsArg("asexplicit", "asexp") { - expArguments.addTarget(split.Name) - } - } - } - - err = show(passToPacman(arguments)) - if err != nil { - return err } var mux sync.Mutex @@ -1116,20 +1165,9 @@ func buildInstallPkgbuilds(dp *depPool, do *depOrder, srcinfos map[string]*gosrc } wg.Wait() - - err = saveVCSInfo() - if err != nil { - fmt.Fprintln(os.Stderr, err) - } - - if len(depArguments.targets) > 0 { - _, stderr, err := capture(passToPacman(depArguments)) - if err != nil { - return fmt.Errorf("%s%s", stderr, err) - } - } - config.NoConfirm = oldConfirm } - return nil + err = doInstall() + config.NoConfirm = oldConfirm + return err } diff --git a/parser.go b/parser.go index 3003ef4a..3fad57c8 100644 --- a/parser.go +++ b/parser.go @@ -33,6 +33,15 @@ func makeArguments() *arguments { } } +func (parser *arguments) copyGlobal() (cp *arguments) { + cp = makeArguments() + for k, v := range parser.globals { + cp.globals[k] = v + } + + return +} + func (parser *arguments) copy() (cp *arguments) { cp = makeArguments() @@ -386,6 +395,8 @@ func isArg(arg string) bool { case "rebuildall": case "rebuildtree": case "norebuild": + case "batchinstall": + case "nobatchinstall": case "answerclean": case "noanswerclean": case "answerdiff": @@ -494,6 +505,10 @@ func handleConfig(option, value string) bool { config.ReBuild = "tree" case "norebuild": config.ReBuild = "no" + case "batchinstall": + config.BatchInstall = true + case "nobatchinstall": + config.BatchInstall = false case "answerclean": config.AnswerClean = value case "noanswerclean":