-
Notifications
You must be signed in to change notification settings - Fork 27
feat(cli): add -outdated modifier in list command #1095
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
2029db0
42d3684
265414b
c71fcf3
269c97b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -526,6 +526,9 @@ reinstall -env /path/to/env1.json;/path/to/env2.json example-package | |
| <example description="Shows all installed Python packages."> | ||
| list -python | ||
| </example> | ||
| <example description="Lists all installed modules with available updates in the registry."> | ||
| list -outdated | ||
| </example> | ||
|
|
||
| <!-- Parameters --> | ||
| <parameter name="searchString" description="Search string, * can be used." /> | ||
|
|
@@ -538,6 +541,7 @@ reinstall -env /path/to/env1.json;/path/to/env2.json example-package | |
| <modifier name="showupstream" aliases="su" description="If specified, show the latest version for each module in configured repos if it's different than the local version." /> | ||
| <modifier name="repository" aliases="repo" value="true" description="If specified, only show modules installed that belong to the provided repository." /> | ||
| <modifier name="python" aliases="py" description="If specified, lists installed Embedded Python libraries instead of IPM modules." /> | ||
| <modifier name="outdated" aliases="o" description="If specified, only lists installed modules that have available updates in the registry. Modules installed as dependencies are skipped." /> | ||
| </command> | ||
|
|
||
| <command name="list-dependents" aliases="dependents"> | ||
|
|
@@ -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))) { | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Skipping of dependencies should be an optional flag. The default should be to list all outdated modules in the namespace. |
||
| 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)) | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Similar to |
||
| if width<currentwidth { | ||
| set width = currentwidth | ||
| } | ||
| } | ||
| } | ||
| } | ||
| set list("width") = width | ||
| } | ||
|
|
||
| ClassMethod GetPythonInstalledLibs(Output list) | ||
| { | ||
| set target = ##class(%File).NormalizeDirectory("python", $system.Util.ManagerDirectory()) | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -352,4 +352,43 @@ Method TestUninstallWithoutModuleName() | |
| do $$$AssertNotTrue(exists, "Module removed successfully.") | ||
| } | ||
|
|
||
| /// Validates that the '-outdated' modifier correctly identifies and displays modules with newer registry versions | ||
| Method TestListOutdatedModules() | ||
| { | ||
| set moduleName = "irisjwt" | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should probably add a test with more than one module and one with dependencies. |
||
| if $isobject(##class(%IPM.Storage.Module).NameOpen(moduleName)) { | ||
| do $$$LogMessage(moduleName_" already exist. So uninstalling the module") | ||
| do ..RunCommand("uninstall "_moduleName) | ||
| } | ||
|
|
||
| set status = ..RunCommand("install "_moduleName_" 1.0.0") | ||
| do $$$AssertStatusOK(status, moduleName_" installed at version 1.0.0") | ||
| do ##class(%IPM.Main).GetOutdatedModulesList(.list) | ||
|
|
||
| set found = 0 | ||
| for i=1:1:list { | ||
| set moduleInfo = list(i) | ||
| set currentModuleName = $listget(moduleInfo, 1) | ||
| set versionString = $listget(moduleInfo, 2) | ||
|
|
||
| // Scrub ANSI color codes | ||
| set matcher = ##class(%Regex.Matcher).%New("\x1b\[[0-9;]*m", versionString) | ||
| set cleanString = matcher.ReplaceAll("") | ||
|
|
||
| set cleanString = $zstrip(cleanString, "<>W") | ||
| 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") | ||
| } | ||
|
|
||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be nice for the
listto have column headers to display