mirror of
https://github.com/EnumeratedDev/bpm.git
synced 2026-09-16 02:26:12 +00:00
Moved package fetching, installation and removal functionality to operations.go
This commit is contained in:
+12
-1
@@ -49,7 +49,18 @@ func stringSliceRemove(s []string, r string) []string {
|
||||
return s
|
||||
}
|
||||
|
||||
func BytesToHumanReadable(b uint64) string {
|
||||
func UnsignedBytesToHumanReadable(b uint64) string {
|
||||
bf := float64(b)
|
||||
for _, unit := range []string{"", "Ki", "Mi", "Gi", "Ti", "Pi", "Ei", "Zi"} {
|
||||
if math.Abs(bf) < 1024.0 {
|
||||
return fmt.Sprintf("%3.1f%sB", bf, unit)
|
||||
}
|
||||
bf /= 1024.0
|
||||
}
|
||||
return fmt.Sprintf("%.1fYiB", bf)
|
||||
}
|
||||
|
||||
func BytesToHumanReadable(b int64) string {
|
||||
bf := float64(b)
|
||||
for _, unit := range []string{"", "Ki", "Mi", "Gi", "Ti", "Pi", "Ei", "Zi"} {
|
||||
if math.Abs(bf) < 1024.0 {
|
||||
|
||||
+194
-7
@@ -1,7 +1,18 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"slices"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type BPMOperation struct {
|
||||
Actions []OperationAction
|
||||
Actions []OperationAction
|
||||
UnresolvedDepends []string
|
||||
RootDir string
|
||||
}
|
||||
|
||||
func (operation *BPMOperation) ActionsContainPackage(pkg string) bool {
|
||||
@@ -47,23 +58,199 @@ func (operation *BPMOperation) GetTotalInstalledSize() uint64 {
|
||||
return ret
|
||||
}
|
||||
|
||||
func (operation *BPMOperation) GetFinalActionSize(rootDir string) uint64 {
|
||||
var ret uint64 = 0
|
||||
func (operation *BPMOperation) GetFinalActionSize(rootDir string) int64 {
|
||||
var ret int64 = 0
|
||||
for _, action := range operation.Actions {
|
||||
if action.GetActionType() == "install" {
|
||||
ret += action.(*InstallPackageAction).BpmPackage.GetInstalledSize()
|
||||
ret += int64(action.(*InstallPackageAction).BpmPackage.GetInstalledSize())
|
||||
if IsPackageInstalled(action.(*InstallPackageAction).BpmPackage.PkgInfo.Name, rootDir) {
|
||||
ret -= GetPackage(action.(*InstallPackageAction).BpmPackage.PkgInfo.Name, rootDir).GetInstalledSize()
|
||||
ret -= int64(GetPackage(action.(*InstallPackageAction).BpmPackage.PkgInfo.Name, rootDir).GetInstalledSize())
|
||||
}
|
||||
} else if action.GetActionType() == "fetch" {
|
||||
ret += action.(*FetchPackageAction).RepositoryEntry.InstalledSize
|
||||
ret += int64(action.(*FetchPackageAction).RepositoryEntry.InstalledSize)
|
||||
} else if action.GetActionType() == "remove" {
|
||||
ret -= action.(*RemovePackageAction).BpmPackage.GetInstalledSize()
|
||||
ret -= int64(action.(*RemovePackageAction).BpmPackage.GetInstalledSize())
|
||||
}
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func (operation *BPMOperation) ResolveDependencies(reinstallDependencies, installOptionalDependencies, verbose bool) error {
|
||||
pos := 0
|
||||
for _, value := range slices.Clone(operation.Actions) {
|
||||
var pkgInfo *PackageInfo
|
||||
if value.GetActionType() == "install" {
|
||||
action := value.(*InstallPackageAction)
|
||||
pkgInfo = action.BpmPackage.PkgInfo
|
||||
} else if value.GetActionType() == "fetch" {
|
||||
action := value.(*FetchPackageAction)
|
||||
pkgInfo = action.RepositoryEntry.Info
|
||||
} else {
|
||||
pos++
|
||||
continue
|
||||
}
|
||||
|
||||
resolved, unresolved := pkgInfo.ResolveDependencies(&[]string{}, &[]string{}, pkgInfo.Type == "source", installOptionalDependencies, !reinstallDependencies, verbose, operation.RootDir)
|
||||
|
||||
operation.UnresolvedDepends = append(operation.UnresolvedDepends, unresolved...)
|
||||
|
||||
for _, depend := range resolved {
|
||||
if !operation.ActionsContainPackage(depend) && depend != pkgInfo.Name {
|
||||
if !reinstallDependencies && IsPackageInstalled(depend, operation.RootDir) {
|
||||
continue
|
||||
}
|
||||
entry, _, err := GetRepositoryEntry(depend)
|
||||
if err != nil {
|
||||
return errors.New("could not get repository entry for package (" + depend + ")")
|
||||
}
|
||||
operation.InsertActionAt(pos, &FetchPackageAction{
|
||||
IsDependency: true,
|
||||
RepositoryEntry: entry,
|
||||
})
|
||||
pos++
|
||||
}
|
||||
}
|
||||
pos++
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (operation *BPMOperation) ShowOperationSummary() {
|
||||
if len(operation.Actions) == 0 {
|
||||
fmt.Println("All packages are up to date!")
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
for _, value := range operation.Actions {
|
||||
var pkgInfo *PackageInfo
|
||||
if value.GetActionType() == "install" {
|
||||
pkgInfo = value.(*InstallPackageAction).BpmPackage.PkgInfo
|
||||
} else if value.GetActionType() == "fetch" {
|
||||
pkgInfo = value.(*FetchPackageAction).RepositoryEntry.Info
|
||||
} else {
|
||||
pkgInfo = value.(*RemovePackageAction).BpmPackage.PkgInfo
|
||||
fmt.Printf("%s: %s (Remove)\n", pkgInfo.Name, pkgInfo.GetFullVersion())
|
||||
continue
|
||||
}
|
||||
|
||||
installedInfo := GetPackageInfo(pkgInfo.Name, operation.RootDir)
|
||||
sourceInfo := ""
|
||||
if pkgInfo.Type == "source" {
|
||||
if operation.RootDir != "/" {
|
||||
log.Fatalf("cannot compile and install source packages to a different root directory")
|
||||
}
|
||||
sourceInfo = "(From Source)"
|
||||
}
|
||||
|
||||
if installedInfo == nil {
|
||||
fmt.Printf("%s: %s (Install) %s\n", pkgInfo.Name, pkgInfo.GetFullVersion(), sourceInfo)
|
||||
} else {
|
||||
comparison := 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 operation.RootDir != "/" {
|
||||
fmt.Println("Warning: Operating in " + operation.RootDir)
|
||||
}
|
||||
if operation.GetTotalDownloadSize() > 0 {
|
||||
fmt.Printf("%s will be downloaded to complete this operation\n", UnsignedBytesToHumanReadable(operation.GetTotalDownloadSize()))
|
||||
}
|
||||
if operation.GetFinalActionSize(operation.RootDir) > 0 {
|
||||
fmt.Printf("A total of %s will be installed after the operation finishes\n", BytesToHumanReadable(operation.GetFinalActionSize(operation.RootDir)))
|
||||
} else if operation.GetFinalActionSize(operation.RootDir) < 0 {
|
||||
fmt.Printf("A total of %s will be freed after the operation finishes\n", strings.TrimPrefix(BytesToHumanReadable(operation.GetFinalActionSize(operation.RootDir)), "-"))
|
||||
}
|
||||
}
|
||||
|
||||
func (operation *BPMOperation) Execute(verbose, force bool) error {
|
||||
// Fetch packages from repositories
|
||||
if slices.ContainsFunc(operation.Actions, func(action OperationAction) bool {
|
||||
return action.GetActionType() == "fetch"
|
||||
}) {
|
||||
fmt.Println("Fetching packages from available repositories...")
|
||||
for i, action := range operation.Actions {
|
||||
if action.GetActionType() != "fetch" {
|
||||
continue
|
||||
}
|
||||
entry := action.(*FetchPackageAction).RepositoryEntry
|
||||
fetchedPackage, err := entry.Repository.FetchPackage(entry.Info.Name)
|
||||
if err != nil {
|
||||
return errors.New(fmt.Sprintf("could not fetch package (%s): %s\n", entry.Info.Name, err))
|
||||
}
|
||||
bpmpkg, err := ReadPackage(fetchedPackage)
|
||||
if err != nil {
|
||||
return errors.New(fmt.Sprintf("could not fetch package (%s): %s\n", entry.Info.Name, err))
|
||||
}
|
||||
fmt.Printf("Package (%s) was successfully fetched!\n", bpmpkg.PkgInfo.Name)
|
||||
operation.Actions[i] = &InstallPackageAction{
|
||||
File: fetchedPackage,
|
||||
IsDependency: action.(*FetchPackageAction).IsDependency,
|
||||
BpmPackage: bpmpkg,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Determine words to be used for the following message
|
||||
words := make([]string, 0)
|
||||
if slices.ContainsFunc(operation.Actions, func(action OperationAction) bool {
|
||||
return action.GetActionType() == "install"
|
||||
}) {
|
||||
words = append(words, "Installing")
|
||||
}
|
||||
|
||||
if slices.ContainsFunc(operation.Actions, func(action OperationAction) bool {
|
||||
return action.GetActionType() == "remove"
|
||||
}) {
|
||||
words = append(words, "Removing")
|
||||
}
|
||||
|
||||
if len(words) == 0 {
|
||||
return nil
|
||||
}
|
||||
fmt.Printf("%s packages...\n", strings.Join(words, "/"))
|
||||
|
||||
// Installing/Removing packages from system
|
||||
for _, action := range operation.Actions {
|
||||
if action.GetActionType() == "remove" {
|
||||
pkgInfo := action.(*RemovePackageAction).BpmPackage.PkgInfo
|
||||
err := RemovePackage(pkgInfo.Name, verbose, operation.RootDir)
|
||||
if err != nil {
|
||||
return errors.New(fmt.Sprintf("could not remove package (%s): %s\n", pkgInfo.Name, err))
|
||||
}
|
||||
} else if action.GetActionType() == "install" {
|
||||
value := action.(*InstallPackageAction)
|
||||
bpmpkg := value.BpmPackage
|
||||
var err error
|
||||
if value.IsDependency {
|
||||
err = InstallPackage(value.File, operation.RootDir, verbose, true, false, false, false)
|
||||
} else {
|
||||
err = InstallPackage(value.File, operation.RootDir, verbose, force, false, false, false)
|
||||
}
|
||||
if err != nil {
|
||||
return errors.New(fmt.Sprintf("could not install package (%s): %s\n", bpmpkg.PkgInfo.Name, err))
|
||||
}
|
||||
fmt.Printf("Package (%s) was successfully installed\n", bpmpkg.PkgInfo.Name)
|
||||
if value.IsDependency {
|
||||
err := SetInstallationReason(bpmpkg.PkgInfo.Name, Dependency, operation.RootDir)
|
||||
if err != nil {
|
||||
return errors.New(fmt.Sprintf("could not set installation reason for package (%s): %s\n", value.BpmPackage.PkgInfo.Name, err))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
fmt.Println("Operation complete!")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type OperationAction interface {
|
||||
GetActionType() string
|
||||
}
|
||||
|
||||
+7
-10
@@ -238,31 +238,31 @@ func ReadPackageScripts(filename string) (map[string]string, error) {
|
||||
return nil, err
|
||||
}
|
||||
if header.Name == "pre_install.sh" {
|
||||
bs, _ := io.ReadAll(tr)
|
||||
bs, err := io.ReadAll(tr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ret[header.Name] = string(bs)
|
||||
} else if header.Name == "post_install.sh" {
|
||||
bs, _ := io.ReadAll(tr)
|
||||
bs, err := io.ReadAll(tr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ret[header.Name] = string(bs)
|
||||
} else if header.Name == "pre_update.sh" {
|
||||
bs, _ := io.ReadAll(tr)
|
||||
bs, err := io.ReadAll(tr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ret[header.Name] = string(bs)
|
||||
} else if header.Name == "post_update.sh" {
|
||||
bs, _ := io.ReadAll(tr)
|
||||
bs, err := io.ReadAll(tr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ret[header.Name] = string(bs)
|
||||
} else if header.Name == "post_remove.sh" {
|
||||
bs, _ := io.ReadAll(tr)
|
||||
bs, err := io.ReadAll(tr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -744,9 +744,6 @@ func compilePackage(bpmpkg *BPMPackage, filename, rootDir string, verbose, binar
|
||||
if _, err := os.Stat(path.Join(temp, "source.sh")); os.IsNotExist(err) {
|
||||
return errors.New("source.sh file could not be found in the temporary build directory"), nil
|
||||
}
|
||||
if err != nil {
|
||||
return err, nil
|
||||
}
|
||||
fmt.Println("Running source.sh file...")
|
||||
if !IsPackageInstalled(bpmpkg.PkgInfo.Name, rootDir) {
|
||||
err = ExecutePackageScripts(filename, rootDir, Install, false)
|
||||
@@ -1301,7 +1298,7 @@ func (pkgInfo *PackageInfo) CheckConflicts(rootDir string) []string {
|
||||
return ret
|
||||
}
|
||||
|
||||
func (pkgInfo *PackageInfo) ResolveAll(resolved, unresolved *[]string, checkMake, checkOptional, ignoreInstalled, verbose bool, rootDir string) ([]string, []string) {
|
||||
func (pkgInfo *PackageInfo) ResolveDependencies(resolved, unresolved *[]string, checkMake, checkOptional, ignoreInstalled, verbose bool, rootDir string) ([]string, []string) {
|
||||
*unresolved = append(*unresolved, pkgInfo.Name)
|
||||
for _, depend := range pkgInfo.GetAllDependencies(checkMake, checkOptional) {
|
||||
depend = strings.TrimSpace(depend)
|
||||
@@ -1325,7 +1322,7 @@ func (pkgInfo *PackageInfo) ResolveAll(resolved, unresolved *[]string, checkMake
|
||||
}
|
||||
continue
|
||||
}
|
||||
entry.Info.ResolveAll(resolved, unresolved, checkMake, checkOptional, ignoreInstalled, verbose, rootDir)
|
||||
entry.Info.ResolveDependencies(resolved, unresolved, checkMake, checkOptional, ignoreInstalled, verbose, rootDir)
|
||||
}
|
||||
}
|
||||
if !slices.Contains(*resolved, pkgInfo.Name) {
|
||||
|
||||
Reference in New Issue
Block a user