mirror of
https://github.com/EnumeratedDev/bpm.git
synced 2026-09-24 06:26:12 +00:00
Compare commits
18
Commits
2072e3856f
...
ad89650dc4
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ad89650dc4
|
||
|
|
3a7adb27ab
|
||
|
|
f6aa01339e
|
||
|
|
a29de2e52d
|
||
|
|
619335bbe6
|
||
|
|
8579c688d7
|
||
|
|
48cec35f0c
|
||
|
|
e19d64bf04
|
||
|
|
ee80640153
|
||
|
|
e4d94e378f
|
||
|
|
b37360ed82
|
||
|
|
ba0d288e45
|
||
|
|
c1fa9d9474
|
||
|
|
0742c81f2f
|
||
|
|
dd20574470
|
||
|
|
b3dc6e3e34
|
||
|
|
0a06808303
|
||
|
|
9f8a20c671
|
+129
-20
@@ -13,6 +13,7 @@ import (
|
|||||||
"slices"
|
"slices"
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/EnumeratedDev/bpm/src/bpmlib"
|
"github.com/EnumeratedDev/bpm/src/bpmlib"
|
||||||
|
|
||||||
@@ -54,7 +55,7 @@ func main() {
|
|||||||
currentFlagSet = flag.NewFlagSet("query", flag.ExitOnError)
|
currentFlagSet = flag.NewFlagSet("query", flag.ExitOnError)
|
||||||
currentFlagSet.StringP("root", "R", "/", "Operate on specified root directory")
|
currentFlagSet.StringP("root", "R", "/", "Operate on specified root directory")
|
||||||
currentFlagSet.BoolP("database", "d", false, "Show package information from remote databases")
|
currentFlagSet.BoolP("database", "d", false, "Show package information from remote databases")
|
||||||
currentFlagSet.BoolP("human-readable", "h", false, "Show package installed size in a human readable format")
|
currentFlagSet.BoolP("show-bytes", "b", false, "Show package installed size in bytes")
|
||||||
setupFlagsAndHelp(currentFlagSet, fmt.Sprintf("bpm %s <options>", subcommand), "Show information on the specified packages", os.Args[2:])
|
setupFlagsAndHelp(currentFlagSet, fmt.Sprintf("bpm %s <options>", subcommand), "Show information on the specified packages", os.Args[2:])
|
||||||
|
|
||||||
showPackageInfo()
|
showPackageInfo()
|
||||||
@@ -70,7 +71,7 @@ func main() {
|
|||||||
currentFlagSet.Bool("make-depends", false, "Show packages installed as make dependencies")
|
currentFlagSet.Bool("make-depends", false, "Show packages installed as make dependencies")
|
||||||
currentFlagSet.String("sort", "", "Sort listed packages by 'name' or 'size")
|
currentFlagSet.String("sort", "", "Sort listed packages by 'name' or 'size")
|
||||||
currentFlagSet.Bool("reverse", false, "Reverse the order in which packages are listed")
|
currentFlagSet.Bool("reverse", false, "Reverse the order in which packages are listed")
|
||||||
currentFlagSet.BoolP("human-readable", "h", false, "Show package installed size in a human readable format")
|
currentFlagSet.BoolP("show-bytes", "b", false, "Show package installed size in bytes")
|
||||||
setupFlagsAndHelp(currentFlagSet, fmt.Sprintf("bpm %s <options>", subcommand), "List packages", os.Args[2:])
|
setupFlagsAndHelp(currentFlagSet, fmt.Sprintf("bpm %s <options>", subcommand), "List packages", os.Args[2:])
|
||||||
|
|
||||||
showPackageList()
|
showPackageList()
|
||||||
@@ -93,6 +94,7 @@ func main() {
|
|||||||
currentFlagSet.BoolP("reinstall", "r", false, "Reinstall the specified packages")
|
currentFlagSet.BoolP("reinstall", "r", false, "Reinstall the specified packages")
|
||||||
currentFlagSet.BoolP("reinstall-all", "a", false, "Reinstall the specified packages and their dependencies")
|
currentFlagSet.BoolP("reinstall-all", "a", false, "Reinstall the specified packages and their dependencies")
|
||||||
currentFlagSet.IntP("jobs", "j", bpmlib.CompilationBPMConfig.CompilationJobs, "Set the amount of concurrent processes to use for source package compilation")
|
currentFlagSet.IntP("jobs", "j", bpmlib.CompilationBPMConfig.CompilationJobs, "Set the amount of concurrent processes to use for source package compilation")
|
||||||
|
currentFlagSet.BoolP("skip-checks", "s", false, "Skip the check function in source.sh scripts")
|
||||||
setupFlagsAndHelp(currentFlagSet, fmt.Sprintf("bpm %s <options>", subcommand), "Install the specified packages", os.Args[2:])
|
setupFlagsAndHelp(currentFlagSet, fmt.Sprintf("bpm %s <options>", subcommand), "Install the specified packages", os.Args[2:])
|
||||||
|
|
||||||
installPackages()
|
installPackages()
|
||||||
@@ -142,6 +144,7 @@ func main() {
|
|||||||
currentFlagSet.BoolP("no-sync", "n", false, "Do not sync databases")
|
currentFlagSet.BoolP("no-sync", "n", false, "Do not sync databases")
|
||||||
currentFlagSet.Bool("allow-downgrades", false, "Allow package downgrades")
|
currentFlagSet.Bool("allow-downgrades", false, "Allow package downgrades")
|
||||||
currentFlagSet.BoolP("optional", "o", false, "Install all optional dependencies")
|
currentFlagSet.BoolP("optional", "o", false, "Install all optional dependencies")
|
||||||
|
currentFlagSet.BoolP("skip-checks", "s", false, "Skip the check function in source.sh scripts")
|
||||||
currentFlagSet.IntP("jobs", "j", bpmlib.CompilationBPMConfig.CompilationJobs, "Set the amount of concurrent processes to use for source package compilation")
|
currentFlagSet.IntP("jobs", "j", bpmlib.CompilationBPMConfig.CompilationJobs, "Set the amount of concurrent processes to use for source package compilation")
|
||||||
setupFlagsAndHelp(currentFlagSet, fmt.Sprintf("bpm %s <options>", subcommand), "Update installed packages", os.Args[2:])
|
setupFlagsAndHelp(currentFlagSet, fmt.Sprintf("bpm %s <options>", subcommand), "Update installed packages", os.Args[2:])
|
||||||
|
|
||||||
@@ -174,6 +177,18 @@ func main() {
|
|||||||
setupFlagsAndHelp(currentFlagSet, fmt.Sprintf("bpm %s <options>", subcommand), "Compare two version numbers", os.Args[2:])
|
setupFlagsAndHelp(currentFlagSet, fmt.Sprintf("bpm %s <options>", subcommand), "Compare two version numbers", os.Args[2:])
|
||||||
|
|
||||||
compareVersions()
|
compareVersions()
|
||||||
|
case "upgrade-persistent-data":
|
||||||
|
currentFlagSet = flag.NewFlagSet("upgrade-persistent-data", flag.ExitOnError)
|
||||||
|
currentFlagSet.StringP("root", "R", "/", "Operate on specified root directory")
|
||||||
|
setupFlagsAndHelp(currentFlagSet, fmt.Sprintf("bpm %s <options>", subcommand), "Upgrade BPM's persistent data directory contents", os.Args[2:])
|
||||||
|
|
||||||
|
rootDir, _ := currentFlagSet.GetString("root")
|
||||||
|
err = bpmlib.UpgradePersistentData(rootDir)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("Error: could not upgrade persistent data directory: %s", err)
|
||||||
|
exitCode = 1
|
||||||
|
return
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
printUsage()
|
printUsage()
|
||||||
exitCode = 1
|
exitCode = 1
|
||||||
@@ -188,7 +203,15 @@ func showPackageInfo() {
|
|||||||
// Get flags
|
// Get flags
|
||||||
rootDir, _ := currentFlagSet.GetString("root")
|
rootDir, _ := currentFlagSet.GetString("root")
|
||||||
showDatabaseInfo, _ := currentFlagSet.GetBool("database")
|
showDatabaseInfo, _ := currentFlagSet.GetBool("database")
|
||||||
showHumanReadableSize, _ := currentFlagSet.GetBool("human-readable")
|
showBytes, _ := currentFlagSet.GetBool("show-bytes")
|
||||||
|
|
||||||
|
// Initialize installed packages map
|
||||||
|
err := bpmlib.InitializeLocalPackageInformation(rootDir)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("Error: %s", err)
|
||||||
|
exitCode = 1
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// Get packages
|
// Get packages
|
||||||
packages := currentFlagSet.Args()
|
packages := currentFlagSet.Args()
|
||||||
@@ -198,7 +221,7 @@ func showPackageInfo() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Read local databases
|
// Read local databases
|
||||||
err := bpmlib.ReadLocalDatabaseFiles()
|
err = bpmlib.ReadLocalDatabaseFiles()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Error: could not read local databases: %s", err)
|
log.Printf("Error: could not read local databases: %s", err)
|
||||||
exitCode = 1
|
exitCode = 1
|
||||||
@@ -211,7 +234,9 @@ func showPackageInfo() {
|
|||||||
var entry *bpmlib.BPMDatabaseEntry
|
var entry *bpmlib.BPMDatabaseEntry
|
||||||
entry, _, err = bpmlib.GetDatabaseEntry(pkg)
|
entry, _, err = bpmlib.GetDatabaseEntry(pkg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if entry = bpmlib.ResolveVirtualPackage(pkg); entry == nil {
|
if providers := bpmlib.GetDatabaseVirtualPackageEntry(pkg); len(providers) > 0 {
|
||||||
|
entry = providers[0]
|
||||||
|
} else {
|
||||||
log.Printf("Error: could not find package (%s) in any database\n", pkg)
|
log.Printf("Error: could not find package (%s) in any database\n", pkg)
|
||||||
exitCode = 1
|
exitCode = 1
|
||||||
return
|
return
|
||||||
@@ -221,7 +246,7 @@ func showPackageInfo() {
|
|||||||
if n != 0 {
|
if n != 0 {
|
||||||
fmt.Println()
|
fmt.Println()
|
||||||
}
|
}
|
||||||
fmt.Println(entry.CreateReadableInfo(rootDir, showHumanReadableSize))
|
fmt.Println(entry.CreateReadableInfo(rootDir, showBytes))
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -237,8 +262,8 @@ func showPackageInfo() {
|
|||||||
}
|
}
|
||||||
isFile = true
|
isFile = true
|
||||||
} else {
|
} else {
|
||||||
if isVirtual, p := bpmlib.IsVirtualPackage(pkg, rootDir); isVirtual {
|
if providers := bpmlib.GetVirtualPackageInfo(pkg, rootDir); len(providers) > 0 {
|
||||||
bpmpkg = bpmlib.GetPackage(p, rootDir)
|
bpmpkg = bpmlib.GetPackage(providers[0].Name, rootDir)
|
||||||
} else {
|
} else {
|
||||||
bpmpkg = bpmlib.GetPackage(pkg, rootDir)
|
bpmpkg = bpmlib.GetPackage(pkg, rootDir)
|
||||||
}
|
}
|
||||||
@@ -262,12 +287,20 @@ func showPackageInfo() {
|
|||||||
}
|
}
|
||||||
fmt.Println(bpmpkg.PkgInfo.CreateReadableInfo(rootDir))
|
fmt.Println(bpmpkg.PkgInfo.CreateReadableInfo(rootDir))
|
||||||
if bpmpkg.PkgInfo.Type == "binary" {
|
if bpmpkg.PkgInfo.Type == "binary" {
|
||||||
if !showHumanReadableSize {
|
if showBytes {
|
||||||
fmt.Printf("Installed size: %d\n", bpmpkg.GetInstalledSize())
|
fmt.Printf("Installed size: %d\n", bpmpkg.GetInstalledSize())
|
||||||
} else {
|
} else {
|
||||||
fmt.Printf("Installed size: %s\n", bpmlib.BytesToHumanReadable(bpmpkg.GetInstalledSize()))
|
fmt.Printf("Installed size: %s\n", bpmlib.BytesToHumanReadable(bpmpkg.GetInstalledSize()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if bpmlib.IsPackageInstalled(bpmpkg.PkgInfo.Name, rootDir) {
|
||||||
|
format := "02/01/2006 15:04"
|
||||||
|
installedOnDate := time.Unix(bpmpkg.LocalInfo.InstalledOn, 0).Format(format)
|
||||||
|
lastUpdatedOn := time.Unix(bpmpkg.LocalInfo.LastUpdatedOn, 0).Format(format)
|
||||||
|
fmt.Printf("Installed on: %s\n", installedOnDate)
|
||||||
|
fmt.Printf("Last updated on: %s\n", lastUpdatedOn)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -282,7 +315,7 @@ func showPackageList() {
|
|||||||
showMakeDepends, _ := currentFlagSet.GetBool("make-depends")
|
showMakeDepends, _ := currentFlagSet.GetBool("make-depends")
|
||||||
sortPackages, _ := currentFlagSet.GetString("sort")
|
sortPackages, _ := currentFlagSet.GetString("sort")
|
||||||
reversePackages, _ := currentFlagSet.GetBool("reverse")
|
reversePackages, _ := currentFlagSet.GetBool("reverse")
|
||||||
showHumanReadableSize, _ := currentFlagSet.GetBool("human-readable")
|
showBytes, _ := currentFlagSet.GetBool("show-bytes")
|
||||||
|
|
||||||
if !isFlagSet(currentFlagSet, "manual") && !isFlagSet(currentFlagSet, "depends") && !isFlagSet(currentFlagSet, "make-depends") {
|
if !isFlagSet(currentFlagSet, "manual") && !isFlagSet(currentFlagSet, "depends") && !isFlagSet(currentFlagSet, "make-depends") {
|
||||||
showManual = true
|
showManual = true
|
||||||
@@ -290,8 +323,16 @@ func showPackageList() {
|
|||||||
showMakeDepends = true
|
showMakeDepends = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Initialize installed packages map
|
||||||
|
err := bpmlib.InitializeLocalPackageInformation(rootDir)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("Error: %s", err)
|
||||||
|
exitCode = 1
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// Read local databases
|
// Read local databases
|
||||||
err := bpmlib.ReadLocalDatabaseFiles()
|
err = bpmlib.ReadLocalDatabaseFiles()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Error: could not read local databases: %s", err)
|
log.Printf("Error: could not read local databases: %s", err)
|
||||||
exitCode = 1
|
exitCode = 1
|
||||||
@@ -329,6 +370,15 @@ func showPackageList() {
|
|||||||
|
|
||||||
switch sortPackages {
|
switch sortPackages {
|
||||||
case "", "name":
|
case "", "name":
|
||||||
|
slices.SortFunc(installedPackages, func(a, b struct {
|
||||||
|
pkgInfo bpmlib.PackageInfo
|
||||||
|
installedSize int64
|
||||||
|
}) int {
|
||||||
|
return strings.Compare(a.pkgInfo.Name, b.pkgInfo.Name)
|
||||||
|
})
|
||||||
|
slices.SortFunc(databaseEntries, func(a, b *bpmlib.BPMDatabaseEntry) int {
|
||||||
|
return strings.Compare(a.Info.Name, b.Info.Name)
|
||||||
|
})
|
||||||
case "size":
|
case "size":
|
||||||
slices.SortFunc(installedPackages, func(a, b struct {
|
slices.SortFunc(installedPackages, func(a, b struct {
|
||||||
pkgInfo bpmlib.PackageInfo
|
pkgInfo bpmlib.PackageInfo
|
||||||
@@ -363,7 +413,7 @@ func showPackageList() {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for _, pkg := range installedPackages {
|
for _, pkg := range installedPackages {
|
||||||
installationReason := bpmlib.GetInstallationReason(pkg.pkgInfo.Name, rootDir)
|
installationReason := bpmlib.GetPackage(pkg.pkgInfo.Name, rootDir).LocalInfo.GetInstallationReason()
|
||||||
if installationReason == bpmlib.InstallationReasonManual && !showManual {
|
if installationReason == bpmlib.InstallationReasonManual && !showManual {
|
||||||
continue
|
continue
|
||||||
} else if installationReason == bpmlib.InstallationReasonDependency && !showDepends {
|
} else if installationReason == bpmlib.InstallationReasonDependency && !showDepends {
|
||||||
@@ -387,7 +437,7 @@ func showPackageList() {
|
|||||||
if n != 0 {
|
if n != 0 {
|
||||||
fmt.Println()
|
fmt.Println()
|
||||||
}
|
}
|
||||||
fmt.Println(entry.CreateReadableInfo(rootDir, showHumanReadableSize))
|
fmt.Println(entry.CreateReadableInfo(rootDir, showBytes))
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if len(installedPackages) == 0 {
|
if len(installedPackages) == 0 {
|
||||||
@@ -395,7 +445,7 @@ func showPackageList() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
for n, pkg := range installedPackages {
|
for n, pkg := range installedPackages {
|
||||||
installationReason := bpmlib.GetInstallationReason(pkg.pkgInfo.Name, rootDir)
|
installationReason := bpmlib.GetPackage(pkg.pkgInfo.Name, rootDir).LocalInfo.GetInstallationReason()
|
||||||
if installationReason == bpmlib.InstallationReasonManual && !showManual {
|
if installationReason == bpmlib.InstallationReasonManual && !showManual {
|
||||||
continue
|
continue
|
||||||
} else if installationReason == bpmlib.InstallationReasonDependency && !showDepends {
|
} else if installationReason == bpmlib.InstallationReasonDependency && !showDepends {
|
||||||
@@ -412,12 +462,20 @@ func showPackageList() {
|
|||||||
|
|
||||||
fmt.Println(pkg.pkgInfo.CreateReadableInfo(rootDir))
|
fmt.Println(pkg.pkgInfo.CreateReadableInfo(rootDir))
|
||||||
if pkg.pkgInfo.Type == "binary" {
|
if pkg.pkgInfo.Type == "binary" {
|
||||||
if !showHumanReadableSize {
|
if showBytes {
|
||||||
fmt.Printf("Installed size: %d\n", pkg.installedSize)
|
fmt.Printf("Installed size: %d\n", pkg.installedSize)
|
||||||
} else {
|
} else {
|
||||||
fmt.Printf("Installed size: %s\n", bpmlib.BytesToHumanReadable(pkg.installedSize))
|
fmt.Printf("Installed size: %s\n", bpmlib.BytesToHumanReadable(pkg.installedSize))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
localInfo := bpmlib.GetPackage(pkg.pkgInfo.Name, rootDir).LocalInfo
|
||||||
|
format := "02/01/2006 15:04"
|
||||||
|
installedOnDate := time.Unix(localInfo.InstalledOn, 0).Format(format)
|
||||||
|
lastUpdatedOn := time.Unix(localInfo.LastUpdatedOn, 0).Format(format)
|
||||||
|
fmt.Printf("Installed on: %s\n", installedOnDate)
|
||||||
|
fmt.Printf("Last updated on: %s\n", lastUpdatedOn)
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -489,6 +547,7 @@ func installPackages() {
|
|||||||
installationReason, _ := currentFlagSet.GetString("installation-reason")
|
installationReason, _ := currentFlagSet.GetString("installation-reason")
|
||||||
reinstall, _ := currentFlagSet.GetBool("reinstall")
|
reinstall, _ := currentFlagSet.GetBool("reinstall")
|
||||||
reinstallAll, _ := currentFlagSet.GetBool("reinstall-all")
|
reinstallAll, _ := currentFlagSet.GetBool("reinstall-all")
|
||||||
|
skipChecks, _ := currentFlagSet.GetBool("skip-checks")
|
||||||
compilationJobs, _ := currentFlagSet.GetInt("jobs")
|
compilationJobs, _ := currentFlagSet.GetInt("jobs")
|
||||||
|
|
||||||
// Get packages
|
// Get packages
|
||||||
@@ -540,6 +599,14 @@ func installPackages() {
|
|||||||
}
|
}
|
||||||
defer fileLock.Unlock()
|
defer fileLock.Unlock()
|
||||||
|
|
||||||
|
// Initialize installed packages map
|
||||||
|
err = bpmlib.InitializeLocalPackageInformation(rootDir)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("Error: %s", err)
|
||||||
|
exitCode = 1
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// Read local databases
|
// Read local databases
|
||||||
err = bpmlib.ReadLocalDatabaseFiles()
|
err = bpmlib.ReadLocalDatabaseFiles()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -549,7 +616,7 @@ func installPackages() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create installation operation
|
// Create installation operation
|
||||||
operation, err := bpmlib.InstallPackages(rootDir, ir, reinstallMethod, installRuntime, installOptional, force, verbose, packages...)
|
operation, err := bpmlib.InstallPackages(rootDir, ir, reinstallMethod, installRuntime, installOptional, force, !skipChecks, verbose, packages...)
|
||||||
if errors.As(err, &bpmlib.PackageNotFoundErr{}) || errors.As(err, &bpmlib.DependencyNotFoundErr{}) || errors.As(err, &bpmlib.PackageConflictErr{}) {
|
if errors.As(err, &bpmlib.PackageNotFoundErr{}) || errors.As(err, &bpmlib.DependencyNotFoundErr{}) || errors.As(err, &bpmlib.PackageConflictErr{}) {
|
||||||
log.Printf("Error: %s", err)
|
log.Printf("Error: %s", err)
|
||||||
exitCode = 1
|
exitCode = 1
|
||||||
@@ -673,6 +740,14 @@ func removePackages() {
|
|||||||
}
|
}
|
||||||
defer fileLock.Unlock()
|
defer fileLock.Unlock()
|
||||||
|
|
||||||
|
// Initialize installed packages map
|
||||||
|
err = bpmlib.InitializeLocalPackageInformation(rootDir)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("Error: %s", err)
|
||||||
|
exitCode = 1
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// Read local databases
|
// Read local databases
|
||||||
err = bpmlib.ReadLocalDatabaseFiles()
|
err = bpmlib.ReadLocalDatabaseFiles()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -786,6 +861,14 @@ func doCleanup() {
|
|||||||
}
|
}
|
||||||
defer fileLock.Unlock()
|
defer fileLock.Unlock()
|
||||||
|
|
||||||
|
// Initialize installed packages map
|
||||||
|
err = bpmlib.InitializeLocalPackageInformation(rootDir)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("Error: %s", err)
|
||||||
|
exitCode = 1
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
err = bpmlib.CleanupCache(rootDir, cleanupCompilationFiles, cleanupBinaryPackages, cleanupFetchedPackages, verbose)
|
err = bpmlib.CleanupCache(rootDir, cleanupCompilationFiles, cleanupBinaryPackages, cleanupFetchedPackages, verbose)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Error: could not complete cache cleanup: %s", err)
|
log.Printf("Error: could not complete cache cleanup: %s", err)
|
||||||
@@ -907,6 +990,7 @@ func updatePackages() {
|
|||||||
noSync, _ := currentFlagSet.GetBool("no-sync")
|
noSync, _ := currentFlagSet.GetBool("no-sync")
|
||||||
allowDowngrades, _ := currentFlagSet.GetBool("allow-downgrades")
|
allowDowngrades, _ := currentFlagSet.GetBool("allow-downgrades")
|
||||||
installOptional, _ := currentFlagSet.GetBool("optional")
|
installOptional, _ := currentFlagSet.GetBool("optional")
|
||||||
|
skipChecks, _ := currentFlagSet.GetBool("skip-checks")
|
||||||
compilationJobs, _ := currentFlagSet.GetInt("jobs")
|
compilationJobs, _ := currentFlagSet.GetInt("jobs")
|
||||||
|
|
||||||
// Check for required permissions
|
// Check for required permissions
|
||||||
@@ -925,6 +1009,14 @@ func updatePackages() {
|
|||||||
}
|
}
|
||||||
defer fileLock.Unlock()
|
defer fileLock.Unlock()
|
||||||
|
|
||||||
|
// Initialize installed packages map
|
||||||
|
err = bpmlib.InitializeLocalPackageInformation(rootDir)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("Error: %s", err)
|
||||||
|
exitCode = 1
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// Read local databases if no sync
|
// Read local databases if no sync
|
||||||
if noSync {
|
if noSync {
|
||||||
err := bpmlib.ReadLocalDatabaseFiles()
|
err := bpmlib.ReadLocalDatabaseFiles()
|
||||||
@@ -945,7 +1037,7 @@ func updatePackages() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create update operation
|
// Create update operation
|
||||||
operation, err := bpmlib.UpdatePackages(rootDir, !noSync, allowDowngrades, installOptional, force, verbose)
|
operation, err := bpmlib.UpdatePackages(rootDir, !noSync, allowDowngrades, installOptional, force, !skipChecks, verbose)
|
||||||
if errors.As(err, &bpmlib.PackageNotFoundErr{}) || errors.As(err, &bpmlib.DependencyNotFoundErr{}) || errors.As(err, &bpmlib.PackageConflictErr{}) {
|
if errors.As(err, &bpmlib.PackageNotFoundErr{}) || errors.As(err, &bpmlib.DependencyNotFoundErr{}) || errors.As(err, &bpmlib.PackageConflictErr{}) {
|
||||||
log.Printf("Error: %s", err)
|
log.Printf("Error: %s", err)
|
||||||
exitCode = 1
|
exitCode = 1
|
||||||
@@ -1046,6 +1138,14 @@ func getFileOwner() {
|
|||||||
// Get flags
|
// Get flags
|
||||||
rootDir, _ := currentFlagSet.GetString("root")
|
rootDir, _ := currentFlagSet.GetString("root")
|
||||||
|
|
||||||
|
// Initialize installed packages map
|
||||||
|
err := bpmlib.InitializeLocalPackageInformation(rootDir)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("Error: %s", err)
|
||||||
|
exitCode = 1
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// Get files
|
// Get files
|
||||||
files := currentFlagSet.Args()
|
files := currentFlagSet.Args()
|
||||||
if len(files) == 0 {
|
if len(files) == 0 {
|
||||||
@@ -1139,6 +1239,14 @@ func compilePackage() {
|
|||||||
outputFd, _ := currentFlagSet.GetInt("output-fd")
|
outputFd, _ := currentFlagSet.GetInt("output-fd")
|
||||||
compilationJobs, _ := currentFlagSet.GetInt("jobs")
|
compilationJobs, _ := currentFlagSet.GetInt("jobs")
|
||||||
|
|
||||||
|
// Initialize installed packages map
|
||||||
|
err := bpmlib.InitializeLocalPackageInformation(rootDir)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("Error: %s", err)
|
||||||
|
exitCode = 1
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// Get files
|
// Get files
|
||||||
sourcePackages := currentFlagSet.Args()
|
sourcePackages := currentFlagSet.Args()
|
||||||
if len(sourcePackages) == 0 {
|
if len(sourcePackages) == 0 {
|
||||||
@@ -1147,7 +1255,7 @@ func compilePackage() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Read local databases
|
// Read local databases
|
||||||
err := bpmlib.ReadLocalDatabaseFiles()
|
err = bpmlib.ReadLocalDatabaseFiles()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Error: could not read local databases: %s", err)
|
log.Printf("Error: could not read local databases: %s", err)
|
||||||
exitCode = 1
|
exitCode = 1
|
||||||
@@ -1179,7 +1287,7 @@ func compilePackage() {
|
|||||||
|
|
||||||
// Get direct common and make dependencies
|
// Get direct common and make dependencies
|
||||||
totalDepends := make([]string, 0)
|
totalDepends := make([]string, 0)
|
||||||
for _, depend := range bpmpkg.PkgInfo.GetDependencies(true, false, false) {
|
for _, depend := range bpmpkg.PkgInfo.GetDependencies(true, !skipChecks, false, false) {
|
||||||
if !slices.Contains(totalDepends, depend.PkgName) {
|
if !slices.Contains(totalDepends, depend.PkgName) {
|
||||||
totalDepends = append(totalDepends, depend.PkgName)
|
totalDepends = append(totalDepends, depend.PkgName)
|
||||||
}
|
}
|
||||||
@@ -1196,7 +1304,7 @@ func compilePackage() {
|
|||||||
for i := len(unmetDepends) - 1; i >= 0; i-- {
|
for i := len(unmetDepends) - 1; i >= 0; i-- {
|
||||||
if slices.Contains(installedPackages, unmetDepends[i]) {
|
if slices.Contains(installedPackages, unmetDepends[i]) {
|
||||||
unmetDepends = append(unmetDepends[:i], unmetDepends[i+1:]...)
|
unmetDepends = append(unmetDepends[:i], unmetDepends[i+1:]...)
|
||||||
} else if ok, _ := bpmlib.IsVirtualPackage(unmetDepends[i], rootDir); ok {
|
} else if providers := bpmlib.GetVirtualPackageInfo(unmetDepends[i], rootDir); len(providers) > 0 {
|
||||||
unmetDepends = append(unmetDepends[:i], unmetDepends[i+1:]...)
|
unmetDepends = append(unmetDepends[:i], unmetDepends[i+1:]...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1388,6 +1496,7 @@ func printUsage() {
|
|||||||
fmt.Println(" o, owner Show what packages own the specified paths")
|
fmt.Println(" o, owner Show what packages own the specified paths")
|
||||||
fmt.Println(" c, compile Compile source packages and convert them to binary ones")
|
fmt.Println(" c, compile Compile source packages and convert them to binary ones")
|
||||||
fmt.Println(" p, vercmp Compare package version numbers")
|
fmt.Println(" p, vercmp Compare package version numbers")
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func setupFlagsAndHelp(flagset *flag.FlagSet, usage, desc string, args []string) {
|
func setupFlagsAndHelp(flagset *flag.FlagSet, usage, desc string, args []string) {
|
||||||
|
|||||||
@@ -456,6 +456,24 @@ func CompileSourcePackage(archiveFilename, outputDirectory string, compilationJo
|
|||||||
}
|
}
|
||||||
|
|
||||||
func downloadPackageFiles(pkgInfo *PackageInfo, tempDirectory string, verbose bool) error {
|
func downloadPackageFiles(pkgInfo *PackageInfo, tempDirectory string, verbose bool) error {
|
||||||
|
// Get UID and GID to use for compilation
|
||||||
|
var uid, gid int
|
||||||
|
if os.Getuid() == 0 {
|
||||||
|
_uid, err := strconv.ParseInt(rootCompilationUID, 10, 32)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("could not convert UID '%s' to int", rootCompilationUID)
|
||||||
|
}
|
||||||
|
_gid, err := strconv.ParseInt(rootCompilationGID, 10, 32)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("could not convert GID '%s' to int", rootCompilationGID)
|
||||||
|
}
|
||||||
|
uid = int(_uid)
|
||||||
|
gid = int(_gid)
|
||||||
|
} else {
|
||||||
|
uid = os.Getuid()
|
||||||
|
gid = os.Getgid()
|
||||||
|
}
|
||||||
|
|
||||||
for _, download := range pkgInfo.Downloads {
|
for _, download := range pkgInfo.Downloads {
|
||||||
// Replace variables
|
// Replace variables
|
||||||
replaceVars := func(s string) string {
|
replaceVars := func(s string) string {
|
||||||
@@ -534,12 +552,22 @@ func downloadPackageFiles(pkgInfo *PackageInfo, tempDirectory string, verbose bo
|
|||||||
fmt.Println("Skipping checksum checking...")
|
fmt.Println("Skipping checksum checking...")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Change downloaded file ownership
|
||||||
|
err = os.Chown(filepath, uid, gid)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
if !download.NoExtract && (strings.Contains(filepath, ".tar") || strings.HasSuffix(filepath, ".tgz")) {
|
if !download.NoExtract && (strings.Contains(filepath, ".tar") || strings.HasSuffix(filepath, ".tgz")) {
|
||||||
cmd := exec.Command("tar", "xf", filepath, "--strip-components="+strconv.Itoa(download.ExtractStripComponents))
|
cmd := exec.Command("tar", "xf", filepath, "--strip-components="+strconv.Itoa(download.ExtractStripComponents))
|
||||||
if verbose {
|
if verbose {
|
||||||
cmd.Args[1] = "xvf"
|
cmd.Args[1] = "xvf"
|
||||||
}
|
}
|
||||||
cmd.Dir = tempDirectory
|
cmd.Dir = tempDirectory
|
||||||
|
if os.Getuid() == 0 {
|
||||||
|
cmd.SysProcAttr = &syscall.SysProcAttr{}
|
||||||
|
cmd.SysProcAttr.Credential = &syscall.Credential{Uid: uint32(uid), Gid: uint32(gid)}
|
||||||
|
}
|
||||||
if extractTo != "" {
|
if extractTo != "" {
|
||||||
err := os.MkdirAll(extractTo, 0755)
|
err := os.MkdirAll(extractTo, 0755)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -557,6 +585,11 @@ func downloadPackageFiles(pkgInfo *PackageInfo, tempDirectory string, verbose bo
|
|||||||
}
|
}
|
||||||
} else if !download.NoExtract && strings.HasSuffix(filepath, ".zip") {
|
} else if !download.NoExtract && strings.HasSuffix(filepath, ".zip") {
|
||||||
cmd := exec.Command("unzip", filepath)
|
cmd := exec.Command("unzip", filepath)
|
||||||
|
cmd.Dir = tempDirectory
|
||||||
|
if os.Getuid() == 0 {
|
||||||
|
cmd.SysProcAttr = &syscall.SysProcAttr{}
|
||||||
|
cmd.SysProcAttr.Credential = &syscall.Credential{Uid: uint32(uid), Gid: uint32(gid)}
|
||||||
|
}
|
||||||
if extractTo != "" {
|
if extractTo != "" {
|
||||||
err := os.MkdirAll(extractTo, 0755)
|
err := os.MkdirAll(extractTo, 0755)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -601,6 +634,10 @@ func downloadPackageFiles(pkgInfo *PackageInfo, tempDirectory string, verbose bo
|
|||||||
|
|
||||||
cmd := exec.Command("git", "clone", "--depth=1", downloadUrl)
|
cmd := exec.Command("git", "clone", "--depth=1", downloadUrl)
|
||||||
cmd.Dir = tempDirectory
|
cmd.Dir = tempDirectory
|
||||||
|
if os.Getuid() == 0 {
|
||||||
|
cmd.SysProcAttr = &syscall.SysProcAttr{}
|
||||||
|
cmd.SysProcAttr.Credential = &syscall.Credential{Uid: uint32(uid), Gid: uint32(gid)}
|
||||||
|
}
|
||||||
if gitBranch != "" {
|
if gitBranch != "" {
|
||||||
cmd.Args = slices.Insert(cmd.Args, len(cmd.Args)-1, "--branch="+gitBranch)
|
cmd.Args = slices.Insert(cmd.Args, len(cmd.Args)-1, "--branch="+gitBranch)
|
||||||
}
|
}
|
||||||
|
|||||||
+116
-55
@@ -20,7 +20,7 @@ import (
|
|||||||
type BPMDatabase struct {
|
type BPMDatabase struct {
|
||||||
DatabaseVersion int `yaml:"database_version"`
|
DatabaseVersion int `yaml:"database_version"`
|
||||||
Entries map[string]*BPMDatabaseEntry `yaml:"entries"`
|
Entries map[string]*BPMDatabaseEntry `yaml:"entries"`
|
||||||
VirtualPackages map[string][]string
|
VirtualPackages map[string][]*BPMDatabaseEntry
|
||||||
Name string
|
Name string
|
||||||
Source string
|
Source string
|
||||||
}
|
}
|
||||||
@@ -59,7 +59,7 @@ func (db *configDatabase) ReadLocalDatabase() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Initialize struct values
|
// Initialize struct values
|
||||||
database.VirtualPackages = make(map[string][]string)
|
database.VirtualPackages = make(map[string][]*BPMDatabaseEntry)
|
||||||
database.Name = db.Name
|
database.Name = db.Name
|
||||||
database.Source = db.Source
|
database.Source = db.Source
|
||||||
|
|
||||||
@@ -105,13 +105,13 @@ func (db *configDatabase) ReadLocalDatabase() error {
|
|||||||
|
|
||||||
// Add virtual packages to database
|
// Add virtual packages to database
|
||||||
for _, p := range splitPkg.Provides {
|
for _, p := range splitPkg.Provides {
|
||||||
database.VirtualPackages[p] = append(database.VirtualPackages[p], splitPkg.Name)
|
database.VirtualPackages[p] = append(database.VirtualPackages[p], database.Entries[splitPkg.Name])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Add virtual packages to database
|
// Add virtual packages to database
|
||||||
for _, p := range entry.Info.Provides {
|
for _, p := range entry.Info.Provides {
|
||||||
database.VirtualPackages[p] = append(database.VirtualPackages[p], entry.Info.Name)
|
database.VirtualPackages[p] = append(database.VirtualPackages[p], entry)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -231,15 +231,12 @@ func FindReplacement(pkg string) *BPMDatabaseEntry {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func ResolveVirtualPackage(vpkg string) *BPMDatabaseEntry {
|
func GetDatabaseVirtualPackageEntry(vpkg string) (providers []*BPMDatabaseEntry) {
|
||||||
for _, db := range BPMDatabases {
|
for _, db := range BPMDatabases {
|
||||||
if v, ok := db.VirtualPackages[vpkg]; ok {
|
providers = append(providers, db.VirtualPackages[vpkg]...)
|
||||||
slices.Sort(v)
|
|
||||||
return db.Entries[v[0]]
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return providers
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db *BPMDatabase) FetchPackage(pkg string) (string, error) {
|
func (db *BPMDatabase) FetchPackage(pkg string) (string, error) {
|
||||||
@@ -297,7 +294,9 @@ func (entry *BPMDatabaseEntry) GetEntryOptionalDependants() (dependants []string
|
|||||||
dependantsMap := make(map[string][]string)
|
dependantsMap := make(map[string][]string)
|
||||||
for _, db := range BPMDatabases {
|
for _, db := range BPMDatabases {
|
||||||
for _, e := range db.Entries {
|
for _, e := range db.Entries {
|
||||||
if slices.Contains(e.Info.OptionalDepends, entry.Info.Name) {
|
if slices.ContainsFunc(e.Info.OptionalDepends, func(n string) bool {
|
||||||
|
return strings.SplitN(n, ":", 2)[0] == entry.Info.Name
|
||||||
|
}) {
|
||||||
dependantsMap[e.Info.Name] = append(dependantsMap[e.Info.Name], e.Database.Name)
|
dependantsMap[e.Info.Name] = append(dependantsMap[e.Info.Name], e.Database.Name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -322,65 +321,124 @@ func (entry *BPMDatabaseEntry) GetEntryOptionalDependants() (dependants []string
|
|||||||
return dependants
|
return dependants
|
||||||
}
|
}
|
||||||
|
|
||||||
func (entry *BPMDatabaseEntry) CreateReadableInfo(rootDir string, humanReadableSize bool) string {
|
func (entry *BPMDatabaseEntry) CreateReadableInfo(rootDir string, showBytes bool) string {
|
||||||
ret := make([]string, 0)
|
builder := strings.Builder{}
|
||||||
appendArray := func(label string, array []string, sort bool) {
|
builderWriteStringNotEmpty := func(label string, value string) {
|
||||||
|
if value != "" {
|
||||||
|
builder.WriteString(label + ": " + value + "\n")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
builderWriteArray := func(label string, array []string, sort bool) {
|
||||||
if len(array) == 0 {
|
if len(array) == 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Sort array
|
||||||
if sort {
|
if sort {
|
||||||
// Sort array
|
|
||||||
slices.Sort(array)
|
slices.Sort(array)
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = append(ret, fmt.Sprintf("%s: %s", label, strings.Join(array, ", ")))
|
builder.WriteString(label + " (" + strconv.Itoa(len(array)) + "):\n")
|
||||||
|
for _, val := range array {
|
||||||
|
builder.WriteString(" - " + val + "\n")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
builderWriteDependencyArray := func(label string, depends []string) {
|
||||||
|
if len(depends) == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sort array
|
||||||
|
slices.Sort(depends)
|
||||||
|
|
||||||
|
builder.WriteString(label + " (" + strconv.Itoa(len(depends)) + "):\n")
|
||||||
|
for _, val := range depends {
|
||||||
|
builder.WriteString(" - " + val)
|
||||||
|
|
||||||
|
// Show virtual package providers
|
||||||
|
if providers := GetDatabaseVirtualPackageEntry(val); len(providers) > 0 {
|
||||||
|
builder.WriteString(" (")
|
||||||
|
for i, vpkg := range providers {
|
||||||
|
if i == len(providers)-1 {
|
||||||
|
builder.WriteString(vpkg.Info.Name)
|
||||||
|
} else {
|
||||||
|
builder.WriteString(vpkg.Info.Name + ", ")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
builder.WriteString(")")
|
||||||
|
}
|
||||||
|
|
||||||
|
builder.WriteString("\n")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = append(ret, "Name: "+entry.Info.Name)
|
// Main information
|
||||||
ret = append(ret, "Database: "+entry.Database.Name)
|
builder.WriteString("Name: " + entry.Info.Name + "\n")
|
||||||
ret = append(ret, "Description: "+entry.Info.Description)
|
builder.WriteString("Database: " + entry.Database.Name + "\n")
|
||||||
ret = append(ret, "Version: "+entry.Info.GetFullVersion())
|
builder.WriteString("Description: " + entry.Info.Description + "\n")
|
||||||
if entry.Info.Url != "" {
|
builder.WriteString("Version: " + entry.Info.GetFullVersion() + "\n")
|
||||||
ret = append(ret, "URL: "+entry.Info.Url)
|
builderWriteStringNotEmpty("URL", entry.Info.Url)
|
||||||
}
|
builderWriteStringNotEmpty("License", entry.Info.License)
|
||||||
if entry.Info.License != "" {
|
builderWriteArray("Maintainers", entry.Info.Maintainers, false)
|
||||||
ret = append(ret, "License: "+entry.Info.License)
|
builder.WriteString("Architecture: " + entry.Info.Arch + "\n")
|
||||||
}
|
|
||||||
appendArray("Maintainers", entry.Info.Maintainers, false)
|
|
||||||
ret = append(ret, "Architecture: "+entry.Info.Arch)
|
|
||||||
if entry.Info.Type == "source" && entry.Info.OutputArch != "" && entry.Info.OutputArch != GetArch() {
|
if entry.Info.Type == "source" && entry.Info.OutputArch != "" && entry.Info.OutputArch != GetArch() {
|
||||||
ret = append(ret, "Output architecture: "+entry.Info.OutputArch)
|
builder.WriteString("Output architecture: " + entry.Info.OutputArch + "\n")
|
||||||
}
|
}
|
||||||
ret = append(ret, "Type: "+entry.Info.Type)
|
builder.WriteString("Type: " + entry.Info.Type + "\n")
|
||||||
appendArray("Dependencies", entry.Info.Depends, true)
|
|
||||||
if entry.Info.Type == "source" {
|
|
||||||
appendArray("Make Dependencies", entry.Info.MakeDepends, true)
|
|
||||||
}
|
|
||||||
appendArray("Runtime dependencies", entry.Info.RuntimeDepends, true)
|
|
||||||
appendArray("Optional dependencies", entry.Info.OptionalDepends, true)
|
|
||||||
dependants := entry.GetEntryDependants()
|
|
||||||
if len(dependants) > 0 {
|
|
||||||
appendArray("Dependant packages", dependants, false)
|
|
||||||
}
|
|
||||||
optionalDependants := entry.GetEntryOptionalDependants()
|
|
||||||
if len(optionalDependants) > 0 {
|
|
||||||
appendArray("Optionally dependant packages", optionalDependants, false)
|
|
||||||
}
|
|
||||||
appendArray("Conflicting packages", entry.Info.Conflicts, true)
|
|
||||||
appendArray("Provided packages", entry.Info.Provides, true)
|
|
||||||
appendArray("Replaces packages", entry.Info.Replaces, true)
|
|
||||||
|
|
||||||
|
// Dependencies
|
||||||
|
builderWriteDependencyArray("Dependencies", entry.Info.Depends)
|
||||||
|
if entry.Info.Type == "source" {
|
||||||
|
builderWriteDependencyArray("Make dependencies", entry.Info.MakeDepends)
|
||||||
|
builderWriteDependencyArray("Check dependencies", entry.Info.CheckDepends)
|
||||||
|
}
|
||||||
|
builderWriteDependencyArray("Runtime dependencies", entry.Info.RuntimeDepends)
|
||||||
|
if len(entry.Info.OptionalDepends) > 0 {
|
||||||
|
builder.WriteString("Optional dependencies: (" + strconv.Itoa(len(entry.Info.OptionalDepends)) + ")\n")
|
||||||
|
for _, depend := range entry.Info.OptionalDepends {
|
||||||
|
dependSplit := strings.SplitN(depend, ":", 2)
|
||||||
|
if len(dependSplit) == 2 {
|
||||||
|
builder.WriteString(fmt.Sprintf(" - %s (%s)", dependSplit[0], dependSplit[1]))
|
||||||
|
} else {
|
||||||
|
builder.WriteString(" - " + dependSplit[0])
|
||||||
|
}
|
||||||
|
|
||||||
|
// Show virtual package providers
|
||||||
|
if providers := GetDatabaseVirtualPackageEntry(dependSplit[0]); len(providers) > 0 {
|
||||||
|
builder.WriteString(" (")
|
||||||
|
for i, vpkg := range providers {
|
||||||
|
if i == len(providers)-1 {
|
||||||
|
builder.WriteString(vpkg.Info.Name)
|
||||||
|
} else {
|
||||||
|
builder.WriteString(vpkg.Info.Name + ", ")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
builder.WriteString(")")
|
||||||
|
}
|
||||||
|
|
||||||
|
builder.WriteString("\n")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
builderWriteArray("Dependant packages", entry.GetEntryDependants(), true)
|
||||||
|
builderWriteArray("Optionally dependant packages", entry.GetEntryOptionalDependants(), true)
|
||||||
|
|
||||||
|
// Other package relations
|
||||||
|
builderWriteArray("Conflicting packages", entry.Info.Conflicts, true)
|
||||||
|
builderWriteArray("Provided packages", entry.Info.Provides, true)
|
||||||
|
builderWriteArray("Replaces packages", entry.Info.Replaces, true)
|
||||||
|
|
||||||
|
// Split packages
|
||||||
if entry.Info.Type == "source" && len(entry.Info.SplitPackages) != 0 {
|
if entry.Info.Type == "source" && len(entry.Info.SplitPackages) != 0 {
|
||||||
splitPkgs := make([]string, len(entry.Info.SplitPackages))
|
splitPkgs := make([]string, len(entry.Info.SplitPackages))
|
||||||
for i, splitPkgInfo := range entry.Info.SplitPackages {
|
for i, splitPkgInfo := range entry.Info.SplitPackages {
|
||||||
splitPkgs[i] = splitPkgInfo.Name
|
splitPkgs[i] = splitPkgInfo.Name
|
||||||
}
|
}
|
||||||
appendArray("Split Packages", splitPkgs, true)
|
builderWriteArray("Split packages", splitPkgs, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Installation reason
|
||||||
if rootDir != "" && IsPackageInstalled(entry.Info.Name, rootDir) {
|
if rootDir != "" && IsPackageInstalled(entry.Info.Name, rootDir) {
|
||||||
installationReason := GetInstallationReason(entry.Info.Name, rootDir)
|
installationReason := GetPackage(entry.Info.Name, rootDir).LocalInfo.GetInstallationReason()
|
||||||
var installationReasonString string
|
var installationReasonString string
|
||||||
switch installationReason {
|
switch installationReason {
|
||||||
case InstallationReasonManual:
|
case InstallationReasonManual:
|
||||||
@@ -392,17 +450,20 @@ func (entry *BPMDatabaseEntry) CreateReadableInfo(rootDir string, humanReadableS
|
|||||||
default:
|
default:
|
||||||
installationReasonString = "Unknown"
|
installationReasonString = "Unknown"
|
||||||
}
|
}
|
||||||
ret = append(ret, "Installation Reason: "+installationReasonString)
|
builder.WriteString("Installation reason: " + installationReasonString + "\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Installed size
|
||||||
if entry.Info.Type == "binary" {
|
if entry.Info.Type == "binary" {
|
||||||
installedSize := entry.InstalledSize
|
installedSize := entry.InstalledSize
|
||||||
var installedSizeStr string
|
var installedSizeStr string
|
||||||
if humanReadableSize {
|
if showBytes {
|
||||||
installedSizeStr = BytesToHumanReadable(installedSize)
|
|
||||||
} else {
|
|
||||||
installedSizeStr = strconv.FormatInt(installedSize, 10)
|
installedSizeStr = strconv.FormatInt(installedSize, 10)
|
||||||
|
} else {
|
||||||
|
installedSizeStr = BytesToHumanReadable(installedSize)
|
||||||
}
|
}
|
||||||
ret = append(ret, "Installed size: "+installedSizeStr)
|
builder.WriteString("Installed size: " + installedSizeStr + "\n")
|
||||||
}
|
}
|
||||||
return strings.Join(ret, "\n")
|
|
||||||
|
return strings.TrimSpace(builder.String())
|
||||||
}
|
}
|
||||||
|
|||||||
+32
-17
@@ -3,6 +3,7 @@ package bpmlib
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"slices"
|
"slices"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
type pkgInstallationReason struct {
|
type pkgInstallationReason struct {
|
||||||
@@ -10,7 +11,7 @@ type pkgInstallationReason struct {
|
|||||||
InstallationReason InstallationReason
|
InstallationReason InstallationReason
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pkgInfo *PackageInfo) GetDependencies(includeMakeDepends, includeRuntimeDepends, includeOptionalDepends bool) []pkgInstallationReason {
|
func (pkgInfo *PackageInfo) GetDependencies(includeMakeDepends, includeCheckDepends, includeRuntimeDepends, includeOptionalDepends bool) []pkgInstallationReason {
|
||||||
allDepends := make([]pkgInstallationReason, 0)
|
allDepends := make([]pkgInstallationReason, 0)
|
||||||
|
|
||||||
for _, depend := range pkgInfo.Depends {
|
for _, depend := range pkgInfo.Depends {
|
||||||
@@ -25,6 +26,7 @@ func (pkgInfo *PackageInfo) GetDependencies(includeMakeDepends, includeRuntimeDe
|
|||||||
}
|
}
|
||||||
if includeOptionalDepends {
|
if includeOptionalDepends {
|
||||||
for _, depend := range pkgInfo.OptionalDepends {
|
for _, depend := range pkgInfo.OptionalDepends {
|
||||||
|
depend = strings.SplitN(depend, ":", 2)[0]
|
||||||
if !slices.ContainsFunc(allDepends, func(p pkgInstallationReason) bool {
|
if !slices.ContainsFunc(allDepends, func(p pkgInstallationReason) bool {
|
||||||
return p.PkgName == depend
|
return p.PkgName == depend
|
||||||
}) {
|
}) {
|
||||||
@@ -59,6 +61,18 @@ func (pkgInfo *PackageInfo) GetDependencies(includeMakeDepends, includeRuntimeDe
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if includeCheckDepends {
|
||||||
|
for _, depend := range pkgInfo.CheckDepends {
|
||||||
|
if !slices.ContainsFunc(allDepends, func(p pkgInstallationReason) bool {
|
||||||
|
return p.PkgName == depend
|
||||||
|
}) {
|
||||||
|
allDepends = append(allDepends, pkgInstallationReason{
|
||||||
|
PkgName: depend,
|
||||||
|
InstallationReason: InstallationReasonMakeDependency,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Skip ignored packages
|
// Skip ignored packages
|
||||||
allDepends = slices.DeleteFunc(allDepends, func(depend pkgInstallationReason) bool {
|
allDepends = slices.DeleteFunc(allDepends, func(depend pkgInstallationReason) bool {
|
||||||
@@ -68,27 +82,27 @@ func (pkgInfo *PackageInfo) GetDependencies(includeMakeDepends, includeRuntimeDe
|
|||||||
return allDepends
|
return allDepends
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pkgInfo *PackageInfo) GetDependenciesRecursive(includeRuntimeDepends, includeMakeDepends bool, rootDir string) (resolved []string) {
|
func (pkgInfo *PackageInfo) GetDependenciesRecursive(includeRuntimeDepends, includeCheckDepends, includeMakeDepends bool, rootDir string) (resolved []string) {
|
||||||
// Initialize slices
|
// Initialize slices
|
||||||
resolved = make([]string, 0)
|
resolved = make([]string, 0)
|
||||||
unresolved := make([]string, 0)
|
unresolved := make([]string, 0)
|
||||||
|
|
||||||
// Call unexported function
|
// Call unexported function
|
||||||
pkgInfo.getDependenciesRecursive(&resolved, &unresolved, includeRuntimeDepends, includeMakeDepends, rootDir)
|
pkgInfo.getDependenciesRecursive(&resolved, &unresolved, includeRuntimeDepends, includeMakeDepends, includeCheckDepends, rootDir)
|
||||||
|
|
||||||
return resolved
|
return resolved
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pkgInfo *PackageInfo) getDependenciesRecursive(resolved *[]string, unresolved *[]string, includeRuntimeDepends, includeMakeDepends bool, rootDir string) {
|
func (pkgInfo *PackageInfo) getDependenciesRecursive(resolved *[]string, unresolved *[]string, includeRuntimeDepends, includeMakeDepends, includeCheckDepends bool, rootDir string) {
|
||||||
// Add current package name to unresolved slice
|
// Add current package name to unresolved slice
|
||||||
*unresolved = append(*unresolved, pkgInfo.Name)
|
*unresolved = append(*unresolved, pkgInfo.Name)
|
||||||
|
|
||||||
// Loop through all dependencies
|
// Loop through all dependencies
|
||||||
for _, pkgIR := range pkgInfo.GetDependencies(includeMakeDepends, includeRuntimeDepends, false) {
|
for _, pkgIR := range pkgInfo.GetDependencies(includeMakeDepends, includeCheckDepends, includeRuntimeDepends, false) {
|
||||||
depend := pkgIR.PkgName
|
depend := pkgIR.PkgName
|
||||||
|
|
||||||
if isVirtual, p := IsVirtualPackage(depend, rootDir); isVirtual {
|
if providers := GetVirtualPackageInfo(depend, rootDir); len(providers) > 0 {
|
||||||
depend = p
|
depend = providers[0].Name
|
||||||
}
|
}
|
||||||
|
|
||||||
if !slices.Contains(*resolved, depend) {
|
if !slices.Contains(*resolved, depend) {
|
||||||
@@ -103,7 +117,7 @@ func (pkgInfo *PackageInfo) getDependenciesRecursive(resolved *[]string, unresol
|
|||||||
dependInfo := GetPackageInfo(depend, rootDir)
|
dependInfo := GetPackageInfo(depend, rootDir)
|
||||||
|
|
||||||
if dependInfo != nil {
|
if dependInfo != nil {
|
||||||
dependInfo.getDependenciesRecursive(resolved, unresolved, includeRuntimeDepends, includeMakeDepends, rootDir)
|
dependInfo.getDependenciesRecursive(resolved, unresolved, includeRuntimeDepends, includeMakeDepends, includeCheckDepends, rootDir)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -113,7 +127,7 @@ func (pkgInfo *PackageInfo) getDependenciesRecursive(resolved *[]string, unresol
|
|||||||
*unresolved = stringSliceRemove(*unresolved, pkgInfo.Name)
|
*unresolved = stringSliceRemove(*unresolved, pkgInfo.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
func ResolveAllPackageDependenciesFromDatabases(pkgInfo *PackageInfo, resolvedVirtualPkgs map[string]string, checkMake, checkRuntime, checkOptional, ignoreInstalled, verbose bool, rootDir string) (resolved []pkgInstallationReason, unresolved []string) {
|
func ResolveAllPackageDependenciesFromDatabases(pkgInfo *PackageInfo, resolvedVirtualPkgs map[string]string, checkMake, checkCheck, checkRuntime, checkOptional, ignoreInstalled, verbose bool, rootDir string) (resolved []pkgInstallationReason, unresolved []string) {
|
||||||
// Initialize slices and maps
|
// Initialize slices and maps
|
||||||
resolved = make([]pkgInstallationReason, 0)
|
resolved = make([]pkgInstallationReason, 0)
|
||||||
unresolved = make([]string, 0)
|
unresolved = make([]string, 0)
|
||||||
@@ -122,7 +136,7 @@ func ResolveAllPackageDependenciesFromDatabases(pkgInfo *PackageInfo, resolvedVi
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Call unexported function
|
// Call unexported function
|
||||||
resolvePackageDependenciesFromDatabase(&resolved, &unresolved, resolvedVirtualPkgs, pkgInfo, checkMake, checkRuntime, checkOptional, ignoreInstalled, verbose, rootDir)
|
resolvePackageDependenciesFromDatabase(&resolved, &unresolved, resolvedVirtualPkgs, pkgInfo, checkMake, checkCheck, checkRuntime, checkOptional, ignoreInstalled, verbose, rootDir)
|
||||||
|
|
||||||
// Remove main package from unresolved slice
|
// Remove main package from unresolved slice
|
||||||
unresolved = stringSliceRemove(unresolved, pkgInfo.Name)
|
unresolved = stringSliceRemove(unresolved, pkgInfo.Name)
|
||||||
@@ -130,7 +144,7 @@ func ResolveAllPackageDependenciesFromDatabases(pkgInfo *PackageInfo, resolvedVi
|
|||||||
return resolved, unresolved
|
return resolved, unresolved
|
||||||
}
|
}
|
||||||
|
|
||||||
func resolvePackageDependenciesFromDatabase(resolved *[]pkgInstallationReason, unresolved *[]string, resolvedVirtualPkgs map[string]string, pkgInfo *PackageInfo, checkMake, checkRuntime, checkOptional, ignoreInstalled, verbose bool, rootDir string) {
|
func resolvePackageDependenciesFromDatabase(resolved *[]pkgInstallationReason, unresolved *[]string, resolvedVirtualPkgs map[string]string, pkgInfo *PackageInfo, checkMake, checkCheck, checkRuntime, checkOptional, ignoreInstalled, verbose bool, rootDir string) {
|
||||||
// Add current package name to unresolved slice
|
// Add current package name to unresolved slice
|
||||||
*unresolved = append(*unresolved, pkgInfo.Name)
|
*unresolved = append(*unresolved, pkgInfo.Name)
|
||||||
|
|
||||||
@@ -141,7 +155,7 @@ func resolvePackageDependenciesFromDatabase(resolved *[]pkgInstallationReason, u
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Loop through all dependencies
|
// Loop through all dependencies
|
||||||
for _, pkgIR := range pkgInfo.GetDependencies(pkgInfo.Type == "source", checkRuntime, checkOptional) {
|
for _, pkgIR := range pkgInfo.GetDependencies(pkgInfo.Type == "source", pkgInfo.Type == "source" && checkCheck, checkRuntime, checkOptional) {
|
||||||
// Skip dependency if it has already been resolved
|
// Skip dependency if it has already been resolved
|
||||||
if slices.ContainsFunc(*resolved, func(p pkgInstallationReason) bool {
|
if slices.ContainsFunc(*resolved, func(p pkgInstallationReason) bool {
|
||||||
return p.PkgName == pkgIR.PkgName
|
return p.PkgName == pkgIR.PkgName
|
||||||
@@ -163,7 +177,7 @@ func resolvePackageDependenciesFromDatabase(resolved *[]pkgInstallationReason, u
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Skip dependency if it is already installed or provided
|
// Skip dependency if it is already installed or provided
|
||||||
if ignoreInstalled && IsPackageProvided(pkgIR.PkgName, rootDir) {
|
if providers := GetVirtualPackageInfo(pkgIR.PkgName, rootDir); ignoreInstalled && len(providers) > 0 {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -187,8 +201,9 @@ func resolvePackageDependenciesFromDatabase(resolved *[]pkgInstallationReason, u
|
|||||||
*unresolved = stringSliceRemove(*unresolved, resolvedVirtualPkg)
|
*unresolved = stringSliceRemove(*unresolved, resolvedVirtualPkg)
|
||||||
|
|
||||||
continue
|
continue
|
||||||
} else if entry = ResolveVirtualPackage(pkgIR.PkgName); entry != nil {
|
} else if providers := GetDatabaseVirtualPackageEntry(pkgIR.PkgName); len(providers) > 0 {
|
||||||
// Virtual package found in database
|
// Virtual package found in database
|
||||||
|
entry = providers[0]
|
||||||
} else {
|
} else {
|
||||||
// Virtual package not found
|
// Virtual package not found
|
||||||
if !slices.Contains(*unresolved, pkgIR.PkgName) {
|
if !slices.Contains(*unresolved, pkgIR.PkgName) {
|
||||||
@@ -199,7 +214,7 @@ func resolvePackageDependenciesFromDatabase(resolved *[]pkgInstallationReason, u
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Resolve the dependencies of this dependency
|
// Resolve the dependencies of this dependency
|
||||||
resolvePackageDependenciesFromDatabase(resolved, unresolved, resolvedVirtualPkgs, entry.Info, checkMake, checkRuntime, false, ignoreInstalled, verbose, rootDir)
|
resolvePackageDependenciesFromDatabase(resolved, unresolved, resolvedVirtualPkgs, entry.Info, checkMake, checkCheck, checkRuntime, false, ignoreInstalled, verbose, rootDir)
|
||||||
|
|
||||||
// Move dependency from the unresolved slice to the resolved slice
|
// Move dependency from the unresolved slice to the resolved slice
|
||||||
if !slices.ContainsFunc(*resolved, func(p pkgInstallationReason) bool {
|
if !slices.ContainsFunc(*resolved, func(p pkgInstallationReason) bool {
|
||||||
@@ -283,7 +298,7 @@ func (pkgInfo *PackageInfo) GetPackageOptionalDependants(rootDir string) (depend
|
|||||||
|
|
||||||
// Add installed package to list if its optional dependencies include pkgName
|
// Add installed package to list if its optional dependencies include pkgName
|
||||||
if slices.ContainsFunc(installedPkg.OptionalDepends, func(n string) bool {
|
if slices.ContainsFunc(installedPkg.OptionalDepends, func(n string) bool {
|
||||||
return n == pkgInfo.Name
|
return strings.SplitN(n, ":", 2)[0] == pkgInfo.Name
|
||||||
}) {
|
}) {
|
||||||
dependants = append(dependants, installedPkg.Name)
|
dependants = append(dependants, installedPkg.Name)
|
||||||
continue
|
continue
|
||||||
@@ -293,7 +308,7 @@ func (pkgInfo *PackageInfo) GetPackageOptionalDependants(rootDir string) (depend
|
|||||||
for _, vpkg := range pkgInfo.Provides {
|
for _, vpkg := range pkgInfo.Provides {
|
||||||
// Add installed package to list if its optional dependencies contain a provided virtual package
|
// Add installed package to list if its optional dependencies contain a provided virtual package
|
||||||
if slices.ContainsFunc(installedPkg.OptionalDepends, func(n string) bool {
|
if slices.ContainsFunc(installedPkg.OptionalDepends, func(n string) bool {
|
||||||
return n == vpkg
|
return strings.SplitN(n, ":", 2)[0] == vpkg
|
||||||
}) {
|
}) {
|
||||||
dependants = append(dependants, installedPkg.Name)
|
dependants = append(dependants, installedPkg.Name)
|
||||||
break
|
break
|
||||||
|
|||||||
+14
-12
@@ -20,12 +20,13 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// InstallPackages installs the specified packages into the given root directory by fetching them from databases or directly from local bpm archives
|
// InstallPackages installs the specified packages into the given root directory by fetching them from databases or directly from local bpm archives
|
||||||
func InstallPackages(rootDir string, forceInstallationReason InstallationReason, reinstallMethod ReinstallMethod, installRuntimeDependencies, installOptionalDependencies, forceInstallation, verbose bool, packages ...string) (operation *BPMOperation, err error) {
|
func InstallPackages(rootDir string, forceInstallationReason InstallationReason, reinstallMethod ReinstallMethod, installRuntimeDependencies, installOptionalDependencies, forceInstallation, runChecks bool, verbose bool, packages ...string) (operation *BPMOperation, err error) {
|
||||||
// Setup operation struct
|
// Setup operation struct
|
||||||
operation = &BPMOperation{
|
operation = &BPMOperation{
|
||||||
Actions: make([]OperationAction, 0),
|
Actions: make([]OperationAction, 0),
|
||||||
UnresolvedDepends: make([]string, 0),
|
UnresolvedDepends: make([]string, 0),
|
||||||
Changes: make(map[string]string),
|
Changes: make(map[string]string),
|
||||||
|
RunChecks: runChecks,
|
||||||
RootDir: rootDir,
|
RootDir: rootDir,
|
||||||
compiledPackages: make(map[string]string),
|
compiledPackages: make(map[string]string),
|
||||||
}
|
}
|
||||||
@@ -52,7 +53,7 @@ func InstallPackages(rootDir string, forceInstallationReason InstallationReason,
|
|||||||
installationReason := forceInstallationReason
|
installationReason := forceInstallationReason
|
||||||
if installationReason == InstallationReasonUnknown {
|
if installationReason == InstallationReasonUnknown {
|
||||||
if IsPackageInstalled(splitPkg.Name, rootDir) {
|
if IsPackageInstalled(splitPkg.Name, rootDir) {
|
||||||
installationReason = GetInstallationReason(splitPkg.Name, rootDir)
|
installationReason = GetPackage(splitPkg.Name, rootDir).LocalInfo.GetInstallationReason()
|
||||||
} else {
|
} else {
|
||||||
installationReason = InstallationReasonManual
|
installationReason = InstallationReasonManual
|
||||||
}
|
}
|
||||||
@@ -76,7 +77,7 @@ func InstallPackages(rootDir string, forceInstallationReason InstallationReason,
|
|||||||
installationReason := forceInstallationReason
|
installationReason := forceInstallationReason
|
||||||
if installationReason == InstallationReasonUnknown {
|
if installationReason == InstallationReasonUnknown {
|
||||||
if IsPackageInstalled(bpmpkg.PkgInfo.Name, rootDir) {
|
if IsPackageInstalled(bpmpkg.PkgInfo.Name, rootDir) {
|
||||||
installationReason = GetInstallationReason(bpmpkg.PkgInfo.Name, rootDir)
|
installationReason = GetPackage(bpmpkg.PkgInfo.Name, rootDir).LocalInfo.GetInstallationReason()
|
||||||
} else {
|
} else {
|
||||||
installationReason = InstallationReasonManual
|
installationReason = InstallationReasonManual
|
||||||
}
|
}
|
||||||
@@ -92,14 +93,14 @@ func InstallPackages(rootDir string, forceInstallationReason InstallationReason,
|
|||||||
|
|
||||||
if e, _, err := GetDatabaseEntry(pkg); err == nil {
|
if e, _, err := GetDatabaseEntry(pkg); err == nil {
|
||||||
entry = e
|
entry = e
|
||||||
} else if isVirtual, p := IsVirtualPackage(pkg, rootDir); isVirtual {
|
} else if providers := GetVirtualPackageInfo(pkg, rootDir); len(providers) > 0 {
|
||||||
entry, _, err = GetDatabaseEntry(p)
|
entry, _, err = GetDatabaseEntry(providers[0].Name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
pkgsNotFound = append(pkgsNotFound, pkg)
|
pkgsNotFound = append(pkgsNotFound, pkg)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
} else if e := ResolveVirtualPackage(pkg); e != nil {
|
} else if providers := GetDatabaseVirtualPackageEntry(pkg); len(providers) > 0 {
|
||||||
entry = e
|
entry = providers[0]
|
||||||
} else {
|
} else {
|
||||||
pkgsNotFound = append(pkgsNotFound, pkg)
|
pkgsNotFound = append(pkgsNotFound, pkg)
|
||||||
continue
|
continue
|
||||||
@@ -112,7 +113,7 @@ func InstallPackages(rootDir string, forceInstallationReason InstallationReason,
|
|||||||
installationReason := forceInstallationReason
|
installationReason := forceInstallationReason
|
||||||
if installationReason == InstallationReasonUnknown {
|
if installationReason == InstallationReasonUnknown {
|
||||||
if IsPackageInstalled(entry.Info.Name, rootDir) {
|
if IsPackageInstalled(entry.Info.Name, rootDir) {
|
||||||
installationReason = GetInstallationReason(entry.Info.Name, rootDir)
|
installationReason = GetPackage(entry.Info.Name, rootDir).LocalInfo.GetInstallationReason()
|
||||||
} else {
|
} else {
|
||||||
installationReason = InstallationReasonManual
|
installationReason = InstallationReasonManual
|
||||||
}
|
}
|
||||||
@@ -201,8 +202,8 @@ func RemovePackages(rootDir string, force, cleanupDependencies bool, packages ..
|
|||||||
// Search for packages
|
// Search for packages
|
||||||
for _, pkg := range packages {
|
for _, pkg := range packages {
|
||||||
bpmpkg := GetPackage(pkg, rootDir)
|
bpmpkg := GetPackage(pkg, rootDir)
|
||||||
if isVirutal, vpkg := IsVirtualPackage(pkg, rootDir); isVirutal {
|
if providers := GetVirtualPackageInfo(pkg, rootDir); len(providers) > 0 {
|
||||||
bpmpkg = GetPackage(vpkg, rootDir)
|
bpmpkg = GetPackage(providers[0].Name, rootDir)
|
||||||
}
|
}
|
||||||
if bpmpkg == nil {
|
if bpmpkg == nil {
|
||||||
continue
|
continue
|
||||||
@@ -365,7 +366,7 @@ func CleanupCache(rootDir string, cleanupCompilationFiles, cleanupCompiledPackag
|
|||||||
}
|
}
|
||||||
|
|
||||||
// UpdatePackages fetches the newest versions of all installed packages from
|
// UpdatePackages fetches the newest versions of all installed packages from
|
||||||
func UpdatePackages(rootDir string, syncDatabase bool, allowDowngrades bool, installOptionalDependencies, forceInstallation, verbose bool) (operation *BPMOperation, err error) {
|
func UpdatePackages(rootDir string, syncDatabase bool, allowDowngrades bool, installOptionalDependencies, forceInstallation, runChecks, verbose bool) (operation *BPMOperation, err error) {
|
||||||
// Sync databases
|
// Sync databases
|
||||||
if syncDatabase {
|
if syncDatabase {
|
||||||
err := SyncDatabase(verbose)
|
err := SyncDatabase(verbose)
|
||||||
@@ -397,6 +398,7 @@ func UpdatePackages(rootDir string, syncDatabase bool, allowDowngrades bool, ins
|
|||||||
Actions: make([]OperationAction, 0),
|
Actions: make([]OperationAction, 0),
|
||||||
UnresolvedDepends: make([]string, 0),
|
UnresolvedDepends: make([]string, 0),
|
||||||
Changes: make(map[string]string),
|
Changes: make(map[string]string),
|
||||||
|
RunChecks: runChecks,
|
||||||
RootDir: rootDir,
|
RootDir: rootDir,
|
||||||
compiledPackages: make(map[string]string),
|
compiledPackages: make(map[string]string),
|
||||||
}
|
}
|
||||||
@@ -421,7 +423,7 @@ func UpdatePackages(rootDir string, syncDatabase bool, allowDowngrades bool, ins
|
|||||||
comparison := CompareVersions(entry.Info.GetFullVersion(), installedInfo.GetFullVersion())
|
comparison := CompareVersions(entry.Info.GetFullVersion(), installedInfo.GetFullVersion())
|
||||||
if (!allowDowngrades && comparison > 0) || (allowDowngrades && comparison != 0) {
|
if (!allowDowngrades && comparison > 0) || (allowDowngrades && comparison != 0) {
|
||||||
operation.AppendAction(&FetchPackageAction{
|
operation.AppendAction(&FetchPackageAction{
|
||||||
InstallationReason: GetInstallationReason(pkg, rootDir),
|
InstallationReason: GetPackage(pkg, rootDir).LocalInfo.GetInstallationReason(),
|
||||||
DatabaseEntry: entry,
|
DatabaseEntry: entry,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,20 +7,42 @@ import (
|
|||||||
"slices"
|
"slices"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"gopkg.in/yaml.v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
var localPackageInformation map[string]map[string]*PackageInfo = make(map[string]map[string]*PackageInfo)
|
var persistentDataVersion int = 1
|
||||||
|
|
||||||
func initializeLocalPackageInformation(rootDir string) (err error) {
|
var localPackageInformation map[string]map[string]*PackageInfo = make(map[string]map[string]*PackageInfo)
|
||||||
|
var installedVirtualPackages map[string]map[string][]*PackageInfo = make(map[string]map[string][]*PackageInfo)
|
||||||
|
|
||||||
|
func InitializeLocalPackageInformation(rootDir string) (err error) {
|
||||||
// Return if information is already initialized
|
// Return if information is already initialized
|
||||||
if _, ok := localPackageInformation[rootDir]; ok {
|
if _, ok := localPackageInformation[rootDir]; ok {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
tempPackageInformation := make(map[string]*PackageInfo)
|
tempPackageInformation := make(map[string]*PackageInfo)
|
||||||
|
tempInstalledVirtualPackages := make(map[string][]*PackageInfo)
|
||||||
|
|
||||||
// Get path to installed package information directory
|
// Get paths
|
||||||
installedDir := path.Join(rootDir, "var/lib/bpm/installed/")
|
persistentDataDir := path.Join(rootDir, "var/lib/bpm")
|
||||||
|
installedDir := path.Join(persistentDataDir, "installed")
|
||||||
|
|
||||||
|
// Ensure persistent data directory is up-to-date
|
||||||
|
if _, err := os.Stat(persistentDataDir); err == nil {
|
||||||
|
data, err := os.ReadFile(path.Join(persistentDataDir, ".version"))
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("persistent data is not up-to-date! Please run 'bpm upgrade-persistent-data' first")
|
||||||
|
}
|
||||||
|
currentPersistentDataVersion, err := strconv.Atoi(strings.TrimSpace(string(data)))
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("persistent data is not up-to-date! Please run 'bpm upgrade-persistent-data' first")
|
||||||
|
}
|
||||||
|
if currentPersistentDataVersion != persistentDataVersion {
|
||||||
|
return fmt.Errorf("persistent data is not up-to-date! Please run 'bpm upgrade-persistent-data' first")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Get directory content
|
// Get directory content
|
||||||
items, err := os.ReadDir(installedDir)
|
items, err := os.ReadDir(installedDir)
|
||||||
@@ -51,15 +73,21 @@ func initializeLocalPackageInformation(rootDir string) (err error) {
|
|||||||
|
|
||||||
// Add package to slice
|
// Add package to slice
|
||||||
tempPackageInformation[info.Name] = info
|
tempPackageInformation[info.Name] = info
|
||||||
|
|
||||||
|
// Add virtual packages
|
||||||
|
for _, vpkg := range info.Provides {
|
||||||
|
tempInstalledVirtualPackages[vpkg] = append(tempInstalledVirtualPackages[vpkg], info)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
localPackageInformation[rootDir] = tempPackageInformation
|
localPackageInformation[rootDir] = tempPackageInformation
|
||||||
|
installedVirtualPackages[rootDir] = tempInstalledVirtualPackages
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetInstalledPackages(rootDir string) (ret []string, err error) {
|
func GetInstalledPackages(rootDir string) (ret []string, err error) {
|
||||||
// Initialize local package information
|
// Initialize local package information
|
||||||
err = initializeLocalPackageInformation(rootDir)
|
err = InitializeLocalPackageInformation(rootDir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -77,7 +105,7 @@ func GetInstalledPackages(rootDir string) (ret []string, err error) {
|
|||||||
|
|
||||||
func IsPackageInstalled(pkg, rootDir string) bool {
|
func IsPackageInstalled(pkg, rootDir string) bool {
|
||||||
// Initialize local package information
|
// Initialize local package information
|
||||||
err := initializeLocalPackageInformation(rootDir)
|
err := InitializeLocalPackageInformation(rootDir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@@ -88,48 +116,17 @@ func IsPackageInstalled(pkg, rootDir string) bool {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
func IsVirtualPackage(pkg, rootDir string) (bool, string) {
|
func GetVirtualPackageInfo(vpkg, rootDir string) []*PackageInfo {
|
||||||
pkgs, err := GetInstalledPackages(rootDir)
|
err := InitializeLocalPackageInformation(rootDir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, ""
|
return nil
|
||||||
}
|
}
|
||||||
for _, p := range pkgs {
|
|
||||||
if p == pkg {
|
|
||||||
return false, ""
|
|
||||||
}
|
|
||||||
i := GetPackageInfo(p, rootDir)
|
|
||||||
if i == nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if slices.Contains(i.Provides, pkg) {
|
|
||||||
return true, p
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false, ""
|
|
||||||
}
|
|
||||||
|
|
||||||
func IsPackageProvided(pkg, rootDir string) bool {
|
return installedVirtualPackages[rootDir][vpkg]
|
||||||
pkgs, err := GetInstalledPackages(rootDir)
|
|
||||||
if err != nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
for _, p := range pkgs {
|
|
||||||
if p == pkg {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
i := GetPackageInfo(p, rootDir)
|
|
||||||
if i == nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if slices.Contains(i.Provides, pkg) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetPackageInfo(pkg string, rootDir string) *PackageInfo {
|
func GetPackageInfo(pkg string, rootDir string) *PackageInfo {
|
||||||
err := initializeLocalPackageInformation(rootDir)
|
err := InitializeLocalPackageInformation(rootDir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -144,10 +141,12 @@ func GetPackage(pkg, rootDir string) *BPMPackage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
files := getPackageFiles(pkgInfo.Name, rootDir)
|
files := getPackageFiles(pkgInfo.Name, rootDir)
|
||||||
|
localInfo := getPackageLocalInfo(pkgInfo.Name, rootDir)
|
||||||
|
|
||||||
return &BPMPackage{
|
return &BPMPackage{
|
||||||
PkgInfo: pkgInfo,
|
PkgInfo: pkgInfo,
|
||||||
PkgFiles: files,
|
PkgFiles: files,
|
||||||
|
LocalInfo: localInfo,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -234,3 +233,127 @@ func getPackageFiles(pkg, rootDir string) []*PackageFileEntry {
|
|||||||
|
|
||||||
return pkgFiles
|
return pkgFiles
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getPackageLocalInfo(pkg, rootDir string) PackageLocalInfo {
|
||||||
|
localInfo := PackageLocalInfo{}
|
||||||
|
|
||||||
|
installedDir := path.Join(rootDir, "var/lib/bpm/installed/")
|
||||||
|
pkgDir := path.Join(installedDir, pkg)
|
||||||
|
localInfoFile := path.Join(path.Join(pkgDir, "local"))
|
||||||
|
|
||||||
|
if _, err := os.Stat(localInfoFile); os.IsNotExist(err) {
|
||||||
|
return localInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
file, err := os.Open(localInfoFile)
|
||||||
|
if err != nil {
|
||||||
|
return localInfo
|
||||||
|
}
|
||||||
|
defer file.Close()
|
||||||
|
|
||||||
|
err = yaml.NewDecoder(file).Decode(&localInfo)
|
||||||
|
if err != nil {
|
||||||
|
return localInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
return localInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
func SetPackageLocalInfo(pkg string, localInfo PackageLocalInfo, rootDir string) error {
|
||||||
|
installedDir := path.Join(rootDir, "var/lib/bpm/installed/")
|
||||||
|
pkgDir := path.Join(installedDir, pkg)
|
||||||
|
|
||||||
|
localFile, err := os.OpenFile(path.Join(pkgDir, "local"), os.O_WRONLY|os.O_CREATE, 0644)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer localFile.Close()
|
||||||
|
|
||||||
|
err = yaml.NewEncoder(localFile).Encode(localInfo)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func UpgradePersistentData(rootDir string) error {
|
||||||
|
persistentDataDir := path.Join(rootDir, "var/lib/bpm")
|
||||||
|
|
||||||
|
// Create persistent data directory
|
||||||
|
os.MkdirAll(persistentDataDir, 0755)
|
||||||
|
|
||||||
|
// Upgrade installed package directories
|
||||||
|
dirEntries, err := os.ReadDir(path.Join(persistentDataDir, "installed"))
|
||||||
|
if err != nil && !os.IsNotExist(err) {
|
||||||
|
return err
|
||||||
|
} else if err == nil {
|
||||||
|
for _, entry := range dirEntries {
|
||||||
|
pkgDir := path.Join(persistentDataDir, "installed", entry.Name())
|
||||||
|
|
||||||
|
// Generate default local package information file
|
||||||
|
if _, err := os.Stat(path.Join(pkgDir, "local")); err != nil && !os.IsNotExist(err) {
|
||||||
|
return err
|
||||||
|
} else if os.IsNotExist(err) {
|
||||||
|
fmt.Printf("Generating local package information for package (%s)\n", entry.Name())
|
||||||
|
|
||||||
|
out, err := yaml.Marshal(PackageLocalInfo{
|
||||||
|
InstallationReason: "unknown",
|
||||||
|
InstalledOn: 0,
|
||||||
|
LastUpdatedOn: 0,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = os.WriteFile(path.Join(pkgDir, "local"), out, 0644)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Move installation reason to local package information file
|
||||||
|
if installationReason, err := os.ReadFile(path.Join(pkgDir, "installation_reason")); err != nil && !os.IsNotExist(err) {
|
||||||
|
return err
|
||||||
|
} else if err == nil {
|
||||||
|
fmt.Printf("Moving installation reason to local package information for package (%s)\n", entry.Name())
|
||||||
|
|
||||||
|
data, err := os.ReadFile(path.Join(pkgDir, "local"))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
localInfo := &PackageLocalInfo{}
|
||||||
|
err = yaml.Unmarshal(data, localInfo)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
localInfo.InstallationReason = strings.TrimSpace(string(installationReason))
|
||||||
|
|
||||||
|
out, err := yaml.Marshal(localInfo)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = os.WriteFile(path.Join(pkgDir, "local"), out, 0644)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = os.Remove(path.Join(pkgDir, "installation_reason"))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set persistent data version number
|
||||||
|
err = os.WriteFile(path.Join(persistentDataDir, ".version"), []byte(strconv.Itoa(persistentDataVersion)), 0644)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|||||||
+67
-31
@@ -16,6 +16,7 @@ type BPMOperation struct {
|
|||||||
UnresolvedDepends []string
|
UnresolvedDepends []string
|
||||||
Changes map[string]string
|
Changes map[string]string
|
||||||
CompilationJobs int
|
CompilationJobs int
|
||||||
|
RunChecks bool
|
||||||
RootDir string
|
RootDir string
|
||||||
|
|
||||||
compiledPackages map[string]string
|
compiledPackages map[string]string
|
||||||
@@ -146,7 +147,7 @@ func (operation *BPMOperation) ResolveDependencies(reinstallDependencies, instal
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
resolved, unresolved := ResolveAllPackageDependenciesFromDatabases(pkgInfo, resolvedVirtualPkgs, pkgInfo.Type == "source", installRuntimeDependencies, installOptionalDependencies, !reinstallDependencies, verbose, operation.RootDir)
|
resolved, unresolved := ResolveAllPackageDependenciesFromDatabases(pkgInfo, resolvedVirtualPkgs, pkgInfo.Type == "source", pkgInfo.Type == "source" && operation.RunChecks, installRuntimeDependencies, installOptionalDependencies, !reinstallDependencies, verbose, operation.RootDir)
|
||||||
|
|
||||||
operation.UnresolvedDepends = append(operation.UnresolvedDepends, unresolved...)
|
operation.UnresolvedDepends = append(operation.UnresolvedDepends, unresolved...)
|
||||||
|
|
||||||
@@ -204,11 +205,11 @@ func (operation *BPMOperation) Cleanup(cleanupMakeDepends bool) error {
|
|||||||
}
|
}
|
||||||
installedPackages := make([]*PackageInfo, len(installedPackageNames))
|
installedPackages := make([]*PackageInfo, len(installedPackageNames))
|
||||||
for i, value := range installedPackageNames {
|
for i, value := range installedPackageNames {
|
||||||
bpmpkg := GetPackage(value, operation.RootDir)
|
pkgInfo := GetPackageInfo(value, operation.RootDir)
|
||||||
if bpmpkg == nil {
|
if pkgInfo == nil {
|
||||||
return errors.New("could not find installed package (" + value + ")")
|
return errors.New("could not find installed package (" + value + ")")
|
||||||
}
|
}
|
||||||
installedPackages[i] = bpmpkg.PkgInfo
|
installedPackages[i] = pkgInfo
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get packages to remove
|
// Get packages to remove
|
||||||
@@ -219,34 +220,67 @@ func (operation *BPMOperation) Cleanup(cleanupMakeDepends bool) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get manually installed packages, resolve all their dependencies and add them to the keepPackages slice
|
// Run BFS on all manually installed packages
|
||||||
keepPackages := make([]string, 0)
|
visited := make([]string, 0)
|
||||||
for _, pkg := range slices.Clone(installedPackages) {
|
for _, pkg := range installedPackages {
|
||||||
if GetInstallationReason(pkg.Name, operation.RootDir) != InstallationReasonManual {
|
if getPackageLocalInfo(pkg.Name, operation.RootDir).GetInstallationReason() != InstallationReasonManual {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
// Do not resolve dependencies or add package to keepPackages slice if package removal action exists for it
|
queue := make([]*PackageInfo, 0)
|
||||||
if _, ok := removeActions[pkg.Name]; ok {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
keepPackages = append(keepPackages, pkg.Name)
|
queue = append(queue, pkg)
|
||||||
resolved := pkg.GetDependenciesRecursive(true, !cleanupMakeDepends, operation.RootDir)
|
|
||||||
for _, value := range resolved {
|
for len(queue) > 0 {
|
||||||
if !slices.Contains(keepPackages, value) && !slices.Contains(MainBPMConfig.IgnorePackages, value) {
|
v := queue[len(queue)-1]
|
||||||
keepPackages = append(keepPackages, value)
|
queue = queue[:len(queue)-1]
|
||||||
|
|
||||||
|
// Skip package if it's to be removed
|
||||||
|
if _, ok := removeActions[v.Name]; ok {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mark package as visited
|
||||||
|
visited = append(visited, v.Name)
|
||||||
|
|
||||||
|
// Get all package dependencies
|
||||||
|
depends := v.Depends
|
||||||
|
depends = append(depends, v.RuntimeDepends...)
|
||||||
|
if cleanupMakeDepends {
|
||||||
|
depends = append(depends, v.MakeDepends...)
|
||||||
|
depends = append(depends, v.CheckDepends...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Loop through all dependencies
|
||||||
|
for _, depend := range depends {
|
||||||
|
// Resolve dependency
|
||||||
|
var dependPkgInfo *PackageInfo
|
||||||
|
if providers := GetVirtualPackageInfo(depend, operation.RootDir); len(providers) > 0 {
|
||||||
|
dependPkgInfo = providers[0]
|
||||||
|
} else {
|
||||||
|
dependPkgInfo = GetPackageInfo(depend, operation.RootDir)
|
||||||
|
}
|
||||||
|
if dependPkgInfo == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mark dependency as visited and add it to the queue
|
||||||
|
if !slices.Contains(visited, dependPkgInfo.Name) {
|
||||||
|
visited = append(visited, dependPkgInfo.Name)
|
||||||
|
queue = append(queue, dependPkgInfo)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get all installed packages that are not in the keepPackages slice and add them to the BPM operation
|
// Remove all packages that were not discovered after running BFS
|
||||||
for _, pkg := range installedPackageNames {
|
for _, pkg := range installedPackageNames {
|
||||||
// Do not add package removal action if there already is one
|
// Do not add package removal action if there already is one
|
||||||
if _, ok := removeActions[pkg]; ok {
|
if _, ok := removeActions[pkg]; ok {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if !slices.Contains(keepPackages, pkg) {
|
|
||||||
|
if !slices.Contains(visited, pkg) {
|
||||||
bpmpkg := GetPackage(pkg, operation.RootDir)
|
bpmpkg := GetPackage(pkg, operation.RootDir)
|
||||||
if bpmpkg == nil {
|
if bpmpkg == nil {
|
||||||
return errors.New("Error: could not find installed package (" + pkg + ")")
|
return errors.New("Error: could not find installed package (" + pkg + ")")
|
||||||
@@ -485,17 +519,25 @@ func (operation *BPMOperation) GetOptionalDependencies() (optionalDepends map[st
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, depend := range pkgInfo.OptionalDepends {
|
for _, depend := range pkgInfo.OptionalDepends {
|
||||||
|
dependSplit := strings.SplitN(depend, ":", 2)
|
||||||
|
|
||||||
// Skip if dependency is already installed
|
// Skip if dependency is already installed
|
||||||
if IsPackageInstalled(depend, operation.RootDir) {
|
if IsPackageInstalled(dependSplit[0], operation.RootDir) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
// Skip if not a new dependency of the package
|
// Skip if not a new dependency of the package
|
||||||
if installedPkg := GetPackage(pkgInfo.Name, operation.RootDir); installedPkg != nil && slices.Contains(installedPkg.PkgInfo.OptionalDepends, depend) {
|
if installedPkg := GetPackage(pkgInfo.Name, operation.RootDir); installedPkg != nil && slices.ContainsFunc(installedPkg.PkgInfo.OptionalDepends, func(n string) bool {
|
||||||
|
return strings.SplitN(n, ":", 2)[0] == dependSplit[0]
|
||||||
|
}) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
optionalDepends[pkgInfo.Name] = append(optionalDepends[pkgInfo.Name], depend)
|
if len(dependSplit) == 2 {
|
||||||
|
optionalDepends[pkgInfo.Name] = append(optionalDepends[pkgInfo.Name], fmt.Sprintf("%s (%s)", dependSplit[0], dependSplit[1]))
|
||||||
|
} else {
|
||||||
|
optionalDepends[pkgInfo.Name] = append(optionalDepends[pkgInfo.Name], dependSplit[0])
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -672,7 +714,7 @@ func (operation *BPMOperation) Execute(verbose, force bool) (err error) {
|
|||||||
|
|
||||||
// Compile source package if not compiled already
|
// Compile source package if not compiled already
|
||||||
if _, ok := operation.compiledPackages[pkgNameToInstall]; !ok {
|
if _, ok := operation.compiledPackages[pkgNameToInstall]; !ok {
|
||||||
outputBpmPackages, err := CompileSourcePackage(value.File, compiledDir, operation.CompilationJobs, false, false, verbose)
|
outputBpmPackages, err := CompileSourcePackage(value.File, compiledDir, operation.CompilationJobs, !operation.RunChecks, false, verbose)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("could not compile source package (%s): %s\n", value.File, err)
|
return fmt.Errorf("could not compile source package (%s): %s\n", value.File, err)
|
||||||
}
|
}
|
||||||
@@ -692,19 +734,13 @@ func (operation *BPMOperation) Execute(verbose, force bool) (err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if value.InstallationReason != InstallationReasonManual {
|
if value.InstallationReason != InstallationReasonManual {
|
||||||
err = installPackage(fileToInstall, operation.RootDir, verbose, true)
|
err = installPackage(fileToInstall, value.InstallationReason, operation.RootDir, verbose, true)
|
||||||
} else {
|
} else {
|
||||||
err = installPackage(fileToInstall, operation.RootDir, verbose, force)
|
err = installPackage(fileToInstall, value.InstallationReason, operation.RootDir, verbose, force)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("could not install package (%s): %s\n", bpmpkg.PkgInfo.Name, err)
|
return fmt.Errorf("could not install package (%s): %s\n", bpmpkg.PkgInfo.Name, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set installed package's installation reason
|
|
||||||
err = SetInstallationReason(bpmpkg.PkgInfo.Name, value.InstallationReason, operation.RootDir)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("could not set installation reason for package (%s): %s\n", value.BpmPackage.PkgInfo.Name, err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fmt.Println("Operation complete!")
|
fmt.Println("Operation complete!")
|
||||||
|
|||||||
+141
-69
@@ -16,13 +16,15 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
"time"
|
||||||
|
|
||||||
"gopkg.in/yaml.v3"
|
"gopkg.in/yaml.v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
type BPMPackage struct {
|
type BPMPackage struct {
|
||||||
PkgInfo *PackageInfo
|
PkgInfo *PackageInfo
|
||||||
PkgFiles []*PackageFileEntry
|
PkgFiles []*PackageFileEntry
|
||||||
|
LocalInfo PackageLocalInfo
|
||||||
}
|
}
|
||||||
|
|
||||||
type PackageInfo struct {
|
type PackageInfo struct {
|
||||||
@@ -41,6 +43,7 @@ type PackageInfo struct {
|
|||||||
RuntimeDepends []string `yaml:"runtime_depends,omitempty"`
|
RuntimeDepends []string `yaml:"runtime_depends,omitempty"`
|
||||||
OptionalDepends []string `yaml:"optional_depends,omitempty"`
|
OptionalDepends []string `yaml:"optional_depends,omitempty"`
|
||||||
MakeDepends []string `yaml:"make_depends,omitempty"`
|
MakeDepends []string `yaml:"make_depends,omitempty"`
|
||||||
|
CheckDepends []string `yaml:"check_depends,omitempty"`
|
||||||
Conflicts []string `yaml:"conflicts,omitempty"`
|
Conflicts []string `yaml:"conflicts,omitempty"`
|
||||||
Replaces []string `yaml:"replaces,omitempty"`
|
Replaces []string `yaml:"replaces,omitempty"`
|
||||||
Provides []string `yaml:"provides,omitempty"`
|
Provides []string `yaml:"provides,omitempty"`
|
||||||
@@ -74,6 +77,12 @@ type PackageFileEntry struct {
|
|||||||
SizeInBytes int64
|
SizeInBytes int64
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type PackageLocalInfo struct {
|
||||||
|
InstallationReason string `yaml:"installation_reason"`
|
||||||
|
InstalledOn int64 `yaml:"installed_on"`
|
||||||
|
LastUpdatedOn int64 `yaml:"last_updated_on"`
|
||||||
|
}
|
||||||
|
|
||||||
func (pkg *BPMPackage) GetInstalledSize() int64 {
|
func (pkg *BPMPackage) GetInstalledSize() int64 {
|
||||||
var totalSize int64 = 0
|
var totalSize int64 = 0
|
||||||
for _, entry := range pkg.PkgFiles {
|
for _, entry := range pkg.PkgFiles {
|
||||||
@@ -122,35 +131,17 @@ const (
|
|||||||
InstallationReasonUnknown InstallationReason = "unknown"
|
InstallationReasonUnknown InstallationReason = "unknown"
|
||||||
)
|
)
|
||||||
|
|
||||||
func GetInstallationReason(pkg, rootDir string) InstallationReason {
|
func (localInfo PackageLocalInfo) GetInstallationReason() InstallationReason {
|
||||||
installedDir := path.Join(rootDir, "var/lib/bpm/installed/")
|
switch localInfo.InstallationReason {
|
||||||
pkgDir := path.Join(installedDir, pkg)
|
case "manual":
|
||||||
if stat, err := os.Stat(path.Join(pkgDir, "installation_reason")); err != nil || stat.IsDir() {
|
|
||||||
return InstallationReasonManual
|
return InstallationReasonManual
|
||||||
}
|
case "dependency":
|
||||||
b, err := os.ReadFile(path.Join(pkgDir, "installation_reason"))
|
return InstallationReasonDependency
|
||||||
if err != nil {
|
case "make_dependency":
|
||||||
|
return InstallationReasonMakeDependency
|
||||||
|
default:
|
||||||
return InstallationReasonUnknown
|
return InstallationReasonUnknown
|
||||||
}
|
}
|
||||||
reason := strings.TrimSpace(string(b))
|
|
||||||
if reason == "manual" {
|
|
||||||
return InstallationReasonManual
|
|
||||||
} else if reason == "dependency" {
|
|
||||||
return InstallationReasonDependency
|
|
||||||
} else if reason == "make_dependency" {
|
|
||||||
return InstallationReasonMakeDependency
|
|
||||||
}
|
|
||||||
return InstallationReasonUnknown
|
|
||||||
}
|
|
||||||
|
|
||||||
func SetInstallationReason(pkg string, reason InstallationReason, rootDir string) error {
|
|
||||||
installedDir := path.Join(rootDir, "var/lib/bpm/installed/")
|
|
||||||
pkgDir := path.Join(installedDir, pkg)
|
|
||||||
err := os.WriteFile(path.Join(pkgDir, "installation_reason"), []byte(reason), 0644)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetPackageInfoRaw(filename string) (string, error) {
|
func GetPackageInfoRaw(filename string) (string, error) {
|
||||||
@@ -540,59 +531,122 @@ func ReadPackageInfo(contents string) (*PackageInfo, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (pkgInfo *PackageInfo) CreateReadableInfo(rootDir string) string {
|
func (pkgInfo *PackageInfo) CreateReadableInfo(rootDir string) string {
|
||||||
ret := make([]string, 0)
|
builder := strings.Builder{}
|
||||||
appendArray := func(label string, array []string) {
|
builderWriteStringNotEmpty := func(label string, value string) {
|
||||||
|
if value != "" {
|
||||||
|
builder.WriteString(label + ": " + value + "\n")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
builderWriteArray := func(label string, array []string, sort bool) {
|
||||||
if len(array) == 0 {
|
if len(array) == 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = append(ret, fmt.Sprintf("%s: %s", label, strings.Join(array, ", ")))
|
// Sort array
|
||||||
|
if sort {
|
||||||
|
slices.Sort(array)
|
||||||
|
}
|
||||||
|
|
||||||
|
builder.WriteString(label + " (" + strconv.Itoa(len(array)) + "):\n")
|
||||||
|
for _, val := range array {
|
||||||
|
builder.WriteString(" - " + val + "\n")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
builderWriteDependencyArray := func(label string, depends []string) {
|
||||||
|
if len(depends) == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sort array
|
||||||
|
slices.Sort(depends)
|
||||||
|
|
||||||
|
builder.WriteString(label + " (" + strconv.Itoa(len(depends)) + "):\n")
|
||||||
|
for _, val := range depends {
|
||||||
|
builder.WriteString(" - " + val)
|
||||||
|
|
||||||
|
// Show virtual package providers
|
||||||
|
if providers := GetVirtualPackageInfo(val, rootDir); len(providers) > 0 {
|
||||||
|
builder.WriteString(" (")
|
||||||
|
for i, vpkg := range providers {
|
||||||
|
if i == len(providers)-1 {
|
||||||
|
builder.WriteString(vpkg.Name)
|
||||||
|
} else {
|
||||||
|
builder.WriteString(vpkg.Name + ", ")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
builder.WriteString(")")
|
||||||
|
}
|
||||||
|
|
||||||
|
builder.WriteString("\n")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = append(ret, "Name: "+pkgInfo.Name)
|
// Main information
|
||||||
ret = append(ret, "Description: "+pkgInfo.Description)
|
builder.WriteString("Name: " + pkgInfo.Name + "\n")
|
||||||
ret = append(ret, "Version: "+pkgInfo.GetFullVersion())
|
builder.WriteString("Description: " + pkgInfo.Description + "\n")
|
||||||
if pkgInfo.Url != "" {
|
builder.WriteString("Version: " + pkgInfo.GetFullVersion() + "\n")
|
||||||
ret = append(ret, "URL: "+pkgInfo.Url)
|
builderWriteStringNotEmpty("URL", pkgInfo.Url)
|
||||||
}
|
builderWriteStringNotEmpty("License", pkgInfo.License)
|
||||||
if pkgInfo.License != "" {
|
builderWriteArray("Maintainers", pkgInfo.Maintainers, false)
|
||||||
ret = append(ret, "License: "+pkgInfo.License)
|
builder.WriteString("Architecture: " + pkgInfo.Arch + "\n")
|
||||||
}
|
|
||||||
appendArray("Maintainers", pkgInfo.Maintainers)
|
|
||||||
ret = append(ret, "Architecture: "+pkgInfo.Arch)
|
|
||||||
if pkgInfo.Type == "source" && pkgInfo.OutputArch != "" && pkgInfo.OutputArch != GetArch() {
|
if pkgInfo.Type == "source" && pkgInfo.OutputArch != "" && pkgInfo.OutputArch != GetArch() {
|
||||||
ret = append(ret, "Output architecture: "+pkgInfo.Arch)
|
builder.WriteString("Output architecture: " + pkgInfo.OutputArch + "\n")
|
||||||
}
|
}
|
||||||
ret = append(ret, "Type: "+pkgInfo.Type)
|
builder.WriteString("Type: " + pkgInfo.Type + "\n")
|
||||||
appendArray("Dependencies", pkgInfo.Depends)
|
|
||||||
if pkgInfo.Type == "source" {
|
|
||||||
appendArray("Runtime Dependencies", pkgInfo.RuntimeDepends)
|
|
||||||
appendArray("Make Dependencies", pkgInfo.MakeDepends)
|
|
||||||
}
|
|
||||||
appendArray("Runtime dependencies", pkgInfo.RuntimeDepends)
|
|
||||||
appendArray("Optional dependencies", pkgInfo.OptionalDepends)
|
|
||||||
dependants := pkgInfo.GetPackageDependants(rootDir)
|
|
||||||
if len(dependants) > 0 {
|
|
||||||
appendArray("Dependant packages", dependants)
|
|
||||||
}
|
|
||||||
optionalDependants := pkgInfo.GetPackageOptionalDependants(rootDir)
|
|
||||||
if len(optionalDependants) > 0 {
|
|
||||||
appendArray("Optionally dependant packages", optionalDependants)
|
|
||||||
}
|
|
||||||
appendArray("Conflicting packages", pkgInfo.Conflicts)
|
|
||||||
appendArray("Provided packages", pkgInfo.Provides)
|
|
||||||
appendArray("Replaces packages", pkgInfo.Replaces)
|
|
||||||
|
|
||||||
|
// Dependencies
|
||||||
|
builderWriteDependencyArray("Dependencies", pkgInfo.Depends)
|
||||||
|
if pkgInfo.Type == "source" {
|
||||||
|
builderWriteDependencyArray("Make dependencies", pkgInfo.MakeDepends)
|
||||||
|
builderWriteDependencyArray("Check dependencies", pkgInfo.CheckDepends)
|
||||||
|
}
|
||||||
|
builderWriteDependencyArray("Runtime dependencies", pkgInfo.RuntimeDepends)
|
||||||
|
if len(pkgInfo.OptionalDepends) > 0 {
|
||||||
|
builder.WriteString("Optional dependencies (" + strconv.Itoa(len(pkgInfo.OptionalDepends)) + "):\n")
|
||||||
|
for _, depend := range pkgInfo.OptionalDepends {
|
||||||
|
dependSplit := strings.SplitN(depend, ":", 2)
|
||||||
|
if len(dependSplit) == 2 {
|
||||||
|
builder.WriteString(fmt.Sprintf(" - %s (%s)", dependSplit[0], dependSplit[1]))
|
||||||
|
} else {
|
||||||
|
builder.WriteString(" - " + dependSplit[0])
|
||||||
|
}
|
||||||
|
|
||||||
|
// Show virtual package providers
|
||||||
|
if providers := GetVirtualPackageInfo(dependSplit[0], rootDir); len(providers) > 0 {
|
||||||
|
builder.WriteString(" (")
|
||||||
|
for i, vpkg := range providers {
|
||||||
|
if i == len(providers)-1 {
|
||||||
|
builder.WriteString(vpkg.Name)
|
||||||
|
} else {
|
||||||
|
builder.WriteString(vpkg.Name + ", ")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
builder.WriteString(")")
|
||||||
|
}
|
||||||
|
|
||||||
|
builder.WriteString("\n")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
builderWriteArray("Dependant packages", pkgInfo.GetPackageDependants(rootDir), true)
|
||||||
|
builderWriteArray("Optionally dependant packages", pkgInfo.GetPackageOptionalDependants(rootDir), true)
|
||||||
|
|
||||||
|
// Other package relations
|
||||||
|
builderWriteArray("Conflicting packages", pkgInfo.Conflicts, true)
|
||||||
|
builderWriteArray("Provided packages", pkgInfo.Provides, true)
|
||||||
|
builderWriteArray("Replaces packages", pkgInfo.Replaces, true)
|
||||||
|
|
||||||
|
// Split packages
|
||||||
if pkgInfo.Type == "source" && len(pkgInfo.SplitPackages) != 0 {
|
if pkgInfo.Type == "source" && len(pkgInfo.SplitPackages) != 0 {
|
||||||
splitPkgs := make([]string, len(pkgInfo.SplitPackages))
|
splitPkgs := make([]string, len(pkgInfo.SplitPackages))
|
||||||
for i, splitPkgInfo := range pkgInfo.SplitPackages {
|
for i, splitPkgInfo := range pkgInfo.SplitPackages {
|
||||||
splitPkgs[i] = splitPkgInfo.Name
|
splitPkgs[i] = splitPkgInfo.Name
|
||||||
}
|
}
|
||||||
appendArray("Split Packages", splitPkgs)
|
builderWriteArray("Split packages", splitPkgs, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Installation reason
|
||||||
if rootDir != "" && IsPackageInstalled(pkgInfo.Name, rootDir) {
|
if rootDir != "" && IsPackageInstalled(pkgInfo.Name, rootDir) {
|
||||||
installationReason := GetInstallationReason(pkgInfo.Name, rootDir)
|
installationReason := GetPackage(pkgInfo.Name, rootDir).LocalInfo.GetInstallationReason()
|
||||||
var installationReasonString string
|
var installationReasonString string
|
||||||
switch installationReason {
|
switch installationReason {
|
||||||
case InstallationReasonManual:
|
case InstallationReasonManual:
|
||||||
@@ -604,10 +658,10 @@ func (pkgInfo *PackageInfo) CreateReadableInfo(rootDir string) string {
|
|||||||
default:
|
default:
|
||||||
installationReasonString = "Unknown"
|
installationReasonString = "Unknown"
|
||||||
}
|
}
|
||||||
ret = append(ret, "Installation Reason: "+installationReasonString)
|
builder.WriteString("Installation reason: " + installationReasonString + "\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
return strings.Join(ret, "\n")
|
return strings.TrimSpace(builder.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
func extractPackage(bpmpkg *BPMPackage, verbose bool, filename, rootDir string) error {
|
func extractPackage(bpmpkg *BPMPackage, verbose bool, filename, rootDir string) error {
|
||||||
@@ -771,7 +825,7 @@ func extractPackage(bpmpkg *BPMPackage, verbose bool, filename, rootDir string)
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func installPackage(filename, rootDir string, verbose, force bool) error {
|
func installPackage(filename string, installationReason InstallationReason, rootDir string, verbose, force bool) error {
|
||||||
if _, err := os.Stat(filename); os.IsNotExist(err) {
|
if _, err := os.Stat(filename); os.IsNotExist(err) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -955,6 +1009,16 @@ func installPackage(filename, rootDir string, verbose, force bool) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Write local package information
|
||||||
|
localInfo := getPackageLocalInfo(bpmpkg.PkgInfo.Name, rootDir)
|
||||||
|
if !packageInstalled {
|
||||||
|
localInfo.InstalledOn = time.Now().Unix()
|
||||||
|
}
|
||||||
|
localInfo.LastUpdatedOn = time.Now().Unix()
|
||||||
|
localInfo.InstallationReason = string(installationReason)
|
||||||
|
|
||||||
|
SetPackageLocalInfo(bpmpkg.PkgInfo.Name, localInfo, rootDir)
|
||||||
|
|
||||||
// Save remove package scripts
|
// Save remove package scripts
|
||||||
packageScripts, err := ReadPackageScripts(filename)
|
packageScripts, err := ReadPackageScripts(filename)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -994,8 +1058,16 @@ func installPackage(filename, rootDir string, verbose, force bool) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Write persistent data version number
|
||||||
|
if _, err := os.Stat(path.Join(rootDir, "var/lib/bpm/.version")); err != nil {
|
||||||
|
err = os.WriteFile(path.Join(rootDir, "var/lib/bpm/.version"), []byte(strconv.Itoa(persistentDataVersion)), 0644)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Ensure local package information has been initialized for rootDir
|
// Ensure local package information has been initialized for rootDir
|
||||||
err = initializeLocalPackageInformation(rootDir)
|
err = InitializeLocalPackageInformation(rootDir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -1115,7 +1187,7 @@ func removePackage(pkg string, verbose bool, rootDir string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Ensure local package information has been initialized for rootDir
|
// Ensure local package information has been initialized for rootDir
|
||||||
err = initializeLocalPackageInformation(rootDir)
|
err = InitializeLocalPackageInformation(rootDir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-4
@@ -19,14 +19,14 @@ type BPMLock struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func LockBPM(rootDir string) (*BPMLock, error) {
|
func LockBPM(rootDir string) (*BPMLock, error) {
|
||||||
// Create parent directories if they don't already exist
|
// Create cache directory if it doesn't already exist
|
||||||
err := os.MkdirAll(path.Join(rootDir, "/var/lib/bpm"), 0755)
|
err := os.MkdirAll(path.Join(rootDir, "/var/cache/bpm"), 0755)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create file
|
// Create file
|
||||||
f, err := os.Create(path.Join(rootDir, "var/lib/bpm/bpm.lock"))
|
f, err := os.Create(path.Join(rootDir, "var/cache/bpm/bpm.lock"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -37,7 +37,7 @@ func LockBPM(rootDir string) (*BPMLock, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return &BPMLock{f, path.Join(rootDir, "var/lib/bpm/bpm.lock")}, nil
|
return &BPMLock{f, path.Join(rootDir, "var/cache/bpm/bpm.lock")}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (lock *BPMLock) Unlock() error {
|
func (lock *BPMLock) Unlock() error {
|
||||||
|
|||||||
Reference in New Issue
Block a user