From cdaee7d1d4e0bd4f1a8cedf3aa6b480f1b628242 Mon Sep 17 00:00:00 2001 From: morganamilo Date: Thu, 15 Feb 2018 21:23:34 +0000 Subject: [PATCH] Improve support for split packages Split packages are now grouped together when printing displaying the package base and the packages inside of the base to beinstalled. If only one packge is to be installed from a base and the package name matches the base name print normally Only build and install once per package base Only ask questions once per package base for editing pkgbuils and clean build --- dependencies.go | 56 ++++++++++------ install.go | 174 ++++++++++++++++++++++++++---------------------- print.go | 97 ++++++++++++++++++++------- 3 files changed, 205 insertions(+), 122 deletions(-) diff --git a/dependencies.go b/dependencies.go index 1d2de0e4..38d7b669 100644 --- a/dependencies.go +++ b/dependencies.go @@ -16,9 +16,10 @@ type depTree struct { type depCatagories struct { Repo []*alpm.Package - RepoMake []*alpm.Package - Aur []*rpc.Pkg - AurMake []*rpc.Pkg + Aur[]*rpc.Pkg + MakeOnly stringSet + Bases map[string][]*rpc.Pkg + } func makeDepTree() *depTree { @@ -34,10 +35,10 @@ func makeDepTree() *depTree { func makeDependCatagories() *depCatagories { dc := depCatagories{ - make([]*alpm.Package, 0), make([]*alpm.Package, 0), make([]*rpc.Pkg, 0), - make([]*rpc.Pkg, 0), + make(stringSet), + make(map[string][]*rpc.Pkg), } return &dc @@ -51,6 +52,7 @@ func getNameFromDep(dep string) string { func getDepCatagories(pkgs []string, dt *depTree) (*depCatagories, error) { dc := makeDependCatagories() + seen := make(stringSet) for _, pkg := range pkgs { dep := getNameFromDep(pkg) @@ -63,12 +65,22 @@ func getDepCatagories(pkgs []string, dt *depTree) (*depCatagories, error) { aurpkg, exists := dt.Aur[dep] if exists { - depCatagoriesRecursive(aurpkg, dc, dt, false) - dc.Aur = append(dc.Aur, aurpkg) + depCatagoriesRecursive(aurpkg, dc, dt, false, seen) + if !seen.get(aurpkg.PackageBase) { + dc.Aur = append(dc.Aur, aurpkg) + seen.set(aurpkg.PackageBase) + } + + _, ok := dc.Bases[aurpkg.PackageBase] + if !ok { + dc.Bases[aurpkg.PackageBase] = make([]*rpc.Pkg, 0) + } + dc.Bases[aurpkg.PackageBase] = append(dc.Bases[aurpkg.PackageBase], aurpkg) delete(dt.Aur, dep) } } + return dc, nil } @@ -81,33 +93,40 @@ func repoDepCatagoriesRecursive(pkg *alpm.Package, dc *depCatagories, dt *depTre repoDepCatagoriesRecursive(alpmpkg, dc, dt, isMake) if isMake { - dc.RepoMake = append(dc.RepoMake, alpmpkg) - } else { - dc.Repo = append(dc.Repo, alpmpkg) + dc.MakeOnly.set(alpmpkg.Name()) } + dc.Repo = append(dc.Repo, alpmpkg) } return nil }) } -func depCatagoriesRecursive(pkg *rpc.Pkg, dc *depCatagories, dt *depTree, isMake bool) { +func depCatagoriesRecursive(pkg *rpc.Pkg, dc *depCatagories, dt *depTree, isMake bool, seen stringSet) { for _, deps := range [2][]string{pkg.Depends, pkg.MakeDepends} { for _, _dep := range deps { dep := getNameFromDep(_dep) aurpkg, exists := dt.Aur[dep] if exists { - delete(dt.Aur, dep) - depCatagoriesRecursive(aurpkg, dc, dt, isMake) + _, ok := dc.Bases[aurpkg.PackageBase] + if !ok { + dc.Bases[aurpkg.PackageBase] = make([]*rpc.Pkg, 0) + } + dc.Bases[aurpkg.PackageBase] = append(dc.Bases[aurpkg.PackageBase], aurpkg) - if isMake { - dc.AurMake = append(dc.AurMake, aurpkg) - } else { + delete(dt.Aur, dep) + depCatagoriesRecursive(aurpkg, dc, dt, isMake, seen) + + if !seen.get(aurpkg.PackageBase) { dc.Aur = append(dc.Aur, aurpkg) + seen.set(aurpkg.PackageBase) } + if isMake { + dc.MakeOnly.set(aurpkg.Name) + } } alpmpkg, exists := dt.Repo[dep] @@ -116,11 +135,10 @@ func depCatagoriesRecursive(pkg *rpc.Pkg, dc *depCatagories, dt *depTree, isMake repoDepCatagoriesRecursive(alpmpkg, dc, dt, isMake) if isMake { - dc.RepoMake = append(dc.RepoMake, alpmpkg) - } else { - dc.Repo = append(dc.Repo, alpmpkg) + dc.MakeOnly.set(alpmpkg.Name()) } + dc.Repo = append(dc.Repo, alpmpkg) } } diff --git a/install.go b/install.go index d6c92b35..d5da9052 100644 --- a/install.go +++ b/install.go @@ -40,7 +40,7 @@ func install(parser *arguments) error { } if len(aurs) != 0 { - //todo make pretty + //todo mamakeke pretty fmt.Println(greenFg(arrow), greenFg("Resolving Dependencies")) dt, err := getDepTree(aurs) @@ -58,13 +58,6 @@ func install(parser *arguments) error { return err } - for _, pkg := range dc.AurMake { - if pkg.Maintainer == "" { - fmt.Println(boldRedFgBlackBg(arrow+" Warning:"), - blackBg(pkg.Name+"-"+pkg.Version+" is orphaned")) - } - } - for _, pkg := range dc.Aur { if pkg.Maintainer == "" { fmt.Println(boldRedFgBlackBg(arrow+" Warning:"), @@ -72,20 +65,24 @@ func install(parser *arguments) error { } } - printDownloadsFromRepo("Repo", dc.Repo) - printDownloadsFromRepo("Repo Make", dc.RepoMake) - printDownloadsFromAur("AUR", dc.Aur) - printDownloadsFromAur("AUR Make", dc.AurMake) + //printDownloadsFromRepo("Repo", dc.Repo) + //printDownloadsFromRepo("Repo Make", dc.RepoMake) + //printDownloadsFromAur("AUR", dc.Aur) + //printDownloadsFromAur("AUR Make", dc.AurMake) + + //fmt.Println(dc.MakeOnly) + //fmt.Println(dc.AurSet) - askCleanBuilds(dc.AurMake) - askCleanBuilds(dc.Aur) + printDepCatagories(dc) + + askCleanBuilds(dc.Aur, dc.Bases) fmt.Println() if !continueTask("Proceed with install?", "nN") { return fmt.Errorf("Aborting due to user") } - if len(dc.RepoMake) + len(dc.Repo) > 0 { + if len(dc.Repo) > 0 { arguments := parser.copy() arguments.delArg("u", "sysupgrade") arguments.delArg("y", "refresh") @@ -95,9 +92,6 @@ func install(parser *arguments) error { for _, pkg := range dc.Repo { arguments.addTarget(pkg.Name()) } - for _, pkg := range dc.RepoMake { - arguments.addTarget(pkg.Name()) - } oldConfirm := config.NoConfirm config.NoConfirm = true @@ -113,26 +107,18 @@ func install(parser *arguments) error { // } if _, ok := arguments.options["gendb"]; !ok { - err = checkForConflicts(dc.Aur, dc.AurMake, dc.Repo, dc.RepoMake) + //err = checkForConflicts(dc.Aur, dc.AurMake, dc.Repo, dc.RepoMake) if err != nil { return err } } - err = dowloadPkgBuilds(dc.AurMake) - if err != nil { - return err - } - err = dowloadPkgBuilds(dc.Aur) + err = dowloadPkgBuilds(dc.Aur, dc.Bases) if err != nil { return err } - err = askEditPkgBuilds(dc.AurMake) - if err != nil { - return err - } - err = askEditPkgBuilds(dc.Aur) + err = askEditPkgBuilds(dc.Aur, dc.Bases) if err != nil { return err } @@ -146,34 +132,22 @@ func install(parser *arguments) error { // return fmt.Errorf("Aborting due to user") // } - err = downloadPkgBuildsSources(dc.AurMake) - if err != nil { - return err - } err = downloadPkgBuildsSources(dc.Aur) if err != nil { return err } - err = parsesrcinfos(dc.AurMake, srcinfos) - if err != nil { - return err - } err = parsesrcinfos(dc.Aur, srcinfos) if err != nil { return err } - err = buildInstallPkgBuilds(dc.AurMake, srcinfos, parser.targets, parser) - if err != nil { - return err - } - err = buildInstallPkgBuilds(dc.Aur, srcinfos, parser.targets, parser) + err = buildInstallPkgBuilds(dc.Aur, srcinfos, parser.targets, parser, dc.Bases) if err != nil { return err } - if len(dc.RepoMake)+len(dc.AurMake) > 0 { + if len(dc.MakeOnly) > 0 { if continueTask("Remove make dependencies?", "yY") { return nil } @@ -181,12 +155,8 @@ func install(parser *arguments) error { removeArguments := makeArguments() removeArguments.addArg("R", "u") - for _, pkg := range dc.RepoMake { - removeArguments.addTarget(pkg.Name()) - } - - for _, pkg := range dc.AurMake { - removeArguments.addTarget(pkg.Name) + for pkg := range dc.MakeOnly { + removeArguments.addTarget(pkg) } oldValue := config.NoConfirm @@ -196,7 +166,6 @@ func install(parser *arguments) error { } if config.CleanAfter { - clean(dc.AurMake) clean(dc.Aur) } @@ -206,12 +175,21 @@ func install(parser *arguments) error { return nil } -func askCleanBuilds(pkgs []*rpc.Pkg) { +func askCleanBuilds(pkgs []*rpc.Pkg, bases map[string][]*rpc.Pkg) { for _, pkg := range pkgs { dir := config.BuildDir + pkg.PackageBase + "/" if _, err := os.Stat(dir); !os.IsNotExist(err) { - if !continueTask(pkg.Name+" Directory exists. Clean Build?", "yY") { + str := pkg.Name + if len(bases[pkg.PackageBase]) > 1 || pkg.PackageBase != pkg.Name { + str += " (" + for _, split := range bases[pkg.PackageBase] { + str += split.Name + " " + } + str = str[:len(str)-1] + ")" + } + + if !continueTask(str + " Directory exists. Clean Build?", "yY") { _ = os.RemoveAll(config.BuildDir + pkg.PackageBase) } } @@ -288,11 +266,20 @@ func checkForConflicts(aur []*rpc.Pkg, aurMake []*rpc.Pkg, repo []*alpm.Package, return nil } -func askEditPkgBuilds(pkgs []*rpc.Pkg) (error) { +func askEditPkgBuilds(pkgs []*rpc.Pkg, bases map[string][]*rpc.Pkg) (error) { for _, pkg := range pkgs { dir := config.BuildDir + pkg.PackageBase + "/" - if !continueTask(pkg.Name+" Edit PKGBUILD?", "yY") { + str := "Edit PKGBUILD? " + pkg.PackageBase + if len(bases[pkg.PackageBase]) > 1 || pkg.PackageBase != pkg.Name { + str += " (" + for _, split := range bases[pkg.PackageBase] { + str += split.Name + " " + } + str = str[:len(str)-1] + ")" + } + + if !continueTask(str, "yY") { editcmd := exec.Command(editor(), dir+"PKGBUILD") editcmd.Stdin, editcmd.Stdout, editcmd.Stderr = os.Stdin, os.Stdout, os.Stderr editcmd.Run() @@ -336,10 +323,18 @@ func parsesrcinfos(pkgs []*rpc.Pkg, srcinfos map[string]*gopkg.PKGBUILD) (error) return nil } -func dowloadPkgBuilds(pkgs []*rpc.Pkg) (err error) { +func dowloadPkgBuilds(pkgs []*rpc.Pkg, bases map[string][]*rpc.Pkg) (err error) { for _, pkg := range pkgs { //todo make pretty - fmt.Println("Downloading:", pkg.Name+"-"+pkg.Version) + str := "Downloading: " + pkg.PackageBase+"-"+pkg.Version + if len(bases[pkg.PackageBase]) > 1 || pkg.PackageBase != pkg.Name { + str += " (" + for _, split := range bases[pkg.PackageBase] { + str += split.Name + " " + } + str = str[:len(str)-1] + ")" + } + fmt.Println(str) err = downloadAndUnpack(baseURL+pkg.URLPath, config.BuildDir, false) if err != nil { @@ -362,32 +357,35 @@ func downloadPkgBuildsSources(pkgs []*rpc.Pkg) (err error) { return } -func buildInstallPkgBuilds(pkgs []*rpc.Pkg, srcinfos map[string]*gopkg.PKGBUILD, targets stringSet, parser *arguments) (error) { +func buildInstallPkgBuilds(pkgs []*rpc.Pkg, srcinfos map[string]*gopkg.PKGBUILD, targets stringSet, parser *arguments, bases map[string][]*rpc.Pkg) (error) { //for n := len(pkgs) -1 ; n > 0; n-- { for n := 0; n < len(pkgs); n++ { pkg := pkgs[n] + dir := config.BuildDir + pkg.PackageBase + "/" + built := true srcinfo := srcinfos[pkg.PackageBase] version := srcinfo.CompleteVersion() - file, err := completeFileName(dir, pkg.Name + "-" + version.String()) - if file != "" { - fmt.Println(boldRedFgBlackBg(arrow+" Warning:"), - blackBg(pkg.Name+"-"+pkg.Version+ " Already made -- skipping build")) - } else { - err = passToMakepkg(dir, "-Cscf", "--noconfirm") - if err != nil { - return err - } - - file, err = completeFileName(dir, pkg.Name + "-" + version.String()) + for _, split:= range bases[pkg.PackageBase] { + file, err := completeFileName(dir, split.Name + "-" + version.String()) if err != nil { return err } if file == "" { - return fmt.Errorf("Could not find built package") + built = false + } + } + + if built { + fmt.Println(boldRedFgBlackBg(arrow+" Warning:"), + blackBg(pkg.Name+"-"+pkg.Version+ " Already made -- skipping build")) + } else { + err := passToMakepkg(dir, "-Cscf", "--noconfirm") + if err != nil { + return err } } @@ -402,20 +400,38 @@ func buildInstallPkgBuilds(pkgs []*rpc.Pkg, srcinfos map[string]*gopkg.PKGBUILD, arguments.delArg("u", "sysupgrade") arguments.delArg("w", "downloadonly") + depArguments := makeArguments() + depArguments.addArg("D", "asdeps") + + for _, split := range bases[pkg.PackageBase] { + file, err := completeFileName(dir, split.Name + "-" + version.String()) + if err != nil { + return err + } + + if file == "" { + return fmt.Errorf("Could not find built package " + split.Name + "-" + version.String()) + } + + arguments.addTarget(file) + if !targets.get(split.Name) { + depArguments.addTarget(split.Name) + } + } + oldConfirm := config.NoConfirm config.NoConfirm = true - - if targets.get(pkg.Name) { - arguments.addArg("asdeps") - } - - arguments.addTarget(file) - - err = passToPacman(arguments) - config.NoConfirm = oldConfirm - if err !=nil { + err := passToPacman(arguments) + if err != nil { return err } + if len(depArguments.targets) > 0 { + err = passToPacman(depArguments) + if err != nil { + return err + } + } + config.NoConfirm = oldConfirm } return nil diff --git a/print.go b/print.go index 6535aaba..d5e62f35 100644 --- a/print.go +++ b/print.go @@ -95,32 +95,81 @@ func (s repoQuery) printSearch() { } // printDownloadsFromRepo prints repository packages to be downloaded -func printDownloadsFromRepo(repoType string, repo []*alpm.Package) { - var packages string - for _, v := range repo { - packages += v.Name() + " " +func printDepCatagories(dc *depCatagories) { + repo := "" + repoMake := "" + aur := "" + aurMake := "" + + repoLen := 0 + repoMakeLen := 0 + aurLen := 0 + aurMakeLen := 0 + + for _, pkg := range dc.Repo { + if dc.MakeOnly.get(pkg.Name()) { + repoMake += " " + pkg.Name() + repoMakeLen++ + } else { + repo += " " + pkg.Name() + repoLen++ + } } + + for _, pkg := range dc.Aur { + pkgStr := " " + pkg.PackageBase + pkgStrMake := pkgStr + + push := false + pushMake := false + + if len(dc.Bases[pkg.PackageBase]) > 1 || pkg.PackageBase != pkg.Name { + pkgStr += " (" + pkgStrMake += " (" + + for _, split := range dc.Bases[pkg.PackageBase] { + if dc.MakeOnly.get(split.Name) { + pkgStrMake += split.Name + " " + aurMakeLen++ + pushMake = true + } else { + pkgStr += split.Name + " " + aurLen++ + push = true + } + } + + pkgStr = pkgStr[:len(pkgStr)-1] + ")" + pkgStrMake = pkgStrMake[:len(pkgStrMake)-1] + ")" + } else if dc.MakeOnly.get(pkg.Name) { + aurMakeLen++ + pushMake = true + } else { + aurLen++ + push = true + } + + if push { + aur += pkgStr + } + if pushMake { + aurMake += pkgStrMake + } + } + + printDownloads("Repo", repoLen, repo) + printDownloads("Repo Make", repoMakeLen, repoMake) + printDownloads("Aur", aurLen, aur) + printDownloads("Aur Make", aurMakeLen, aurMake) +} + +func printDownloads(repoName string, length int, packages string) { + if length < 1 { + return + } + repoInfo := boldBlueFg( - "[" + repoType + ", " + strconv.Itoa(len(repo)) + " packages] ") - if len(repo) > 0 { - printDownloads(repoInfo, packages) - } -} - -// printDownloadsFromAur prints AUR packages to be downloaded -func printDownloadsFromAur(repoType string, repo []*rpc.Pkg) { - var packages string - for _, v := range repo { - packages += v.Name + " " - } - repoInfo := redFg( - "[" + repoType + ", " + strconv.Itoa(len(repo)) + " packages] ") - if len(repo) > 0 { - printDownloads(repoInfo, packages) - } -} - -func printDownloads(repoInfo, packages string) { + "[" + repoName + ": " + strconv.Itoa(length) + "]") fmt.Println(repoInfo + yellowFg(packages)) }