@@ -114,7 +114,7 @@ ClassMethod LoadModuleReference(
114114
115115 // Ensure requested versions match those required by other modules in the namespace, excluding versions currently being installed
116116 // (the requirements of such modules are already known to be satisfied)
117- set tSC = ..GetRequiredVersionExpression (pModuleName ,,.tExpression ,.tSourceList )
117+ set tSC = ..GetRequiredVersionExpression (pModuleName ,,.pDependencyGraph ,. tExpression ,.tSourceList )
118118 if $$$ISERR(tSC ) {
119119 quit
120120 }
@@ -349,36 +349,79 @@ ClassMethod GetModuleObjectFromString(
349349
350350/// Returns a semantic version expression capturing all version requirements for a given module name in the current namespace.
351351/// A list of modules to exclude may be provided (for example, if these modules would be updated at the same time).
352+ ///
353+ /// If provided a dependency graph, will use versions defined there instead of what the SQL call returns.
354+ /// This is especially important for the update command, where we want to check requirements with post-update versions as opposed to what's currently installed.
352355ClassMethod GetRequiredVersionExpression (
353- pModuleName As %String ,
354- pExcludeModules As %List = " " ,
355- Output pExpression As %IPM .General .SemanticVersionExpression ,
356- Output pSourceList As %List ) As %Status
356+ moduleName As %String ,
357+ excludeModules As %List = " " ,
358+ ByRef dependencyGraph ,
359+ Output expression As %IPM .General .SemanticVersionExpression ,
360+ Output sourceList As %List ) As %Status
357361{
358- set tSC = $$$OK
362+ set sc = $$$OK
359363 try {
360- set pExpression = ##class (%IPM.General.SemanticVersionExpression ).%New ()
361- set pSourceList = " "
364+ // Add modules from the dependency graph to the excludeModules list
365+ if ($data (dependencyGraph )) {
366+ do ..ConstructInvertedDependencyGraph (.dependencyGraph , .invertedDependencyGraph )
367+ set flatDepList = ..GetFlatDependencyListFromInvertedDependencyGraph (.invertedDependencyGraph )
368+ for i = 1 :1 :flatDepList .Count () {
369+ set excludeModules = excludeModules _ $listbuild (flatDepList .GetAt (i ).Name )
370+ }
371+ }
362372
363- set tResult = ##class (%IPM.Storage.Module ).VersionRequirementsFunc (pModuleName ,pExcludeModules )
364- if (tResult .%SQLCODE < 0 ) {
365- $$$ThrowStatus($$$ERROR($$$SQLCode,tResult .%SQLCODE ,tResult .%Message ))
373+ set expression = ##class (%IPM.General.SemanticVersionExpression ).%New ()
374+ set sourceList = " "
375+
376+ set result = ##class (%IPM.Storage.Module ).VersionRequirementsFunc (moduleName ,excludeModules )
377+ if (result .%SQLCODE < 0 ) {
378+ $$$ThrowStatus($$$ERROR($$$SQLCode,result .%SQLCODE ,result .%Message ))
366379 }
367380
368- while tResult .%Next (.tSC ) {
369- $$$ThrowOnError(tSC )
370- set tVersion = tResult .%Get (" Version" )
371- $$$ThrowOnError(##class (%IPM.General.SemanticVersionExpression ).FromString (tVersion ,.tVersionExpr ))
372- set pExpression = pExpression .And (tVersionExpr )
373- set pSourceList = pSourceList _$listbuild ($listtostring (tResult .%Get (" ModuleNames" )," , " )_" : " _tVersion )
381+ while result .%Next (.sc ) {
382+ $$$ThrowOnError(sc )
383+ set version = result .%Get (" Version" )
384+ $$$ThrowOnError(##class (%IPM.General.SemanticVersionExpression ).FromString (version ,.versionExpr ))
385+ set expression = expression .And (versionExpr )
386+ set sourceList = sourceList _$listbuild ($listtostring (result .%Get (" ModuleNames" )," , " )_" : " _version )
387+ }
388+ $$$ThrowOnError(sc )
389+
390+ // Add modules from the dependency graph to the expression and sourceList objects
391+ if ($data (dependencyGraph )) {
392+ set key = " "
393+ for {
394+ set key = $order (dependencyGraph (moduleName , key ))
395+ if (key = " " ) {
396+ quit
397+ }
398+ // Name of module which requires this one + the version expression string it requires
399+ set requiringModuleName = $piece (key , " " )
400+ set version = dependencyGraph (moduleName , key )
401+
402+ // Iterate over sourceList; if the required version expression is equivalent to this one, add this module name to that version
403+ set newVersion = 1
404+ for i =1 :1 :$listlength (sourceList ) {
405+ if $find ($listget (sourceList , i ), version ) {
406+ set $list (sourceList , i ) = requiringModuleName _ " , " _ $list (sourceList , i )
407+ set newVersion = 0
408+ quit
409+ }
410+ }
411+ // If this is a new required version expression, add a new item to the list
412+ if (newVersion ) {
413+ $$$ThrowOnError(##class (%IPM.General.SemanticVersionExpression ).FromString (version , .versionExpr ))
414+ set expression = expression .And (versionExpr )
415+ set sourceList = sourceList _ $listbuild (requiringModuleName _ " : " _ version )
416+ }
417+ }
374418 }
375- $$$ThrowOnError(tSC )
376419 } catch e {
377- set pExpression = $$$NULLOREF
378- set pSourceList = " "
379- set tSC = e .AsStatus ()
420+ set expression = $$$NULLOREF
421+ set sourceList = " "
422+ set sc = e .AsStatus ()
380423 }
381- quit tSC
424+ quit sc
382425}
383426
384427/// Returns a flat list of dependents for a given module name (and optional version) <br />
@@ -1278,7 +1321,7 @@ ClassMethod LoadDependencies(
12781321 // Ignore modules already installed that do not need to be installed again
12791322 continue
12801323 }
1281- set sc = ..LoadModuleReference (moduleReference .ServerName , moduleReference .Name , moduleReference .VersionString , moduleReference .Deployed , moduleReference .PlatformVersion , .pParams )
1324+ set sc = ..LoadModuleReference (moduleReference .ServerName , moduleReference .Name , moduleReference .VersionString , moduleReference .Deployed , moduleReference .PlatformVersion , .pParams , . dependencyGraph )
12821325 $$$ThrowOnError(sc )
12831326 }
12841327
0 commit comments