diff --git a/CHANGELOG.md b/CHANGELOG.md
index 6f72ed274..371d39df6 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added
- #992: Implement automatic history purge logic
- #973: Enables CORS and JWT configuration for WebApplications in module.xml
+- #1095: Add -outdated modifier in list command
### Fixed
- #1001: The `unmap` and `enable` commands will now only activate CPF merge once after all namespaces have been configured instead after every namespace
diff --git a/src/cls/IPM/Main.cls b/src/cls/IPM/Main.cls
index 64f7e2819..114697aaf 100644
--- a/src/cls/IPM/Main.cls
+++ b/src/cls/IPM/Main.cls
@@ -526,6 +526,9 @@ reinstall -env /path/to/env1.json;/path/to/env2.json example-package
list -python
+
+ list -outdated
+
@@ -538,6 +541,7 @@ reinstall -env /path/to/env1.json;/path/to/env2.json example-package
+
@@ -2757,6 +2761,12 @@ ClassMethod ListInstalled(ByRef pCommandInfo) [ Private ]
do ..DisplayModules(.list,,,, .tModifiers)
quit
}
+ if $data(pCommandInfo("modifiers","outdated")) {
+ merge tModifiers = pCommandInfo("modifiers")
+ do ..GetOutdatedModulesList(.list)
+ do ..DisplayModules(.list,,,, .tModifiers)
+ quit
+ }
if (''$data(pCommandInfo("modifiers","tree"))) {
// Show tree of dependencies as well.
// Modules that are dependencies for no other are shown at the top level.
@@ -2821,8 +2831,7 @@ ClassMethod GetListModule(
{
new $namespace
set $namespace=ns
- set tRes = ##class(%SQL.Statement).%ExecDirect(,
- "select * from %IPM_Storage.ModuleItem")
+ set tRes = ##class(%SQL.Statement).%ExecDirect(, "select * from %IPM_Storage.ModuleItem")
$$$ThrowSQLIfError(tRes.%SQLCODE,tRes.%Message)
set in=""
while tRes.%Next(.tSC) {
@@ -4171,6 +4180,47 @@ ClassMethod Update(ByRef pCommandInfo)
}
}
+ClassMethod GetOutdatedModulesList(Output list)
+{
+ // Get the dependencies list to prevent displaying an outdated list
+ set depRes = ##class(%SQL.Statement).%ExecDirect(,
+ "select ModuleItem->Name ModName,Dependencies_Name DepName,Dependencies_VersionString DepVer "_
+ "from %IPM_Storage.ModuleItem_Dependencies")
+ $$$ThrowSQLIfError(depRes.%SQLCODE, depRes.%Message)
+ while depRes.%Next(.sc) {
+ $$$ThrowOnError(sc)
+ set visitedMap($zconvert(depRes.%Get("DepName"),"l")) = 1
+ }
+ $$$ThrowOnError(sc)
+
+ do ..GetListModules($namespace, , .installedModules)
+ do ..GetUpstreamPackageVersions(.serverModuleVersions)
+
+ set width = 0
+ for i=1:1:installedModules {
+ set moduleInfo = installedModules(i)
+ set moduleName = $listget(moduleInfo)
+
+ // Skip processing if the module is a dependency module
+ if moduleName="zpm"||($data(visitedMap(moduleName))) {
+ continue
+ }
+
+ set currentVersion = $listget(moduleInfo,2)
+ if $data(serverModuleVersions(moduleName)) {
+ set reg = $order(serverModuleVersions(moduleName,""),1,versionString)
+ if currentVersion'=versionString {
+ set currentwidth = $length(moduleName)
+ set list($increment(list)) = $listbuild(moduleName,$$$FormattedLine($$$Red, currentVersion)_" "_$$$FormattedLine($$$Green,versionString))
+ if widthW")
+ set currentVersion = $piece(cleanString, " ", 1)
+ set serverVersion = $piece(cleanString, " ", 2)
+ if (moduleName = currentModuleName) {
+ set found = 1
+ }
+ if currentVersion'=serverVersion {
+ do $$$AssertNotEquals(currentVersion, serverVersion, "Version mismatch detected for "_moduleName)
+ do $$$LogMessage(currentVersion_" "_serverVersion)
+ do $$$LogMessage("Currently installed "_currentModuleName_" (local:"_currentVersion_") has a newer version available (server:"_serverVersion_")")
+ }
+ }
+ do $$$AssertTrue(found, "The module "_moduleName_" was found in the outdated list")
+ do ..RunCommand("list -o")
+}
+
}