Compare commits

...

4 Commits

11 changed files with 286 additions and 234 deletions

View File

@ -30,7 +30,7 @@ You are able to install bpm packages by typing the following:
```sh
bpm install /path/to/package.bpm
```
You can also use the package name directly if using repositories
You can also use the package name directly if using databases
```sh
bpm install package_name
```
@ -50,7 +50,7 @@ To remove all unused dependencies and clean cached files try using the cleanup c
bpm cleanup
```
If using repositories, all packages can be updated using this simple command
If using databases, all packages can be updated using this simple command
```sh
bpm update
```

View File

@ -1,7 +1,8 @@
ignore_packages: []
privilege_escalator_cmd: "sudo"
compilation_env: []
repositories:
- name: example-repository
source: https://my-repo.xyz/
cleanup_make_dependencies: true
databases:
- name: example-database
source: https://my-database.xyz/
disabled: true

View File

@ -39,11 +39,12 @@ var installationReason = ""
var nosync = true
var removeUnused = false
var doCleanup = false
var showRepoInfo = false
var showDatabaseInfo = false
var installSrcPkgDepends = false
var skipChecks = false
var outputDirectory = ""
var cleanupDependencies = false
var cleanupMakeDependencies = false
var cleanupCompilationFiles = false
var cleanupCompiledPackages = false
var cleanupFetchedPackages = false
@ -116,7 +117,7 @@ func resolveCommand() {
}
// Read local databases
err := bpmlib.ReadLocalDatabases()
err := bpmlib.ReadLocalDatabaseFiles()
if err != nil {
log.Fatalf("Error: could not read local databases: %s", err)
}
@ -124,13 +125,14 @@ func resolveCommand() {
for n, pkg := range packages {
var info *bpmlib.PackageInfo
isFile := false
if showRepoInfo {
showInstallationReason := false
if showDatabaseInfo {
var err error
var entry *bpmlib.RepositoryEntry
entry, _, err = bpmlib.GetRepositoryEntry(pkg)
var entry *bpmlib.BPMDatabaseEntry
entry, _, err = bpmlib.GetDatabaseEntry(pkg)
if err != nil {
if entry = bpmlib.ResolveVirtualPackage(pkg); entry == nil {
log.Fatalf("Error: could not find package (%s) in any repository\n", pkg)
log.Fatalf("Error: could not find package (%s) in any database\n", pkg)
}
}
info = entry.Info
@ -147,6 +149,7 @@ func resolveCommand() {
} else {
info = bpmlib.GetPackageInfo(pkg, rootDir)
}
showInstallationReason = true
}
if info == nil {
log.Fatalf("Error: package (%s) is not installed\n", pkg)
@ -161,11 +164,11 @@ func resolveCommand() {
}
fmt.Println("File: " + abs)
}
fmt.Println(bpmlib.CreateReadableInfo(true, true, true, info, rootDir))
fmt.Println(bpmlib.CreateReadableInfo(true, true, true, showInstallationReason, info, rootDir))
}
case list:
// Read local databases
err := bpmlib.ReadLocalDatabases()
err := bpmlib.ReadLocalDatabaseFiles()
if err != nil {
log.Fatalf("Error: could not read local databases: %s", err)
}
@ -195,7 +198,7 @@ func resolveCommand() {
if n != 0 {
fmt.Println()
}
fmt.Println(bpmlib.CreateReadableInfo(true, true, true, info, rootDir))
fmt.Println(bpmlib.CreateReadableInfo(true, true, true, true, info, rootDir))
}
}
case search:
@ -205,7 +208,7 @@ func resolveCommand() {
}
// Read local databases
err := bpmlib.ReadLocalDatabases()
err := bpmlib.ReadLocalDatabaseFiles()
if err != nil {
log.Fatalf("Error: could not read local databases: %s", err)
}
@ -213,8 +216,8 @@ func resolveCommand() {
for i, term := range searchTerms {
nameResults := make([]*bpmlib.PackageInfo, 0)
descResults := make([]*bpmlib.PackageInfo, 0)
for _, repo := range bpmlib.BPMConfig.Repositories {
for _, entry := range repo.Entries {
for _, db := range bpmlib.BPMConfig.Databases {
for _, entry := range db.Entries {
if strings.Contains(entry.Info.Name, term) {
nameResults = append(nameResults, entry.Info)
} else if strings.Contains(entry.Info.Description, term) {
@ -247,12 +250,14 @@ func resolveCommand() {
}
// Check if installationReason argument is valid
ir := bpmlib.InstallationReasonUnknown
ir := bpmlib.InstallationReasonManual
switch installationReason {
case "manual":
ir = bpmlib.InstallationReasonManual
case "dependency":
ir = bpmlib.InstallationReasonDependency
case "make-dependency":
ir = bpmlib.InstallationReasonMakeDependency
case "":
default:
log.Fatalf("Error: %s is not a valid installation reason", installationReason)
@ -269,7 +274,7 @@ func resolveCommand() {
}
// Read local databases
err := bpmlib.ReadLocalDatabases()
err := bpmlib.ReadLocalDatabaseFiles()
if err != nil {
log.Fatalf("Error: could not read local databases: %s", err)
}
@ -327,7 +332,7 @@ func resolveCommand() {
// Read local databases if no sync
if nosync {
err := bpmlib.ReadLocalDatabases()
err := bpmlib.ReadLocalDatabaseFiles()
if err != nil {
log.Fatalf("Error: could not read local databases: %s", err)
}
@ -409,7 +414,7 @@ func resolveCommand() {
}
// Read local databases
err := bpmlib.ReadLocalDatabases()
err := bpmlib.ReadLocalDatabaseFiles()
if err != nil {
log.Fatalf("Error: could not read local databases: %s", err)
}
@ -465,15 +470,15 @@ func resolveCommand() {
log.Fatalf("Error: could not complete cache cleanup: %s", err)
}
if cleanupDependencies {
if cleanupDependencies || cleanupMakeDependencies {
// Read local databases
err := bpmlib.ReadLocalDatabases()
err := bpmlib.ReadLocalDatabaseFiles()
if err != nil {
log.Fatalf("Error: could not read local databases: %s", err)
}
// Create cleanup operation
operation, err := bpmlib.CleanupPackages(rootDir)
operation, err := bpmlib.CleanupPackages(cleanupMakeDependencies, rootDir)
if errors.As(err, &bpmlib.PackageNotFoundErr{}) || errors.As(err, &bpmlib.DependencyNotFoundErr{}) || errors.As(err, &bpmlib.PackageConflictErr{}) {
log.Fatalf("Error: %s", err)
} else if err != nil {
@ -569,7 +574,7 @@ func resolveCommand() {
}
// Read local databases
err := bpmlib.ReadLocalDatabases()
err := bpmlib.ReadLocalDatabaseFiles()
if err != nil {
log.Fatalf("Error: could not read local databases: %s", err)
}
@ -593,7 +598,7 @@ func resolveCommand() {
// Get direct runtime and make dependencies
totalDepends := make([]string, 0)
for _, depend := range bpmpkg.PkgInfo.GetDependencies(true, false) {
for depend := range bpmpkg.PkgInfo.GetDependencies(true, false) {
if !slices.Contains(totalDepends, depend) {
totalDepends = append(totalDepends, depend)
}
@ -622,7 +627,7 @@ func resolveCommand() {
}
// Run 'bpm install' using the set privilege escalator command
args := []string{executable, "install", "--installation-reason=dependency"}
args := []string{executable, "install", "--installation-reason=make-dependency"}
args = append(args, unmetDepends...)
cmd := exec.Command(bpmlib.BPMConfig.PrivilegeEscalatorCmd, args...)
if yesAll {
@ -641,7 +646,7 @@ func resolveCommand() {
} else {
// Ensure the required dependencies are installed
if len(unmetDepends) != 0 {
log.Fatalf("Error: could not resolve dependencies: the following dependencies were not found in any repositories: " + strings.Join(unmetDepends, ", "))
log.Fatalf("Error: could not resolve dependencies: the following dependencies were not found in any databases: " + strings.Join(unmetDepends, ", "))
}
}
@ -736,14 +741,14 @@ func printHelp() {
fmt.Println("-> flags will be read if passed right after the subcommand otherwise they will be read as subcommand arguments")
fmt.Println("\033[1m---- Command List ----\033[0m")
fmt.Println("-> bpm version | shows information on the installed version of bpm")
fmt.Println("-> bpm info [-R, --repos] <packages...> | shows information on an installed package")
fmt.Println("-> bpm info [-R, --databases] <packages...> | shows information on an installed package")
fmt.Println(" -R=<path> lets you define the root path which will be used")
fmt.Println(" --repos show information on package in repository")
fmt.Println(" --databases show information on package in configured databases")
fmt.Println("-> bpm list [-R, -c, -n] | lists all installed packages")
fmt.Println(" -R=<path> lets you define the root path which will be used")
fmt.Println(" -c lists the amount of installed packages")
fmt.Println(" -n lists only the names of installed packages")
fmt.Println("-> bpm search <search terms...> | Searches for packages through declared repositories")
fmt.Println("-> bpm search <search terms...> | Searches for packages through configured databases")
fmt.Println("-> bpm install [-R, -v, -y, -f, --reinstall, --reinstall-all, --no-optional, --installation-reason] <packages...> | installs the following files")
fmt.Println(" -R=<path> lets you define the root path which will be used")
fmt.Println(" -v Show additional information about what BPM is doing")
@ -753,7 +758,7 @@ func printHelp() {
fmt.Println(" --reinstall-all Same as --reinstall but also reinstalls dependencies")
fmt.Println(" --no-optional Prevents installation of optional dependencies")
fmt.Println(" --installation-reason=<manual/dependency> sets the installation reason for all newly installed packages")
fmt.Println("-> bpm update [-R, -v, -y, -f, --reinstall, --no-sync] | updates all packages that are available in the repositories")
fmt.Println("-> bpm update [-R, -v, -y, -f, --reinstall, --no-sync] | updates all packages that are available in the configured databases")
fmt.Println(" -R=<path> lets you define the root path which will be used")
fmt.Println(" -v Show additional information about what BPM is doing")
fmt.Println(" -y skips the confirmation prompt")
@ -775,9 +780,10 @@ func printHelp() {
fmt.Println(" -R=<path> lets you define the root path which will be used")
fmt.Println(" -y skips the confirmation prompt")
fmt.Println(" --depends performs a dependency cleanup")
fmt.Println(" --make-depends performs a make dependency cleanup")
fmt.Println(" --compilation-files performs a cleanup of compilation files")
fmt.Println(" --compiled-pkgs performs a cleanup of compilation compiled binary packages")
fmt.Println(" --fetched-pkgs performs a cleanup of fetched packages from repositories")
fmt.Println(" --fetched-pkgs performs a cleanup of fetched packages from databases")
fmt.Println("-> bpm file [-R] <files...> | shows what packages the following packages are managed by")
fmt.Println(" -R=<root_path> lets you define the root path which will be used")
fmt.Println("-> bpm compile [-d, -s, -o] <source packages...> | Compile source BPM package")
@ -800,7 +806,7 @@ func resolveFlags() {
// Info flags
infoFlagSet := flag.NewFlagSet("Info flags", flag.ExitOnError)
infoFlagSet.StringVar(&rootDir, "R", "/", "Set the destination root")
infoFlagSet.BoolVar(&showRepoInfo, "repos", false, "Show information on package in repository")
infoFlagSet.BoolVar(&showDatabaseInfo, "databases", false, "Show information on package in configured databases")
infoFlagSet.Usage = printHelp
// Install flags
installFlagSet := flag.NewFlagSet("Install flags", flag.ExitOnError)
@ -841,9 +847,10 @@ func resolveFlags() {
cleanupFlagSet.BoolVar(&verbose, "v", false, "Show additional information about what BPM is doing")
cleanupFlagSet.BoolVar(&yesAll, "y", false, "Skip confirmation prompts")
cleanupFlagSet.BoolVar(&cleanupDependencies, "depends", false, "Perform a dependency cleanup")
cleanupFlagSet.BoolVar(&cleanupMakeDependencies, "make-depends", false, "Perform a make dependency cleanup")
cleanupFlagSet.BoolVar(&cleanupCompilationFiles, "compilation-files", false, "Perform a cleanup of compilation files")
cleanupFlagSet.BoolVar(&cleanupCompiledPackages, "compiled-pkgs", false, "Perform a cleanup of compilation compiled binary packages")
cleanupFlagSet.BoolVar(&cleanupFetchedPackages, "fetched-pkgs", false, "Perform a cleanup of fetched packages from repositories")
cleanupFlagSet.BoolVar(&cleanupFetchedPackages, "fetched-pkgs", false, "Perform a cleanup of fetched packages from databases")
cleanupFlagSet.Usage = printHelp
// File flags
fileFlagSet := flag.NewFlagSet("Remove flags", flag.ExitOnError)
@ -856,8 +863,18 @@ func resolveFlags() {
compileFlagSet.StringVar(&outputDirectory, "o", "", "Set output directory")
compileFlagSet.BoolVar(&verbose, "v", false, "Show additional information about what BPM is doing")
compileFlagSet.BoolVar(&yesAll, "y", false, "Skip confirmation prompts")
compileFlagSet.Usage = printHelp
isFlagSet := func(flagSet *flag.FlagSet, name string) bool {
found := false
flagSet.Visit(func(f *flag.Flag) {
if f.Name == name {
found = true
}
})
return found
}
if len(os.Args[1:]) <= 0 {
subcommand = "help"
} else {
@ -904,8 +921,9 @@ func resolveFlags() {
if err != nil {
return
}
if !cleanupDependencies && !cleanupCompilationFiles && !cleanupCompiledPackages && !cleanupFetchedPackages {
if !isFlagSet(cleanupFlagSet, "depends") && !isFlagSet(cleanupFlagSet, "make-depends") && !isFlagSet(cleanupFlagSet, "compilation-files") && !isFlagSet(cleanupFlagSet, "compiled-pkgs") && !isFlagSet(cleanupFlagSet, "fetched-pkgs") {
cleanupDependencies = true
cleanupMakeDependencies = bpmlib.BPMConfig.CleanupMakeDependencies
cleanupCompilationFiles = true
cleanupCompiledPackages = true
cleanupFetchedPackages = true

View File

@ -264,8 +264,7 @@ func CompileSourcePackage(archiveFilename, outputDirectory string, skipChecks bo
pkgInfo.Arch = GetArch()
}
// Remove source package specific fields
pkgInfo.MakeDepends = nil
// Remove split package field
pkgInfo.SplitPackages = nil
// Marshal package info

View File

@ -6,10 +6,11 @@ import (
)
type BPMConfigStruct struct {
IgnorePackages []string `yaml:"ignore_packages"`
PrivilegeEscalatorCmd string `yaml:"privilege_escalator_cmd"`
CompilationEnvironment []string `yaml:"compilation_env"`
Repositories []*Repository `yaml:"repositories"`
IgnorePackages []string `yaml:"ignore_packages"`
PrivilegeEscalatorCmd string `yaml:"privilege_escalator_cmd"`
CompilationEnvironment []string `yaml:"compilation_env"`
CleanupMakeDependencies bool `yaml:"cleanup_make_dependencies"`
Databases []*BPMDatabase `yaml:"databases"`
}
var BPMConfig BPMConfigStruct
@ -24,15 +25,17 @@ func ReadConfig() (err error) {
return err
}
BPMConfig = BPMConfigStruct{}
BPMConfig = BPMConfigStruct{
CleanupMakeDependencies: true,
}
err = yaml.Unmarshal(bytes, &BPMConfig)
if err != nil {
return err
}
for i := len(BPMConfig.Repositories) - 1; i >= 0; i-- {
if BPMConfig.Repositories[i].Disabled != nil && *BPMConfig.Repositories[i].Disabled {
BPMConfig.Repositories = append(BPMConfig.Repositories[:i], BPMConfig.Repositories[i+1:]...)
for i := len(BPMConfig.Databases) - 1; i >= 0; i-- {
if BPMConfig.Databases[i].Disabled != nil && *BPMConfig.Databases[i].Disabled {
BPMConfig.Databases = append(BPMConfig.Databases[:i], BPMConfig.Databases[i+1:]...)
}
}

View File

@ -12,41 +12,41 @@ import (
"strings"
)
type Repository struct {
type BPMDatabase struct {
Name string `yaml:"name"`
Source string `yaml:"source"`
Disabled *bool `yaml:"disabled"`
Entries map[string]*RepositoryEntry
Entries map[string]*BPMDatabaseEntry
VirtualPackages map[string][]string
}
type RepositoryEntry struct {
type BPMDatabaseEntry struct {
Info *PackageInfo `yaml:"info"`
Download string `yaml:"download"`
DownloadSize uint64 `yaml:"download_size"`
InstalledSize uint64 `yaml:"installed_size"`
Repository *Repository
Database *BPMDatabase
}
func (repo *Repository) ContainsPackage(pkg string) bool {
_, ok := repo.Entries[pkg]
func (db *BPMDatabase) ContainsPackage(pkg string) bool {
_, ok := db.Entries[pkg]
return ok
}
func (repo *Repository) ReadLocalDatabase() error {
repoFile := "/var/lib/bpm/repositories/" + repo.Name + ".bpmdb"
if _, err := os.Stat(repoFile); err != nil {
func (db *BPMDatabase) ReadLocalDatabase() error {
dbFile := "/var/lib/bpm/databases/" + db.Name + ".bpmdb"
if _, err := os.Stat(dbFile); err != nil {
return nil
}
bytes, err := os.ReadFile(repoFile)
bytes, err := os.ReadFile(dbFile)
if err != nil {
return err
}
data := string(bytes)
for _, b := range strings.Split(data, "---") {
entry := RepositoryEntry{
entry := BPMDatabaseEntry{
Info: &PackageInfo{
Name: "",
Description: "",
@ -66,14 +66,14 @@ func (repo *Repository) ReadLocalDatabase() error {
Download: "",
DownloadSize: 0,
InstalledSize: 0,
Repository: repo,
Database: db,
}
err := yaml.Unmarshal([]byte(b), &entry)
if err != nil {
return err
}
// Create repository entries
// Create database entries
if entry.Info.IsSplitPackage() {
for _, splitPkg := range entry.Info.SplitPackages {
// Turn split package into json data
@ -100,26 +100,26 @@ func (repo *Repository) ReadLocalDatabase() error {
splitPkgClone.Url = entry.Info.Url
// Create entry for split package
repo.Entries[splitPkg.Name] = &RepositoryEntry{
db.Entries[splitPkg.Name] = &BPMDatabaseEntry{
Info: &splitPkgClone,
Download: entry.Download,
DownloadSize: entry.DownloadSize,
InstalledSize: 0,
Repository: repo,
Database: db,
}
// Add virtual packages to repository
// Add virtual packages to database
for _, p := range splitPkg.Provides {
repo.VirtualPackages[p] = append(repo.VirtualPackages[p], splitPkg.Name)
db.VirtualPackages[p] = append(db.VirtualPackages[p], splitPkg.Name)
}
}
} else {
// Create entry for package
repo.Entries[entry.Info.Name] = &entry
db.Entries[entry.Info.Name] = &entry
// Add virtual packages to repository
// Add virtual packages to database
for _, p := range entry.Info.Provides {
repo.VirtualPackages[p] = append(repo.VirtualPackages[p], entry.Info.Name)
db.VirtualPackages[p] = append(db.VirtualPackages[p], entry.Info.Name)
}
}
@ -128,11 +128,11 @@ func (repo *Repository) ReadLocalDatabase() error {
return nil
}
func (repo *Repository) SyncLocalDatabase() error {
repoFile := "/var/lib/bpm/repositories/" + repo.Name + ".bpmdb"
func (db *BPMDatabase) SyncLocalDatabaseFile() error {
dbFile := "/var/lib/bpm/databases/" + db.Name + ".bpmdb"
// Get URL to database
u, err := url.JoinPath(repo.Source, "database.bpmdb")
u, err := url.JoinPath(db.Source, "database.bpmdb")
if err != nil {
return err
}
@ -147,20 +147,20 @@ func (repo *Repository) SyncLocalDatabase() error {
// Load data into byte buffer
buffer, err := io.ReadAll(resp.Body)
// Unmarshal data to ensure it is a valid BPM repository
err = yaml.Unmarshal(buffer, &Repository{})
// Unmarshal data to ensure it is a valid BPM database
err = yaml.Unmarshal(buffer, &BPMDatabase{})
if err != nil {
return fmt.Errorf("could not decode repository: %s", err)
return fmt.Errorf("could not decode database: %s", err)
}
// Create parent directories to repository file
err = os.MkdirAll(path.Dir(repoFile), 0755)
// Create parent directories to database file
err = os.MkdirAll(path.Dir(dbFile), 0755)
if err != nil {
return err
}
// Create file and save repository data
out, err := os.Create(repoFile)
// Create file and save database data
out, err := os.Create(dbFile)
if err != nil {
return err
}
@ -171,14 +171,14 @@ func (repo *Repository) SyncLocalDatabase() error {
return nil
}
func ReadLocalDatabases() (err error) {
for _, repo := range BPMConfig.Repositories {
func ReadLocalDatabaseFiles() (err error) {
for _, db := range BPMConfig.Databases {
// Initialize struct values
repo.Entries = make(map[string]*RepositoryEntry)
repo.VirtualPackages = make(map[string][]string)
db.Entries = make(map[string]*BPMDatabaseEntry)
db.VirtualPackages = make(map[string][]string)
// Read database
err = repo.ReadLocalDatabase()
err = db.ReadLocalDatabase()
if err != nil {
return err
}
@ -187,47 +187,47 @@ func ReadLocalDatabases() (err error) {
return nil
}
func GetRepository(name string) *Repository {
for _, repo := range BPMConfig.Repositories {
if repo.Name == name {
return repo
func GetDatabase(name string) *BPMDatabase {
for _, db := range BPMConfig.Databases {
if db.Name == name {
return db
}
}
return nil
}
func GetRepositoryEntry(str string) (*RepositoryEntry, *Repository, error) {
func GetDatabaseEntry(str string) (*BPMDatabaseEntry, *BPMDatabase, error) {
split := strings.Split(str, "/")
if len(split) == 1 {
pkgName := strings.TrimSpace(split[0])
if pkgName == "" {
return nil, nil, errors.New("could not find repository entry for this package")
return nil, nil, errors.New("could not find database entry for this package")
}
for _, repo := range BPMConfig.Repositories {
if repo.ContainsPackage(pkgName) {
return repo.Entries[pkgName], repo, nil
for _, db := range BPMConfig.Databases {
if db.ContainsPackage(pkgName) {
return db.Entries[pkgName], db, nil
}
}
return nil, nil, errors.New("could not find repository entry for this package")
return nil, nil, errors.New("could not find database entry for this package")
} else if len(split) == 2 {
repoName := strings.TrimSpace(split[0])
dbName := strings.TrimSpace(split[0])
pkgName := strings.TrimSpace(split[1])
if repoName == "" || pkgName == "" {
return nil, nil, errors.New("could not find repository entry for this package")
if dbName == "" || pkgName == "" {
return nil, nil, errors.New("could not find database entry for this package")
}
repo := GetRepository(repoName)
if repo == nil || !repo.ContainsPackage(pkgName) {
return nil, nil, errors.New("could not find repository entry for this package")
db := GetDatabase(dbName)
if db == nil || !db.ContainsPackage(pkgName) {
return nil, nil, errors.New("could not find database entry for this package")
}
return repo.Entries[pkgName], repo, nil
return db.Entries[pkgName], db, nil
} else {
return nil, nil, errors.New("could not find repository entry for this package")
return nil, nil, errors.New("could not find database entry for this package")
}
}
func FindReplacement(pkg string) *RepositoryEntry {
for _, repo := range BPMConfig.Repositories {
for _, entry := range repo.Entries {
func FindReplacement(pkg string) *BPMDatabaseEntry {
for _, db := range BPMConfig.Databases {
for _, entry := range db.Entries {
for _, replaced := range entry.Info.Replaces {
if replaced == pkg {
return entry
@ -239,11 +239,11 @@ func FindReplacement(pkg string) *RepositoryEntry {
return nil
}
func ResolveVirtualPackage(vpkg string) *RepositoryEntry {
for _, repo := range BPMConfig.Repositories {
if v, ok := repo.VirtualPackages[vpkg]; ok {
func ResolveVirtualPackage(vpkg string) *BPMDatabaseEntry {
for _, db := range BPMConfig.Databases {
if v, ok := db.VirtualPackages[vpkg]; ok {
for _, pkg := range v {
return repo.Entries[pkg]
return db.Entries[pkg]
}
}
}
@ -251,12 +251,12 @@ func ResolveVirtualPackage(vpkg string) *RepositoryEntry {
return nil
}
func (repo *Repository) FetchPackage(pkg string) (string, error) {
if !repo.ContainsPackage(pkg) {
func (db *BPMDatabase) FetchPackage(pkg string) (string, error) {
if !db.ContainsPackage(pkg) {
return "", errors.New("could not fetch package '" + pkg + "'")
}
entry := repo.Entries[pkg]
URL, err := url.JoinPath(repo.Source, entry.Download)
entry := db.Entries[pkg]
URL, err := url.JoinPath(db.Source, entry.Download)
if err != nil {
return "", err
}

View File

@ -6,14 +6,25 @@ import (
"slices"
)
func (pkgInfo *PackageInfo) GetDependencies(includeMakeDepends, includeOptionalDepends bool) []string {
allDepends := make([]string, 0)
allDepends = append(allDepends, pkgInfo.Depends...)
if includeMakeDepends {
allDepends = append(allDepends, pkgInfo.MakeDepends...)
func (pkgInfo *PackageInfo) GetDependencies(includeMakeDepends, includeOptionalDepends bool) map[string]InstallationReason {
allDepends := make(map[string]InstallationReason)
for _, depend := range pkgInfo.Depends {
allDepends[depend] = InstallationReasonDependency
}
if includeOptionalDepends {
allDepends = append(allDepends, pkgInfo.OptionalDepends...)
for _, depend := range pkgInfo.OptionalDepends {
if _, ok := allDepends[depend]; !ok {
allDepends[depend] = InstallationReasonDependency
}
}
}
if includeMakeDepends {
for _, depend := range pkgInfo.MakeDepends {
if _, ok := allDepends[depend]; !ok {
allDepends[depend] = InstallationReasonMakeDependency
}
}
}
return allDepends
}
@ -34,7 +45,10 @@ func (pkgInfo *PackageInfo) getAllDependencies(resolved *[]string, unresolved *[
*unresolved = append(*unresolved, pkgInfo.Name)
// Loop through all dependencies
for _, depend := range pkgInfo.GetDependencies(includeMakeDepends, includeOptionalDepends) {
for depend := range pkgInfo.GetDependencies(includeMakeDepends, includeOptionalDepends) {
if isVirtual, p := IsVirtualPackage(depend, rootDir); isVirtual {
depend = p
}
if !slices.Contains(*resolved, depend) {
// Add current dependency to resolved slice when circular dependency is detected
if slices.Contains(*unresolved, depend) {
@ -44,13 +58,7 @@ func (pkgInfo *PackageInfo) getAllDependencies(resolved *[]string, unresolved *[
continue
}
var dependInfo *PackageInfo
if isVirtual, p := IsVirtualPackage(depend, rootDir); isVirtual {
dependInfo = GetPackageInfo(p, rootDir)
} else {
dependInfo = GetPackageInfo(depend, rootDir)
}
dependInfo := GetPackageInfo(depend, rootDir)
if dependInfo != nil {
dependInfo.getAllDependencies(resolved, unresolved, includeMakeDepends, includeOptionalDepends, rootDir)
@ -63,39 +71,39 @@ func (pkgInfo *PackageInfo) getAllDependencies(resolved *[]string, unresolved *[
*unresolved = stringSliceRemove(*unresolved, pkgInfo.Name)
}
func ResolvePackageDependenciesFromDatabases(pkgInfo *PackageInfo, checkMake, checkOptional, ignoreInstalled, verbose bool, rootDir string) (resolved []string, unresolved []string) {
func ResolveAllPackageDependenciesFromDatabases(pkgInfo *PackageInfo, checkMake, checkOptional, ignoreInstalled, verbose bool, rootDir string) (resolved map[string]InstallationReason, unresolved []string) {
// Initialize slices
resolved = make([]string, 0)
resolved = make(map[string]InstallationReason)
unresolved = make([]string, 0)
// Call unexported function
resolvePackageDependenciesFromDatabase(&resolved, &unresolved, pkgInfo, checkMake, checkOptional, ignoreInstalled, verbose, rootDir)
resolvePackageDependenciesFromDatabase(resolved, &unresolved, pkgInfo, InstallationReasonDependency, checkMake, checkOptional, ignoreInstalled, verbose, rootDir)
return resolved, unresolved
}
func resolvePackageDependenciesFromDatabase(resolved, unresolved *[]string, pkgInfo *PackageInfo, checkMake, checkOptional, ignoreInstalled, verbose bool, rootDir string) {
func resolvePackageDependenciesFromDatabase(resolved map[string]InstallationReason, unresolved *[]string, pkgInfo *PackageInfo, installationReason InstallationReason, checkMake, checkOptional, ignoreInstalled, verbose bool, rootDir string) {
// Add current package name to unresolved slice
*unresolved = append(*unresolved, pkgInfo.Name)
// Loop through all dependencies
for _, depend := range pkgInfo.GetDependencies(checkMake, checkOptional) {
if !slices.Contains(*resolved, depend) {
for depend, ir := range pkgInfo.GetDependencies(pkgInfo.Type == "source", checkOptional) {
if _, ok := resolved[depend]; !ok {
// Add current dependency to resolved slice when circular dependency is detected
if slices.Contains(*unresolved, depend) {
if verbose {
fmt.Printf("Circular dependency was detected (%s -> %s). Installing %s first\n", pkgInfo.Name, depend, depend)
}
if !slices.Contains(*resolved, depend) {
*resolved = append(*resolved, depend)
if _, ok := resolved[depend]; !ok {
resolved[depend] = ir
}
continue
} else if ignoreInstalled && IsPackageProvided(depend, rootDir) {
continue
}
var err error
var entry *RepositoryEntry
entry, _, err = GetRepositoryEntry(depend)
var entry *BPMDatabaseEntry
entry, _, err = GetDatabaseEntry(depend)
if err != nil {
if entry = ResolveVirtualPackage(depend); entry == nil {
if !slices.Contains(*unresolved, depend) {
@ -104,11 +112,12 @@ func resolvePackageDependenciesFromDatabase(resolved, unresolved *[]string, pkgI
continue
}
}
resolvePackageDependenciesFromDatabase(resolved, unresolved, entry.Info, checkMake, checkOptional, ignoreInstalled, verbose, rootDir)
resolvePackageDependenciesFromDatabase(resolved, unresolved, entry.Info, ir, checkMake, checkOptional, ignoreInstalled, verbose, rootDir)
}
}
if !slices.Contains(*resolved, pkgInfo.Name) {
*resolved = append(*resolved, pkgInfo.Name)
if _, ok := resolved[pkgInfo.Name]; !ok {
resolved[pkgInfo.Name] = installationReason
}
*unresolved = stringSliceRemove(*unresolved, pkgInfo.Name)
}
@ -145,7 +154,7 @@ func GetPackageDependants(pkgName string, rootDir string) ([]string, error) {
dependencies := installedPkg.PkgInfo.GetDependencies(false, true)
// Add installed package to list if its dependencies include pkgName
if slices.Contains(dependencies, pkgName) {
if _, ok := dependencies[pkgName]; ok {
ret = append(ret, installedPkgName)
continue
}
@ -153,7 +162,7 @@ func GetPackageDependants(pkgName string, rootDir string) ([]string, error) {
// Loop through each virtual package
for _, vpkg := range pkg.PkgInfo.Provides {
// Add installed package to list if its dependencies contain a provided virtual package
if slices.Contains(dependencies, vpkg) {
if _, ok := dependencies[vpkg]; ok {
ret = append(ret, installedPkgName)
break
}

View File

@ -10,7 +10,7 @@ type PackageNotFoundErr struct {
}
func (e PackageNotFoundErr) Error() string {
return "The following packages were not found in any repositories: " + strings.Join(e.packages, ", ")
return "The following packages were not found in any databases: " + strings.Join(e.packages, ", ")
}
type DependencyNotFoundErr struct {
@ -18,7 +18,7 @@ type DependencyNotFoundErr struct {
}
func (e DependencyNotFoundErr) Error() string {
return "The following dependencies were not found in any repositories: " + strings.Join(e.dependencies, ", ")
return "The following dependencies were not found in any databases: " + strings.Join(e.dependencies, ", ")
}
type PackageConflictErr struct {

View File

@ -17,16 +17,15 @@ const (
ReinstallMethodAll ReinstallMethod = iota
)
// InstallPackages installs the specified packages into the given root directory by fetching them from repositories 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, installationReason InstallationReason, reinstallMethod ReinstallMethod, installOptionalDependencies, forceInstallation, verbose bool, packages ...string) (operation *BPMOperation, err error) {
// Setup operation struct
operation = &BPMOperation{
Actions: make([]OperationAction, 0),
UnresolvedDepends: make([]string, 0),
Changes: make(map[string]string),
RootDir: rootDir,
ForceInstallationReason: installationReason,
compiledPackages: make(map[string]string),
Actions: make([]OperationAction, 0),
UnresolvedDepends: make([]string, 0),
Changes: make(map[string]string),
RootDir: rootDir,
compiledPackages: make(map[string]string),
}
// Resolve packages
@ -46,7 +45,7 @@ func InstallPackages(rootDir string, installationReason InstallationReason, rein
operation.AppendAction(&InstallPackageAction{
File: pkg,
IsDependency: false,
InstallationReason: installationReason,
BpmPackage: bpmpkg,
SplitPackageToInstall: splitPkg.Name,
})
@ -59,17 +58,17 @@ func InstallPackages(rootDir string, installationReason InstallationReason, rein
}
operation.AppendAction(&InstallPackageAction{
File: pkg,
IsDependency: false,
BpmPackage: bpmpkg,
File: pkg,
InstallationReason: installationReason,
BpmPackage: bpmpkg,
})
} else {
var entry *RepositoryEntry
var entry *BPMDatabaseEntry
if e, _, err := GetRepositoryEntry(pkg); err == nil {
if e, _, err := GetDatabaseEntry(pkg); err == nil {
entry = e
} else if isVirtual, p := IsVirtualPackage(pkg, rootDir); isVirtual {
entry, _, err = GetRepositoryEntry(p)
entry, _, err = GetDatabaseEntry(p)
if err != nil {
pkgsNotFound = append(pkgsNotFound, pkg)
continue
@ -85,8 +84,8 @@ func InstallPackages(rootDir string, installationReason InstallationReason, rein
}
operation.AppendAction(&FetchPackageAction{
IsDependency: false,
RepositoryEntry: entry,
InstallationReason: installationReason,
DatabaseEntry: entry,
})
}
}
@ -161,7 +160,7 @@ func RemovePackages(rootDir string, removeUnusedPackagesOnly, cleanupDependencie
// Do package cleanup
if cleanupDependencies {
err := operation.Cleanup()
err := operation.Cleanup(true)
if err != nil {
return nil, fmt.Errorf("could not perform cleanup for operation: %s", err)
}
@ -170,7 +169,7 @@ func RemovePackages(rootDir string, removeUnusedPackagesOnly, cleanupDependencie
}
// CleanupPackages finds packages installed as dependencies which are no longer required by the rest of the system in the given root directory
func CleanupPackages(rootDir string) (operation *BPMOperation, err error) {
func CleanupPackages(cleanupMakeDepends bool, rootDir string) (operation *BPMOperation, err error) {
operation = &BPMOperation{
Actions: make([]OperationAction, 0),
UnresolvedDepends: make([]string, 0),
@ -180,7 +179,7 @@ func CleanupPackages(rootDir string) (operation *BPMOperation, err error) {
}
// Do package cleanup
err = operation.Cleanup()
err = operation.Cleanup(cleanupMakeDepends)
if err != nil {
return nil, fmt.Errorf("could not perform cleanup for operation: %s", err)
}
@ -272,7 +271,7 @@ func CleanupCache(rootDir string, cleanupCompilationFiles, cleanupCompiledPackag
// UpdatePackages fetches the newest versions of all installed packages from
func UpdatePackages(rootDir string, syncDatabase bool, installOptionalDependencies, forceInstallation, verbose bool) (operation *BPMOperation, err error) {
// Sync repositories
// Sync databases
if syncDatabase {
err := SyncDatabase(verbose)
if err != nil {
@ -287,7 +286,7 @@ func UpdatePackages(rootDir string, syncDatabase bool, installOptionalDependenci
if err != nil {
return nil, fmt.Errorf("could not read BPM config: %s", err)
}
err = ReadLocalDatabases()
err = ReadLocalDatabaseFiles()
if err != nil {
return nil, fmt.Errorf("could not read local databases: %s", err)
}
@ -300,12 +299,11 @@ func UpdatePackages(rootDir string, syncDatabase bool, installOptionalDependenci
}
operation = &BPMOperation{
Actions: make([]OperationAction, 0),
UnresolvedDepends: make([]string, 0),
Changes: make(map[string]string),
RootDir: rootDir,
ForceInstallationReason: InstallationReasonUnknown,
compiledPackages: make(map[string]string),
Actions: make([]OperationAction, 0),
UnresolvedDepends: make([]string, 0),
Changes: make(map[string]string),
RootDir: rootDir,
compiledPackages: make(map[string]string),
}
// Search for packages
@ -313,11 +311,11 @@ func UpdatePackages(rootDir string, syncDatabase bool, installOptionalDependenci
if slices.Contains(BPMConfig.IgnorePackages, pkg) {
continue
}
var entry *RepositoryEntry
var entry *BPMDatabaseEntry
// Check if installed package can be replaced and install that instead
if e := FindReplacement(pkg); e != nil {
entry = e
} else if entry, _, err = GetRepositoryEntry(pkg); err != nil {
} else if entry, _, err = GetDatabaseEntry(pkg); err != nil {
continue
}
@ -328,8 +326,8 @@ func UpdatePackages(rootDir string, syncDatabase bool, installOptionalDependenci
comparison := ComparePackageVersions(*entry.Info, *installedInfo)
if comparison > 0 {
operation.AppendAction(&FetchPackageAction{
IsDependency: false,
RepositoryEntry: entry,
InstallationReason: GetInstallationReason(pkg, rootDir),
DatabaseEntry: entry,
})
}
}
@ -355,12 +353,12 @@ func UpdatePackages(rootDir string, syncDatabase bool, installOptionalDependenci
// SyncDatabase syncs all databases declared in /etc/bpm.conf
func SyncDatabase(verbose bool) (err error) {
for _, repo := range BPMConfig.Repositories {
for _, db := range BPMConfig.Databases {
if verbose {
fmt.Printf("Fetching package database for repository (%s)...\n", repo.Name)
fmt.Printf("Fetching package database file for database (%s)...\n", db.Name)
}
err := repo.SyncLocalDatabase()
err := db.SyncLocalDatabaseFile()
if err != nil {
return err
}

View File

@ -11,12 +11,11 @@ import (
)
type BPMOperation struct {
Actions []OperationAction
UnresolvedDepends []string
Changes map[string]string
RootDir string
ForceInstallationReason InstallationReason
compiledPackages map[string]string
Actions []OperationAction
UnresolvedDepends []string
Changes map[string]string
RootDir string
compiledPackages map[string]string
}
func (operation *BPMOperation) ActionsContainPackage(pkg string) bool {
@ -26,7 +25,7 @@ func (operation *BPMOperation) ActionsContainPackage(pkg string) bool {
return true
}
} else if action.GetActionType() == "fetch" {
if action.(*FetchPackageAction).RepositoryEntry.Info.Name == pkg {
if action.(*FetchPackageAction).DatabaseEntry.Info.Name == pkg {
return true
}
} else if action.GetActionType() == "remove" {
@ -58,7 +57,7 @@ func (operation *BPMOperation) InsertActionAt(index int, action OperationAction)
operation.Changes[pkgInfo.Name] = "upgrade"
}
} else if action.GetActionType() == "fetch" {
pkgInfo := action.(*FetchPackageAction).RepositoryEntry.Info
pkgInfo := action.(*FetchPackageAction).DatabaseEntry.Info
if !IsPackageInstalled(pkgInfo.Name, operation.RootDir) {
operation.Changes[pkgInfo.Name] = "install"
} else {
@ -77,7 +76,7 @@ func (operation *BPMOperation) RemoveAction(pkg, actionType string) {
if a.GetActionType() == "install" {
return a.(*InstallPackageAction).BpmPackage.PkgInfo.Name == pkg
} else if a.GetActionType() == "fetch" {
return a.(*FetchPackageAction).RepositoryEntry.Info.Name == pkg
return a.(*FetchPackageAction).DatabaseEntry.Info.Name == pkg
} else if a.GetActionType() == "remove" {
return a.(*RemovePackageAction).BpmPackage.PkgInfo.Name == pkg
}
@ -89,7 +88,7 @@ func (operation *BPMOperation) GetTotalDownloadSize() uint64 {
var ret uint64 = 0
for _, action := range operation.Actions {
if action.GetActionType() == "fetch" {
ret += action.(*FetchPackageAction).RepositoryEntry.DownloadSize
ret += action.(*FetchPackageAction).DatabaseEntry.DownloadSize
}
}
return ret
@ -101,7 +100,7 @@ func (operation *BPMOperation) GetTotalInstalledSize() uint64 {
if action.GetActionType() == "install" {
ret += action.(*InstallPackageAction).BpmPackage.GetInstalledSize()
} else if action.GetActionType() == "fetch" {
ret += action.(*FetchPackageAction).RepositoryEntry.InstalledSize
ret += action.(*FetchPackageAction).DatabaseEntry.InstalledSize
}
}
return ret
@ -116,7 +115,7 @@ func (operation *BPMOperation) GetFinalActionSize(rootDir string) int64 {
ret -= int64(GetPackage(action.(*InstallPackageAction).BpmPackage.PkgInfo.Name, rootDir).GetInstalledSize())
}
} else if action.GetActionType() == "fetch" {
ret += int64(action.(*FetchPackageAction).RepositoryEntry.InstalledSize)
ret += int64(action.(*FetchPackageAction).DatabaseEntry.InstalledSize)
} else if action.GetActionType() == "remove" {
ret -= int64(action.(*RemovePackageAction).BpmPackage.GetInstalledSize())
}
@ -133,28 +132,28 @@ func (operation *BPMOperation) ResolveDependencies(reinstallDependencies, instal
pkgInfo = action.BpmPackage.PkgInfo
} else if value.GetActionType() == "fetch" {
action := value.(*FetchPackageAction)
pkgInfo = action.RepositoryEntry.Info
pkgInfo = action.DatabaseEntry.Info
} else {
pos++
continue
}
resolved, unresolved := ResolvePackageDependenciesFromDatabases(pkgInfo, pkgInfo.Type == "source", installOptionalDependencies, !reinstallDependencies, verbose, operation.RootDir)
resolved, unresolved := ResolveAllPackageDependenciesFromDatabases(pkgInfo, pkgInfo.Type == "source", installOptionalDependencies, !reinstallDependencies, verbose, operation.RootDir)
operation.UnresolvedDepends = append(operation.UnresolvedDepends, unresolved...)
for _, depend := range resolved {
for depend, installationReason := range resolved {
if !operation.ActionsContainPackage(depend) && depend != pkgInfo.Name {
if !reinstallDependencies && IsPackageInstalled(depend, operation.RootDir) {
continue
}
entry, _, err := GetRepositoryEntry(depend)
entry, _, err := GetDatabaseEntry(depend)
if err != nil {
return errors.New("could not get repository entry for package (" + depend + ")")
return errors.New("could not get database entry for package (" + depend + ")")
}
operation.InsertActionAt(pos, &FetchPackageAction{
IsDependency: true,
RepositoryEntry: entry,
InstallationReason: installationReason,
DatabaseEntry: entry,
})
pos++
}
@ -192,7 +191,7 @@ func (operation *BPMOperation) RemoveNeededPackages() error {
return nil
}
func (operation *BPMOperation) Cleanup() error {
func (operation *BPMOperation) Cleanup(cleanupMakeDepends bool) error {
// Get all installed packages
installedPackageNames, err := GetInstalledPackages(operation.RootDir)
if err != nil {
@ -228,7 +227,7 @@ func (operation *BPMOperation) Cleanup() error {
}
keepPackages = append(keepPackages, pkg.Name)
resolved := pkg.GetAllDependencies(false, true, operation.RootDir)
resolved := pkg.GetAllDependencies(!cleanupMakeDepends, true, operation.RootDir)
for _, value := range resolved {
if !slices.Contains(keepPackages, value) {
keepPackages = append(keepPackages, value)
@ -263,7 +262,7 @@ func (operation *BPMOperation) ReplaceObsoletePackages() {
} else if value.GetActionType() == "fetch" {
action := value.(*FetchPackageAction)
pkgInfo = action.RepositoryEntry.Info
pkgInfo = action.DatabaseEntry.Info
} else {
continue
}
@ -301,7 +300,7 @@ func (operation *BPMOperation) CheckForConflicts() (map[string][]string, error)
allPackages = append(allPackages, pkgInfo)
} else if value.GetActionType() == "fetch" {
action := value.(*FetchPackageAction)
pkgInfo := action.RepositoryEntry.Info
pkgInfo := action.DatabaseEntry.Info
allPackages = append(allPackages, pkgInfo)
} else if value.GetActionType() == "remove" {
action := value.(*RemovePackageAction)
@ -336,13 +335,16 @@ func (operation *BPMOperation) ShowOperationSummary() {
for _, value := range operation.Actions {
var pkgInfo *PackageInfo
var installationReason = InstallationReasonUnknown
if value.GetActionType() == "install" {
installationReason = value.(*InstallPackageAction).InstallationReason
pkgInfo = value.(*InstallPackageAction).BpmPackage.PkgInfo
if value.(*InstallPackageAction).SplitPackageToInstall != "" {
pkgInfo = pkgInfo.GetSplitPackageInfo(value.(*InstallPackageAction).SplitPackageToInstall)
}
} else if value.GetActionType() == "fetch" {
pkgInfo = value.(*FetchPackageAction).RepositoryEntry.Info
installationReason = value.(*FetchPackageAction).InstallationReason
pkgInfo = value.(*FetchPackageAction).DatabaseEntry.Info
} else {
pkgInfo = value.(*RemovePackageAction).BpmPackage.PkgInfo
fmt.Printf("%s: %s (Remove)\n", pkgInfo.Name, pkgInfo.GetFullVersion())
@ -350,21 +352,32 @@ func (operation *BPMOperation) ShowOperationSummary() {
}
installedInfo := GetPackageInfo(pkgInfo.Name, operation.RootDir)
sourceInfo := ""
additionalInfo := ""
switch installationReason {
case InstallationReasonManual:
additionalInfo = "(Manual)"
case InstallationReasonDependency:
additionalInfo = "(Dependency)"
case InstallationReasonMakeDependency:
additionalInfo = "(Make dependency)"
default:
additionalInfo = "(Unknown)"
}
if pkgInfo.Type == "source" {
sourceInfo = "(From Source)"
additionalInfo += " (From Source)"
}
if installedInfo == nil {
fmt.Printf("%s: %s (Install) %s\n", pkgInfo.Name, pkgInfo.GetFullVersion(), sourceInfo)
fmt.Printf("%s: %s (Install) %s\n", pkgInfo.Name, pkgInfo.GetFullVersion(), additionalInfo)
} else {
comparison := ComparePackageVersions(*pkgInfo, *installedInfo)
if comparison < 0 {
fmt.Printf("%s: %s -> %s (Downgrade) %s\n", pkgInfo.Name, installedInfo.GetFullVersion(), pkgInfo.GetFullVersion(), sourceInfo)
fmt.Printf("%s: %s -> %s (Downgrade) %s\n", pkgInfo.Name, installedInfo.GetFullVersion(), pkgInfo.GetFullVersion(), additionalInfo)
} else if comparison > 0 {
fmt.Printf("%s: %s -> %s (Upgrade) %s\n", pkgInfo.Name, installedInfo.GetFullVersion(), pkgInfo.GetFullVersion(), sourceInfo)
fmt.Printf("%s: %s -> %s (Upgrade) %s\n", pkgInfo.Name, installedInfo.GetFullVersion(), pkgInfo.GetFullVersion(), additionalInfo)
} else {
fmt.Printf("%s: %s (Reinstall) %s\n", pkgInfo.Name, pkgInfo.GetFullVersion(), sourceInfo)
fmt.Printf("%s: %s (Reinstall) %s\n", pkgInfo.Name, pkgInfo.GetFullVersion(), additionalInfo)
}
}
}
@ -414,11 +427,11 @@ func (operation *BPMOperation) RunHooks(verbose bool) error {
}
func (operation *BPMOperation) Execute(verbose, force bool) (err error) {
// Fetch packages from repositories
// Fetch packages from databases
if slices.ContainsFunc(operation.Actions, func(action OperationAction) bool {
return action.GetActionType() == "fetch"
}) {
fmt.Println("Fetching packages from available repositories...")
fmt.Println("Fetching packages from available databases...")
// Create map for fetched packages
fetchedPackages := make(map[string]string)
@ -428,16 +441,16 @@ func (operation *BPMOperation) Execute(verbose, force bool) (err error) {
continue
}
// Get repository entry
entry := action.(*FetchPackageAction).RepositoryEntry
// Get database entry
entry := action.(*FetchPackageAction).DatabaseEntry
// Create bpmpkg variable
var bpmpkg *BPMPackage
// Check if package has already been fetched from download link
if _, ok := fetchedPackages[entry.Download]; !ok {
// Fetch package from repository
fetchedPackage, err := entry.Repository.FetchPackage(entry.Info.Name)
// Fetch package from database
fetchedPackage, err := entry.Database.FetchPackage(entry.Info.Name)
if err != nil {
return errors.New(fmt.Sprintf("could not fetch package (%s): %s\n", entry.Info.Name, err))
}
@ -465,15 +478,15 @@ func (operation *BPMOperation) Execute(verbose, force bool) (err error) {
if bpmpkg.PkgInfo.IsSplitPackage() {
operation.Actions[i] = &InstallPackageAction{
File: fetchedPackages[entry.Download],
IsDependency: action.(*FetchPackageAction).IsDependency,
InstallationReason: action.(*FetchPackageAction).InstallationReason,
BpmPackage: bpmpkg,
SplitPackageToInstall: entry.Info.Name,
}
} else {
operation.Actions[i] = &InstallPackageAction{
File: fetchedPackages[entry.Download],
IsDependency: action.(*FetchPackageAction).IsDependency,
BpmPackage: bpmpkg,
File: fetchedPackages[entry.Download],
InstallationReason: action.(*FetchPackageAction).InstallationReason,
BpmPackage: bpmpkg,
}
}
}
@ -553,7 +566,7 @@ func (operation *BPMOperation) Execute(verbose, force bool) (err error) {
}
}
if value.IsDependency {
if value.InstallationReason != InstallationReasonManual {
err = installPackage(fileToInstall, operation.RootDir, verbose, true)
} else {
err = installPackage(fileToInstall, operation.RootDir, verbose, force)
@ -561,13 +574,8 @@ func (operation *BPMOperation) Execute(verbose, force bool) (err error) {
if err != nil {
return errors.New(fmt.Sprintf("could not install package (%s): %s\n", bpmpkg.PkgInfo.Name, err))
}
if operation.ForceInstallationReason != InstallationReasonUnknown && !value.IsDependency {
err := SetInstallationReason(bpmpkg.PkgInfo.Name, operation.ForceInstallationReason, operation.RootDir)
if err != nil {
return errors.New(fmt.Sprintf("could not set installation reason for package (%s): %s\n", value.BpmPackage.PkgInfo.Name, err))
}
} else if value.IsDependency && !isReinstall {
err := SetInstallationReason(bpmpkg.PkgInfo.Name, InstallationReasonDependency, operation.RootDir)
if !isReinstall {
err := SetInstallationReason(bpmpkg.PkgInfo.Name, value.InstallationReason, operation.RootDir)
if err != nil {
return errors.New(fmt.Sprintf("could not set installation reason for package (%s): %s\n", value.BpmPackage.PkgInfo.Name, err))
}
@ -586,7 +594,7 @@ type OperationAction interface {
type InstallPackageAction struct {
File string
IsDependency bool
InstallationReason InstallationReason
SplitPackageToInstall string
BpmPackage *BPMPackage
}
@ -596,8 +604,8 @@ func (action *InstallPackageAction) GetActionType() string {
}
type FetchPackageAction struct {
IsDependency bool
RepositoryEntry *RepositoryEntry
InstallationReason InstallationReason
DatabaseEntry *BPMDatabaseEntry
}
func (action *FetchPackageAction) GetActionType() string {

View File

@ -92,9 +92,10 @@ func (pkgInfo *PackageInfo) GetSplitPackageInfo(splitPkg string) *PackageInfo {
type InstallationReason string
const (
InstallationReasonManual InstallationReason = "manual"
InstallationReasonDependency InstallationReason = "dependency"
InstallationReasonUnknown InstallationReason = "unknown"
InstallationReasonManual InstallationReason = "manual"
InstallationReasonDependency InstallationReason = "dependency"
InstallationReasonMakeDependency InstallationReason = "make_dependency"
InstallationReasonUnknown InstallationReason = "unknown"
)
func ComparePackageVersions(info1, info2 PackageInfo) int {
@ -119,6 +120,8 @@ func GetInstallationReason(pkg, rootDir string) InstallationReason {
return InstallationReasonManual
} else if reason == "dependency" {
return InstallationReasonDependency
} else if reason == "make_dependency" {
return InstallationReasonMakeDependency
}
return InstallationReasonUnknown
}
@ -466,8 +469,7 @@ func ReadPackageInfo(contents string) (*PackageInfo, error) {
pkgInfoClone := *pkgInfo
pkgInfo.SplitPackages[i] = &pkgInfoClone
// Set make depends and split package field of split package to nil
pkgInfo.SplitPackages[i].MakeDepends = nil
// Set split package field of split package to nil
pkgInfo.SplitPackages[i].SplitPackages = nil
// Unmarshal json data back to struct
@ -484,7 +486,7 @@ func ReadPackageInfo(contents string) (*PackageInfo, error) {
return pkgInfo, nil
}
func CreateReadableInfo(showArchitecture, showType, showPackageRelations bool, pkgInfo *PackageInfo, rootDir string) string {
func CreateReadableInfo(showArchitecture, showType, showPackageRelations, showInstallationReason bool, pkgInfo *PackageInfo, rootDir string) string {
ret := make([]string, 0)
appendArray := func(label string, array []string) {
if len(array) == 0 {
@ -524,7 +526,21 @@ func CreateReadableInfo(showArchitecture, showType, showPackageRelations bool, p
}
appendArray("Split Packages", splitPkgs)
}
ret = append(ret, "Installation Reason: "+string(GetInstallationReason(pkgInfo.Name, rootDir)))
if IsPackageInstalled(pkgInfo.Name, rootDir) && showInstallationReason {
installationReason := GetInstallationReason(pkgInfo.Name, rootDir)
var installationReasonString string
switch installationReason {
case InstallationReasonManual:
installationReasonString = "Manual"
case InstallationReasonDependency:
installationReasonString = "Dependency"
case InstallationReasonMakeDependency:
installationReasonString = "Make dependency"
default:
installationReasonString = "Unknown"
}
ret = append(ret, "Installation Reason: "+installationReasonString)
}
return strings.Join(ret, "\n")
}