mirror of
https://github.com/turbot/steampipe.git
synced 2025-12-19 18:12:43 -05:00
121 lines
4.8 KiB
Go
121 lines
4.8 KiB
Go
package modinstaller
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"github.com/Masterminds/semver/v3"
|
|
"github.com/turbot/steampipe/pkg/steampipeconfig/modconfig"
|
|
"github.com/turbot/steampipe/pkg/steampipeconfig/versionmap"
|
|
"github.com/turbot/steampipe/pkg/versionhelpers"
|
|
"github.com/xlab/treeprint"
|
|
)
|
|
|
|
type InstallData struct {
|
|
// record of the full dependency tree
|
|
Lock *versionmap.WorkspaceLock
|
|
NewLock *versionmap.WorkspaceLock
|
|
|
|
// ALL the available versions for each dependency mod(we populate this in a lazy fashion)
|
|
allAvailable versionmap.VersionListMap
|
|
|
|
// list of dependencies installed by recent install operation
|
|
Installed versionmap.DependencyVersionMap
|
|
// list of dependencies which have been upgraded
|
|
Upgraded versionmap.DependencyVersionMap
|
|
// list of dependencies which have been downgraded
|
|
Downgraded versionmap.DependencyVersionMap
|
|
// list of dependencies which have been uninstalled
|
|
Uninstalled versionmap.DependencyVersionMap
|
|
WorkspaceMod *modconfig.Mod
|
|
}
|
|
|
|
func NewInstallData(workspaceLock *versionmap.WorkspaceLock, workspaceMod *modconfig.Mod) *InstallData {
|
|
return &InstallData{
|
|
Lock: workspaceLock,
|
|
WorkspaceMod: workspaceMod,
|
|
NewLock: versionmap.EmptyWorkspaceLock(workspaceLock),
|
|
allAvailable: make(versionmap.VersionListMap),
|
|
Installed: make(versionmap.DependencyVersionMap),
|
|
Upgraded: make(versionmap.DependencyVersionMap),
|
|
Downgraded: make(versionmap.DependencyVersionMap),
|
|
Uninstalled: make(versionmap.DependencyVersionMap),
|
|
}
|
|
}
|
|
|
|
// GetAvailableUpdates returns a map of all installed mods which are not in the lock file
|
|
func (d *InstallData) GetAvailableUpdates() (versionmap.DependencyVersionMap, error) {
|
|
res := make(versionmap.DependencyVersionMap)
|
|
for parent, deps := range d.Lock.InstallCache {
|
|
for name, resolvedConstraint := range deps {
|
|
includePrerelease := resolvedConstraint.IsPrerelease()
|
|
availableVersions, err := d.getAvailableModVersions(name, includePrerelease)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
constraint, _ := versionhelpers.NewConstraint(resolvedConstraint.Constraint)
|
|
var latestVersion = getVersionSatisfyingConstraint(constraint, availableVersions)
|
|
if latestVersion.GreaterThan(resolvedConstraint.Version) {
|
|
res.Add(name, resolvedConstraint.Alias, latestVersion, constraint.Original, parent)
|
|
}
|
|
}
|
|
}
|
|
return res, nil
|
|
}
|
|
|
|
// onModInstalled is called when a dependency is satisfied by installing a mod version
|
|
func (d *InstallData) onModInstalled(dependency *ResolvedModRef, modDef *modconfig.Mod, parent *modconfig.Mod) {
|
|
parentPath := parent.GetInstallCacheKey()
|
|
// get the constraint from the parent (it must be there)
|
|
modVersionConstraint := parent.Require.GetModDependency(dependency.Name).Constraint.Original
|
|
|
|
// update lock
|
|
d.NewLock.InstallCache.Add(dependency.Name, modDef.ShortName, modDef.Version, modVersionConstraint, parentPath)
|
|
}
|
|
|
|
// addExisting is called when a dependency is satisfied by a mod which is already installed
|
|
func (d *InstallData) addExisting(dependencyName string, existingDep *modconfig.Mod, constraint *versionhelpers.Constraints, parent *modconfig.Mod) {
|
|
// update lock
|
|
parentPath := parent.GetInstallCacheKey()
|
|
d.NewLock.InstallCache.Add(dependencyName, existingDep.ShortName, existingDep.Version, constraint.Original, parentPath)
|
|
}
|
|
|
|
// retrieve all available mod versions from our cache, or from Git if not yet cached
|
|
func (d *InstallData) getAvailableModVersions(modName string, includePrerelease bool) ([]*semver.Version, error) {
|
|
// have we already loaded the versions for this mod
|
|
availableVersions, ok := d.allAvailable[modName]
|
|
if ok {
|
|
return availableVersions, nil
|
|
}
|
|
// so we have not cached this yet - retrieve from Git
|
|
var err error
|
|
availableVersions, err = getTagVersionsFromGit(getGitUrl(modName), includePrerelease)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("could not retrieve version data from Git URL '%s'", modName)
|
|
}
|
|
// update our cache
|
|
d.allAvailable[modName] = availableVersions
|
|
|
|
return availableVersions, nil
|
|
}
|
|
|
|
// update the lock with the NewLock and dtermine if any mods have been uninstalled
|
|
func (d *InstallData) onInstallComplete() {
|
|
d.Installed = d.NewLock.InstallCache.GetMissingFromOther(d.Lock.InstallCache)
|
|
d.Uninstalled = d.Lock.InstallCache.GetMissingFromOther(d.NewLock.InstallCache)
|
|
d.Upgraded = d.Lock.InstallCache.GetUpgradedInOther(d.NewLock.InstallCache)
|
|
d.Downgraded = d.Lock.InstallCache.GetDowngradedInOther(d.NewLock.InstallCache)
|
|
d.Lock = d.NewLock
|
|
}
|
|
|
|
func (d *InstallData) GetUpdatedTree() treeprint.Tree {
|
|
return d.Upgraded.GetDependencyTree(d.WorkspaceMod.GetInstallCacheKey())
|
|
}
|
|
|
|
func (d *InstallData) GetInstalledTree() treeprint.Tree {
|
|
return d.Installed.GetDependencyTree(d.WorkspaceMod.GetInstallCacheKey())
|
|
}
|
|
|
|
func (d *InstallData) GetUninstalledTree() treeprint.Tree {
|
|
return d.Uninstalled.GetDependencyTree(d.WorkspaceMod.GetInstallCacheKey())
|
|
}
|