github.com/turbot/steampipe@v1.7.0-rc.0.0.20240517123944-7cef272d4458/pkg/modinstaller/install_data.go (about) 1 package modinstaller 2 3 import ( 4 "fmt" 5 6 "github.com/Masterminds/semver/v3" 7 "github.com/turbot/steampipe/pkg/steampipeconfig/modconfig" 8 "github.com/turbot/steampipe/pkg/steampipeconfig/versionmap" 9 "github.com/turbot/steampipe/pkg/versionhelpers" 10 "github.com/xlab/treeprint" 11 ) 12 13 type InstallData struct { 14 // record of the full dependency tree 15 Lock *versionmap.WorkspaceLock 16 NewLock *versionmap.WorkspaceLock 17 18 // ALL the available versions for each dependency mod(we populate this in a lazy fashion) 19 allAvailable versionmap.VersionListMap 20 21 // list of dependencies installed by recent install operation 22 Installed versionmap.DependencyVersionMap 23 // list of dependencies which have been upgraded 24 Upgraded versionmap.DependencyVersionMap 25 // list of dependencies which have been downgraded 26 Downgraded versionmap.DependencyVersionMap 27 // list of dependencies which have been uninstalled 28 Uninstalled versionmap.DependencyVersionMap 29 WorkspaceMod *modconfig.Mod 30 } 31 32 func NewInstallData(workspaceLock *versionmap.WorkspaceLock, workspaceMod *modconfig.Mod) *InstallData { 33 return &InstallData{ 34 Lock: workspaceLock, 35 WorkspaceMod: workspaceMod, 36 NewLock: versionmap.EmptyWorkspaceLock(workspaceLock), 37 allAvailable: make(versionmap.VersionListMap), 38 Installed: make(versionmap.DependencyVersionMap), 39 Upgraded: make(versionmap.DependencyVersionMap), 40 Downgraded: make(versionmap.DependencyVersionMap), 41 Uninstalled: make(versionmap.DependencyVersionMap), 42 } 43 } 44 45 // GetAvailableUpdates returns a map of all installed mods which are not in the lock file 46 func (d *InstallData) GetAvailableUpdates() (versionmap.DependencyVersionMap, error) { 47 res := make(versionmap.DependencyVersionMap) 48 for parent, deps := range d.Lock.InstallCache { 49 for name, resolvedConstraint := range deps { 50 includePrerelease := resolvedConstraint.IsPrerelease() 51 availableVersions, err := d.getAvailableModVersions(name, includePrerelease) 52 if err != nil { 53 return nil, err 54 } 55 constraint, _ := versionhelpers.NewConstraint(resolvedConstraint.Constraint) 56 var latestVersion = getVersionSatisfyingConstraint(constraint, availableVersions) 57 if latestVersion.GreaterThan(resolvedConstraint.Version) { 58 res.Add(name, resolvedConstraint.Alias, latestVersion, constraint.Original, parent) 59 } 60 } 61 } 62 return res, nil 63 } 64 65 // onModInstalled is called when a dependency is satisfied by installing a mod version 66 func (d *InstallData) onModInstalled(dependency *ResolvedModRef, modDef *modconfig.Mod, parent *modconfig.Mod) { 67 parentPath := parent.GetInstallCacheKey() 68 // get the constraint from the parent (it must be there) 69 modVersionConstraint := parent.Require.GetModDependency(dependency.Name).Constraint.Original 70 71 // update lock 72 d.NewLock.InstallCache.Add(dependency.Name, modDef.ShortName, modDef.Version, modVersionConstraint, parentPath) 73 } 74 75 // addExisting is called when a dependency is satisfied by a mod which is already installed 76 func (d *InstallData) addExisting(dependencyName string, existingDep *modconfig.Mod, constraint *versionhelpers.Constraints, parent *modconfig.Mod) { 77 // update lock 78 parentPath := parent.GetInstallCacheKey() 79 d.NewLock.InstallCache.Add(dependencyName, existingDep.ShortName, existingDep.Version, constraint.Original, parentPath) 80 } 81 82 // retrieve all available mod versions from our cache, or from Git if not yet cached 83 func (d *InstallData) getAvailableModVersions(modName string, includePrerelease bool) ([]*semver.Version, error) { 84 // have we already loaded the versions for this mod 85 availableVersions, ok := d.allAvailable[modName] 86 if ok { 87 return availableVersions, nil 88 } 89 // so we have not cached this yet - retrieve from Git 90 var err error 91 availableVersions, err = getTagVersionsFromGit(getGitUrl(modName), includePrerelease) 92 if err != nil { 93 return nil, fmt.Errorf("could not retrieve version data from Git URL '%s'", modName) 94 } 95 // update our cache 96 d.allAvailable[modName] = availableVersions 97 98 return availableVersions, nil 99 } 100 101 // update the lock with the NewLock and dtermine if any mods have been uninstalled 102 func (d *InstallData) onInstallComplete() { 103 d.Installed = d.NewLock.InstallCache.GetMissingFromOther(d.Lock.InstallCache) 104 d.Uninstalled = d.Lock.InstallCache.GetMissingFromOther(d.NewLock.InstallCache) 105 d.Upgraded = d.Lock.InstallCache.GetUpgradedInOther(d.NewLock.InstallCache) 106 d.Downgraded = d.Lock.InstallCache.GetDowngradedInOther(d.NewLock.InstallCache) 107 d.Lock = d.NewLock 108 } 109 110 func (d *InstallData) GetUpdatedTree() treeprint.Tree { 111 return d.Upgraded.GetDependencyTree(d.WorkspaceMod.GetInstallCacheKey()) 112 } 113 114 func (d *InstallData) GetInstalledTree() treeprint.Tree { 115 return d.Installed.GetDependencyTree(d.WorkspaceMod.GetInstallCacheKey()) 116 } 117 118 func (d *InstallData) GetUninstalledTree() treeprint.Tree { 119 return d.Uninstalled.GetDependencyTree(d.WorkspaceMod.GetInstallCacheKey()) 120 }