Compare commits
2 Commits
4f9d2cdecd
...
87c492a30c
Author | SHA1 | Date | |
---|---|---|---|
87c492a30c | |||
e94b2a8816 |
36
main.go
36
main.go
@ -105,10 +105,14 @@ func resolveCommand() {
|
||||
var info *utils.PackageInfo
|
||||
isFile := false
|
||||
if showRepoInfo {
|
||||
entry, _, err := utils.GetRepositoryEntry(pkg)
|
||||
var err error
|
||||
var entry *utils.RepositoryEntry
|
||||
entry, _, err = utils.GetRepositoryEntry(pkg)
|
||||
if err != nil {
|
||||
if entry = utils.ResolveVirtualPackage(pkg); entry == nil {
|
||||
log.Fatalf("Error: could not find package (%s) in any repository\n", pkg)
|
||||
}
|
||||
}
|
||||
info = entry.Info
|
||||
} else if stat, err := os.Stat(pkg); err == nil && !stat.IsDir() {
|
||||
bpmpkg, err := utils.ReadPackage(pkg)
|
||||
@ -117,9 +121,13 @@ func resolveCommand() {
|
||||
}
|
||||
info = bpmpkg.PkgInfo
|
||||
isFile = true
|
||||
} else {
|
||||
if isVirtual, p := utils.IsVirtualPackage(pkg, rootDir); isVirtual {
|
||||
info = utils.GetPackageInfo(p, rootDir)
|
||||
} else {
|
||||
info = utils.GetPackageInfo(pkg, rootDir)
|
||||
}
|
||||
}
|
||||
if info == nil {
|
||||
log.Fatalf("Error: package (%s) is not installed\n", pkg)
|
||||
}
|
||||
@ -236,8 +244,18 @@ func resolveCommand() {
|
||||
BpmPackage: bpmpkg,
|
||||
})
|
||||
} else {
|
||||
entry, _, err := utils.GetRepositoryEntry(pkg)
|
||||
var entry *utils.RepositoryEntry
|
||||
|
||||
if e, _, err := utils.GetRepositoryEntry(pkg); err == nil {
|
||||
entry = e
|
||||
} else if isVirtual, p := utils.IsVirtualPackage(pkg, rootDir); isVirtual {
|
||||
entry, _, err = utils.GetRepositoryEntry(p)
|
||||
if err != nil {
|
||||
log.Fatalf("Error: could not find package (%s) in any repository\n", p)
|
||||
}
|
||||
} else if e := utils.ResolveVirtualPackage(pkg); e != nil {
|
||||
entry = e
|
||||
} else {
|
||||
log.Fatalf("Error: could not find package (%s) in any repository\n", pkg)
|
||||
}
|
||||
if !reinstall && utils.IsPackageInstalled(entry.Info.Name, rootDir) && utils.GetPackageInfo(entry.Info.Name, rootDir).GetFullVersion() == entry.Info.GetFullVersion() {
|
||||
@ -263,6 +281,9 @@ func resolveCommand() {
|
||||
}
|
||||
}
|
||||
|
||||
// Replace obsolete packages
|
||||
operation.ReplaceObsoletePackages()
|
||||
|
||||
// Check for conflicts
|
||||
conflicts, err := operation.CheckForConflicts()
|
||||
if err != nil {
|
||||
@ -343,10 +364,14 @@ func resolveCommand() {
|
||||
if slices.Contains(utils.BPMConfig.IgnorePackages, pkg) {
|
||||
continue
|
||||
}
|
||||
entry, _, err := utils.GetRepositoryEntry(pkg)
|
||||
if err != nil {
|
||||
var entry *utils.RepositoryEntry
|
||||
// Check if installed package can be replaced and install that instead
|
||||
if e := utils.FindReplacement(pkg); e != nil {
|
||||
entry = e
|
||||
} else if entry, _, err = utils.GetRepositoryEntry(pkg); err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
installedInfo := utils.GetPackageInfo(pkg, rootDir)
|
||||
if installedInfo == nil {
|
||||
log.Fatalf("Error: could not get package info for (%s)\n", pkg)
|
||||
@ -374,6 +399,9 @@ func resolveCommand() {
|
||||
}
|
||||
}
|
||||
|
||||
// Replace obsolete packages
|
||||
operation.ReplaceObsoletePackages()
|
||||
|
||||
// Show operation summary
|
||||
operation.ShowOperationSummary()
|
||||
|
||||
|
@ -42,6 +42,7 @@ func ReadConfig() {
|
||||
}
|
||||
for _, repo := range BPMConfig.Repositories {
|
||||
repo.Entries = make(map[string]*RepositoryEntry)
|
||||
repo.VirtualPackages = make(map[string][]string)
|
||||
err := repo.ReadLocalDatabase()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
|
@ -228,6 +228,30 @@ func (operation *BPMOperation) Cleanup(verbose bool) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (operation *BPMOperation) ReplaceObsoletePackages() {
|
||||
for _, value := range slices.Clone(operation.Actions) {
|
||||
var pkgInfo *PackageInfo
|
||||
if value.GetActionType() == "install" {
|
||||
action := value.(*InstallPackageAction)
|
||||
pkgInfo = action.BpmPackage.PkgInfo
|
||||
|
||||
} else if value.GetActionType() == "fetch" {
|
||||
action := value.(*FetchPackageAction)
|
||||
pkgInfo = action.RepositoryEntry.Info
|
||||
} else {
|
||||
continue
|
||||
}
|
||||
|
||||
for _, r := range pkgInfo.Replaces {
|
||||
if bpmpkg := GetPackage(r, operation.RootDir); bpmpkg != nil && !operation.ActionsContainPackage(bpmpkg.PkgInfo.Name) {
|
||||
operation.InsertActionAt(0, &RemovePackageAction{
|
||||
BpmPackage: bpmpkg,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (operation *BPMOperation) CheckForConflicts() (map[string][]string, error) {
|
||||
conflicts := make(map[string][]string)
|
||||
installedPackages, err := GetInstalledPackages(operation.RootDir)
|
||||
@ -256,9 +280,12 @@ func (operation *BPMOperation) CheckForConflicts() (map[string][]string, error)
|
||||
} else if value.GetActionType() == "remove" {
|
||||
action := value.(*RemovePackageAction)
|
||||
pkgInfo := action.BpmPackage.PkgInfo
|
||||
slices.DeleteFunc(allPackages, func(info *PackageInfo) bool {
|
||||
return info.Name == pkgInfo.Name
|
||||
})
|
||||
for i := len(allPackages) - 1; i >= 0; i-- {
|
||||
info := allPackages[i]
|
||||
if info.Name == pkgInfo.Name {
|
||||
allPackages = append(allPackages[:i], allPackages[i+1:]...)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -39,6 +39,7 @@ type PackageInfo struct {
|
||||
MakeDepends []string `yaml:"make_depends,omitempty"`
|
||||
OptionalDepends []string `yaml:"optional_depends,omitempty"`
|
||||
Conflicts []string `yaml:"conflicts,omitempty"`
|
||||
Replaces []string `yaml:"replaces,omitempty"`
|
||||
Provides []string `yaml:"provides,omitempty"`
|
||||
}
|
||||
|
||||
@ -406,6 +407,7 @@ func ReadPackageInfo(contents string) (*PackageInfo, error) {
|
||||
MakeDepends: make([]string, 0),
|
||||
OptionalDepends: make([]string, 0),
|
||||
Conflicts: make([]string, 0),
|
||||
Replaces: make([]string, 0),
|
||||
Provides: make([]string, 0),
|
||||
}
|
||||
err := yaml.Unmarshal([]byte(contents), &pkgInfo)
|
||||
@ -468,7 +470,7 @@ func CreateReadableInfo(showArchitecture, showType, showPackageRelations bool, p
|
||||
}
|
||||
appendArray("Conflicting packages", pkgInfo.Conflicts)
|
||||
appendArray("Provided packages", pkgInfo.Provides)
|
||||
|
||||
appendArray("Replaces packages", pkgInfo.Replaces)
|
||||
}
|
||||
ret = append(ret, "Installation Reason: "+string(GetInstallationReason(pkgInfo.Name, rootDir)))
|
||||
return strings.Join(ret, "\n")
|
||||
@ -1338,16 +1340,20 @@ func (pkgInfo *PackageInfo) ResolveDependencies(resolved, unresolved *[]string,
|
||||
*resolved = append(*resolved, depend)
|
||||
}
|
||||
continue
|
||||
} else if ignoreInstalled && IsPackageInstalled(depend, rootDir) {
|
||||
} else if ignoreInstalled && IsPackageProvided(depend, rootDir) {
|
||||
continue
|
||||
}
|
||||
entry, _, err := GetRepositoryEntry(depend)
|
||||
var err error
|
||||
var entry *RepositoryEntry
|
||||
entry, _, err = GetRepositoryEntry(depend)
|
||||
if err != nil {
|
||||
if entry = ResolveVirtualPackage(depend); entry == nil {
|
||||
if !slices.Contains(*unresolved, depend) {
|
||||
*unresolved = append(*unresolved, depend)
|
||||
}
|
||||
continue
|
||||
}
|
||||
}
|
||||
entry.Info.ResolveDependencies(resolved, unresolved, checkMake, checkOptional, ignoreInstalled, verbose, rootDir)
|
||||
}
|
||||
}
|
||||
@ -1367,6 +1373,26 @@ func IsPackageInstalled(pkg, rootDir string) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func IsVirtualPackage(pkg, rootDir string) (bool, string) {
|
||||
pkgs, err := GetInstalledPackages(rootDir)
|
||||
if err != nil {
|
||||
return false, ""
|
||||
}
|
||||
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 {
|
||||
pkgs, err := GetInstalledPackages(rootDir)
|
||||
if err != nil {
|
||||
|
@ -8,7 +8,6 @@ import (
|
||||
"net/url"
|
||||
"os"
|
||||
"path"
|
||||
"sort"
|
||||
"strings"
|
||||
)
|
||||
|
||||
@ -17,6 +16,7 @@ type Repository struct {
|
||||
Source string `yaml:"source"`
|
||||
Disabled *bool `yaml:"disabled"`
|
||||
Entries map[string]*RepositoryEntry
|
||||
VirtualPackages map[string][]string
|
||||
}
|
||||
|
||||
type RepositoryEntry struct {
|
||||
@ -24,7 +24,6 @@ type RepositoryEntry struct {
|
||||
Download string `yaml:"download"`
|
||||
DownloadSize uint64 `yaml:"download_size"`
|
||||
InstalledSize uint64 `yaml:"installed_size"`
|
||||
IsVirtualPackage bool `yaml:"-"`
|
||||
Repository *Repository
|
||||
}
|
||||
|
||||
@ -44,8 +43,6 @@ func (repo *Repository) ReadLocalDatabase() error {
|
||||
return err
|
||||
}
|
||||
|
||||
virtualPackages := make(map[string][]string)
|
||||
|
||||
data := string(bytes)
|
||||
for _, b := range strings.Split(data, "---") {
|
||||
entry := RepositoryEntry{
|
||||
@ -68,7 +65,6 @@ func (repo *Repository) ReadLocalDatabase() error {
|
||||
Download: "",
|
||||
DownloadSize: 0,
|
||||
InstalledSize: 0,
|
||||
IsVirtualPackage: false,
|
||||
Repository: repo,
|
||||
}
|
||||
err := yaml.Unmarshal([]byte(b), &entry)
|
||||
@ -77,26 +73,11 @@ func (repo *Repository) ReadLocalDatabase() error {
|
||||
}
|
||||
|
||||
for _, p := range entry.Info.Provides {
|
||||
virtualPackages[p] = append(virtualPackages[p], entry.Info.Name)
|
||||
repo.VirtualPackages[p] = append(repo.VirtualPackages[p], entry.Info.Name)
|
||||
}
|
||||
repo.Entries[entry.Info.Name] = &entry
|
||||
}
|
||||
|
||||
for key, value := range virtualPackages {
|
||||
if _, ok := repo.Entries[key]; ok {
|
||||
continue
|
||||
}
|
||||
sort.Strings(value)
|
||||
entry := RepositoryEntry{
|
||||
Info: repo.Entries[value[0]].Info,
|
||||
Download: repo.Entries[value[0]].Download,
|
||||
DownloadSize: repo.Entries[value[0]].DownloadSize,
|
||||
InstalledSize: repo.Entries[value[0]].InstalledSize,
|
||||
IsVirtualPackage: true,
|
||||
Repository: repo,
|
||||
}
|
||||
repo.Entries[key] = &entry
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -167,6 +148,32 @@ func GetRepositoryEntry(str string) (*RepositoryEntry, *Repository, error) {
|
||||
}
|
||||
}
|
||||
|
||||
func FindReplacement(pkg string) *RepositoryEntry {
|
||||
for _, repo := range BPMConfig.Repositories {
|
||||
for _, entry := range repo.Entries {
|
||||
for _, replaced := range entry.Info.Replaces {
|
||||
if replaced == pkg {
|
||||
return entry
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func ResolveVirtualPackage(vpkg string) *RepositoryEntry {
|
||||
for _, repo := range BPMConfig.Repositories {
|
||||
if v, ok := repo.VirtualPackages[vpkg]; ok {
|
||||
for _, pkg := range v {
|
||||
return repo.Entries[pkg]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (repo *Repository) FetchPackage(pkg string) (string, error) {
|
||||
if !repo.ContainsPackage(pkg) {
|
||||
return "", errors.New("could not fetch package '" + pkg + "'")
|
||||
|
Loading…
x
Reference in New Issue
Block a user