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
This commit is contained in:
morganamilo committed 2018-02-16 15:49:18 +00:00
1 parent e1f3cb6682
commit cdaee7d1d4
3 files changed
+205 -122

No files matched your search

+37 -19
View File
@@ -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)
}
}
+95 -79
View File
@@ -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
+73 -24
View File
@@ -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))
}