Bug fixes and added pre_update.sh pacakge scripts #7

Merged
EnumDev merged 5 commits from develop into master 2024-10-23 06:18:01 +00:00
5 changed files with 92 additions and 33 deletions

1
go.mod
View File

@ -4,5 +4,6 @@ go 1.22
require ( require (
github.com/elliotchance/orderedmap/v2 v2.4.0 // indirect github.com/elliotchance/orderedmap/v2 v2.4.0 // indirect
github.com/knqyf263/go-rpm-version v0.0.0-20240918084003-2afd7dc6a38f // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect
) )

4
go.sum
View File

@ -1,5 +1,9 @@
github.com/elliotchance/orderedmap/v2 v2.4.0 h1:6tUmMwD9F998FNpwFxA5E6NQvSpk2PVw7RKsVq3+2Cw= github.com/elliotchance/orderedmap/v2 v2.4.0 h1:6tUmMwD9F998FNpwFxA5E6NQvSpk2PVw7RKsVq3+2Cw=
github.com/elliotchance/orderedmap/v2 v2.4.0/go.mod h1:85lZyVbpGaGvHvnKa7Qhx7zncAdBIBq6u56Hb1PRU5Q= github.com/elliotchance/orderedmap/v2 v2.4.0/go.mod h1:85lZyVbpGaGvHvnKa7Qhx7zncAdBIBq6u56Hb1PRU5Q=
github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY=
github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
github.com/knqyf263/go-rpm-version v0.0.0-20240918084003-2afd7dc6a38f h1:xt29M2T6STgldg+WEP51gGePQCsQvklmP2eIhPIBK3g=
github.com/knqyf263/go-rpm-version v0.0.0-20240918084003-2afd7dc6a38f/go.mod h1:i4sF0l1fFnY1aiw08QQSwVAFxHEm311Me3WsU/X7nL0=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

62
main.go
View File

@ -47,8 +47,8 @@ func main() {
type commandType uint8 type commandType uint8
const ( const (
help commandType = iota _default commandType = iota
version help
info info
list list
search search
@ -62,7 +62,7 @@ const (
func getCommandType() commandType { func getCommandType() commandType {
switch subcommand { switch subcommand {
case "version": case "version":
return version return _default
case "info": case "info":
return info return info
case "list": case "list":
@ -86,7 +86,7 @@ func getCommandType() commandType {
func resolveCommand() { func resolveCommand() {
switch getCommandType() { switch getCommandType() {
case version: case _default:
fmt.Println("Bubble Package Manager (BPM)") fmt.Println("Bubble Package Manager (BPM)")
fmt.Println("Version: " + bpmVer) fmt.Println("Version: " + bpmVer)
case info: case info:
@ -224,7 +224,7 @@ func resolveCommand() {
}]() }]()
for _, pkg := range clone.Keys() { for _, pkg := range clone.Keys() {
value, _ := clone.Get(pkg) value, _ := clone.Get(pkg)
resolved, unresolved := value.pkgInfo.ResolveAll(&[]string{}, &[]string{}, value.pkgInfo.Type == "source", !noOptional, !reinstall, rootDir) resolved, unresolved := value.pkgInfo.ResolveAll(&[]string{}, &[]string{}, value.pkgInfo.Type == "source", !noOptional, !reinstall, verbose, rootDir)
unresolvedDepends = append(unresolvedDepends, unresolved...) unresolvedDepends = append(unresolvedDepends, unresolved...)
for _, depend := range resolved { for _, depend := range resolved {
if _, ok := pkgsToInstall.Get(depend); !ok && depend != value.pkgInfo.Name { if _, ok := pkgsToInstall.Get(depend); !ok && depend != value.pkgInfo.Name {
@ -270,14 +270,18 @@ func resolveCommand() {
} }
sourceInfo = "(From Source)" sourceInfo = "(From Source)"
} }
if installedInfo == nil { if installedInfo == nil {
fmt.Printf("%s: %s (Install) %s\n", pkgInfo.Name, pkgInfo.GetFullVersion(), sourceInfo) fmt.Printf("%s: %s (Install) %s\n", pkgInfo.Name, pkgInfo.GetFullVersion(), sourceInfo)
} else if strings.Compare(pkgInfo.GetFullVersion(), installedInfo.GetFullVersion()) < 0 {
fmt.Printf("%s: %s -> %s (Downgrade) %s\n", pkgInfo.Name, installedInfo.GetFullVersion(), pkgInfo.GetFullVersion(), sourceInfo)
} else if strings.Compare(pkgInfo.GetFullVersion(), installedInfo.GetFullVersion()) > 0 {
fmt.Printf("%s: %s -> %s (Upgrade) %s\n", pkgInfo.Name, installedInfo.GetFullVersion(), pkgInfo.GetFullVersion(), sourceInfo)
} else { } else {
fmt.Printf("%s: %s (Reinstall) %s\n", pkgInfo.Name, pkgInfo.GetFullVersion(), sourceInfo) comparison := utils.ComparePackageVersions(*pkgInfo, *installedInfo)
if comparison < 0 {
fmt.Printf("%s: %s -> %s (Downgrade) %s\n", pkgInfo.Name, installedInfo.GetFullVersion(), pkgInfo.GetFullVersion(), sourceInfo)
} else if comparison > 0 {
fmt.Printf("%s: %s -> %s (Upgrade) %s\n", pkgInfo.Name, installedInfo.GetFullVersion(), pkgInfo.GetFullVersion(), sourceInfo)
} else {
fmt.Printf("%s: %s (Reinstall) %s\n", pkgInfo.Name, pkgInfo.GetFullVersion(), sourceInfo)
}
} }
} }
if rootDir != "/" { if rootDir != "/" {
@ -382,17 +386,19 @@ func resolveCommand() {
installedInfo := utils.GetPackageInfo(pkg, rootDir, true) installedInfo := utils.GetPackageInfo(pkg, rootDir, true)
if installedInfo == nil { if installedInfo == nil {
log.Fatalf("Error: could not get package info for (%s)\n", pkg) log.Fatalf("Error: could not get package info for (%s)\n", pkg)
} } else {
if strings.Compare(entry.Info.GetFullVersion(), installedInfo.GetFullVersion()) > 0 { comparison := utils.ComparePackageVersions(*entry.Info, *installedInfo)
toUpdate.Set(entry.Info.Name, &struct { if comparison > 0 {
isDependency bool toUpdate.Set(entry.Info.Name, &struct {
entry *utils.RepositoryEntry isDependency bool
}{isDependency: false, entry: entry}) entry *utils.RepositoryEntry
} else if reinstall { }{isDependency: false, entry: entry})
toUpdate.Set(entry.Info.Name, &struct { } else if reinstall {
isDependency bool toUpdate.Set(entry.Info.Name, &struct {
entry *utils.RepositoryEntry isDependency bool
}{isDependency: false, entry: entry}) entry *utils.RepositoryEntry
}{isDependency: false, entry: entry})
}
} }
} }
if toUpdate.Len() == 0 { if toUpdate.Len() == 0 {
@ -405,7 +411,7 @@ func resolveCommand() {
clone := toUpdate.Copy() clone := toUpdate.Copy()
for _, key := range clone.Keys() { for _, key := range clone.Keys() {
pkg, _ := clone.Get(key) pkg, _ := clone.Get(key)
r, u := pkg.entry.Info.ResolveAll(&[]string{}, &[]string{}, pkg.entry.Info.Type == "source", !noOptional, true, rootDir) r, u := pkg.entry.Info.ResolveAll(&[]string{}, &[]string{}, pkg.entry.Info.Type == "source", !noOptional, true, verbose, rootDir)
unresolved = append(unresolved, u...) unresolved = append(unresolved, u...)
for _, depend := range r { for _, depend := range r {
if _, ok := toUpdate.Get(depend); !ok { if _, ok := toUpdate.Get(depend); !ok {
@ -439,11 +445,13 @@ func resolveCommand() {
if installedInfo == nil { if installedInfo == nil {
fmt.Printf("%s: %s (Install) %s\n", value.entry.Info.Name, value.entry.Info.GetFullVersion(), sourceInfo) fmt.Printf("%s: %s (Install) %s\n", value.entry.Info.Name, value.entry.Info.GetFullVersion(), sourceInfo)
continue continue
} } else {
if strings.Compare(value.entry.Info.GetFullVersion(), installedInfo.GetFullVersion()) > 0 { comparison := utils.ComparePackageVersions(*value.entry.Info, *installedInfo)
fmt.Printf("%s: %s -> %s (Upgrade) %s\n", value.entry.Info.Name, installedInfo.GetFullVersion(), value.entry.Info.GetFullVersion(), sourceInfo) if comparison > 0 {
} else if reinstall { fmt.Printf("%s: %s -> %s (Upgrade) %s\n", value.entry.Info.Name, installedInfo.GetFullVersion(), value.entry.Info.GetFullVersion(), sourceInfo)
fmt.Printf("%s: %s -> %s (Reinstall) %s\n", value.entry.Info.Name, installedInfo.GetFullVersion(), value.entry.Info.GetFullVersion(), sourceInfo) } else if reinstall {
fmt.Printf("%s: %s -> %s (Reinstall) %s\n", value.entry.Info.Name, installedInfo.GetFullVersion(), value.entry.Info.GetFullVersion(), sourceInfo)
}
} }
} }

View File

@ -6,6 +6,7 @@ import (
"compress/gzip" "compress/gzip"
"errors" "errors"
"fmt" "fmt"
version "github.com/knqyf263/go-rpm-version"
"gopkg.in/yaml.v3" "gopkg.in/yaml.v3"
"io" "io"
"io/fs" "io/fs"
@ -48,6 +49,13 @@ const (
Unknown InstallationReason = "unknown" Unknown InstallationReason = "unknown"
) )
func ComparePackageVersions(info1, info2 PackageInfo) int {
v1 := version.NewVersion(info1.GetFullVersion())
v2 := version.NewVersion(info2.GetFullVersion())
return v1.Compare(v2)
}
func GetInstallationReason(pkg, rootDir string) InstallationReason { func GetInstallationReason(pkg, rootDir string) InstallationReason {
installedDir := path.Join(rootDir, "var/lib/bpm/installed/") installedDir := path.Join(rootDir, "var/lib/bpm/installed/")
pkgDir := path.Join(installedDir, pkg) pkgDir := path.Join(installedDir, pkg)
@ -308,6 +316,12 @@ func ExecutePackageScripts(filename, rootDir string, operation Operation, postOp
} }
} }
} else if operation == Remove { } else if operation == Remove {
if val, ok := scripts["pre_remove.sh"]; !postOperation && ok {
err := run("pre_remove.sh", val)
if err != nil {
return err
}
}
if val, ok := scripts["post_remove.sh"]; postOperation && ok { if val, ok := scripts["post_remove.sh"]; postOperation && ok {
err := run("post_remove.sh", val) err := run("post_remove.sh", val)
if err != nil { if err != nil {
@ -1270,11 +1284,21 @@ func (pkgInfo *PackageInfo) CheckConflicts(rootDir string) []string {
return ret return ret
} }
func (pkgInfo *PackageInfo) ResolveAll(resolved, unresolved *[]string, checkMake, checkOptional, ignoreInstalled bool, rootDir string) ([]string, []string) { func (pkgInfo *PackageInfo) ResolveAll(resolved, unresolved *[]string, checkMake, checkOptional, ignoreInstalled, verbose bool, rootDir string) ([]string, []string) {
*unresolved = append(*unresolved, pkgInfo.Name) *unresolved = append(*unresolved, pkgInfo.Name)
for _, depend := range pkgInfo.GetAllDependencies(checkMake, checkOptional) { for _, depend := range pkgInfo.GetAllDependencies(checkMake, checkOptional) {
depend = strings.TrimSpace(depend)
depend = strings.ToLower(depend)
if !slices.Contains(*resolved, depend) { if !slices.Contains(*resolved, depend) {
if slices.Contains(*unresolved, depend) || (ignoreInstalled && IsPackageInstalled(depend, rootDir)) { if slices.Contains(*unresolved, depend) {
if verbose {
fmt.Printf("Circular dependency was detected (%s -> %s). Installing %s first\n", pkgInfo.Name, depend, depend)
}
if !slices.Contains(*resolved, depend) {
*resolved = append(*resolved, depend)
}
continue
} else if ignoreInstalled && IsPackageInstalled(depend, rootDir) {
continue continue
} }
entry, _, err := GetRepositoryEntry(depend) entry, _, err := GetRepositoryEntry(depend)
@ -1284,7 +1308,7 @@ func (pkgInfo *PackageInfo) ResolveAll(resolved, unresolved *[]string, checkMake
} }
continue continue
} }
entry.Info.ResolveAll(resolved, unresolved, checkMake, checkOptional, ignoreInstalled, rootDir) entry.Info.ResolveAll(resolved, unresolved, checkMake, checkOptional, ignoreInstalled, verbose, rootDir)
} }
} }
if !slices.Contains(*resolved, pkgInfo.Name) { if !slices.Contains(*resolved, pkgInfo.Name) {

View File

@ -8,6 +8,7 @@ import (
"net/url" "net/url"
"os" "os"
"path" "path"
"sort"
"strings" "strings"
) )
@ -19,8 +20,9 @@ type Repository struct {
} }
type RepositoryEntry struct { type RepositoryEntry struct {
Info *PackageInfo `yaml:"info"` Info *PackageInfo `yaml:"info"`
Download string `yaml:"download"` Download string `yaml:"download"`
IsVirtualPackage bool `yaml:"-"`
} }
func (repo *Repository) ContainsPackage(pkg string) bool { func (repo *Repository) ContainsPackage(pkg string) bool {
@ -39,6 +41,8 @@ func (repo *Repository) ReadLocalDatabase() error {
return err return err
} }
virtualPackages := make(map[string][]string)
data := string(bytes) data := string(bytes)
for _, b := range strings.Split(data, "---") { for _, b := range strings.Split(data, "---") {
entry := RepositoryEntry{ entry := RepositoryEntry{
@ -58,14 +62,32 @@ func (repo *Repository) ReadLocalDatabase() error {
Conflicts: make([]string, 0), Conflicts: make([]string, 0),
Provides: make([]string, 0), Provides: make([]string, 0),
}, },
Download: "", Download: "",
IsVirtualPackage: false,
} }
err := yaml.Unmarshal([]byte(b), &entry) err := yaml.Unmarshal([]byte(b), &entry)
if err != nil { if err != nil {
return err return err
} }
for _, p := range entry.Info.Provides {
virtualPackages[p] = append(virtualPackages[p], entry.Info.Name)
}
repo.Entries[entry.Info.Name] = &entry repo.Entries[entry.Info.Name] = &entry
} }
for key, value := range virtualPackages {
if _, ok := repo.Entries[key]; ok {
continue
}
sort.Strings(value)
entry := RepositoryEntry{
Info: repo.Entries[value[0]].Info,
Download: repo.Entries[value[0]].Download,
IsVirtualPackage: true,
}
repo.Entries[key] = &entry
}
return nil return nil
} }