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)) }