Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- #950: Added support for listing installed Python packages using `list -python`, `list -py` and `list-installed -python`
- #822: The CPF resource processor now supports system expressions and macros in CPF merge files
- #578 Added functionality to record and display IPM history of install, uninstall, load, and update
- #994: prevent crash when target namespace lacks IPM mappings

### Changed
- #316: All parameters, except developer mode, included with a `load`, `install` or `update` command will be propagated to dependencies
Expand Down
25 changes: 22 additions & 3 deletions src/cls/IPM/Main.cls
Original file line number Diff line number Diff line change
Expand Up @@ -1076,7 +1076,11 @@ ClassMethod Namespace(ByRef pCommandInfo) [ Internal ]
set name = $translate($get(pCommandInfo("parameters","name"),"*"),$char(34))
if (name'["*") {
try {
set $namespace = name
if '..IsIPMEnabled(name) {
write $$$FormattedLine($$$Red," IPM is not enabled in this namespace.")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Include name in the message

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Included the name in the message!

} else {
set $namespace = name
}
} catch ex {
$$$ThrowStatus($$$ERROR($$$GeneralError,"Failed to switch to namespace: " _ name))
}
Expand All @@ -1099,7 +1103,14 @@ ClassMethod Namespace(ByRef pCommandInfo) [ Internal ]
do ##class(%Library.Prompt).GetString(prompt, .value)
quit:value=""
try {
set $namespace = $select($data(list(value), ns): $listget(ns), 1: value)
set selectedNamespace = $select($data(list(value), ns): $listget(ns), 1: value)
if '..IsIPMEnabled(selectedNamespace) {
write $$$FormattedLine($$$Red," IPM is not enabled in this namespace.")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: include name in message. Also, is the space before the word "IPM" intentional?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the feed back!.

Yes, the space before “IPM” is intentional. The message is displayed on the same line after the namespace selection. Without the space, it would appear as:

Enter number or name where to go: 1IPM is not enabled in this %SYS namespace.

By adding the space, the message is displayed clearly as:

Enter number or name where to go: 1 IPM is not enabled in this %SYS namespace.

hang 0.5
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the purpose of the hang? Its generally not great practice to have hangs (exceptions are for polling purposes)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @isc-kiyer
The purpose of the hang is to ensure the error message is visible to the user. Without the hang, the message IPM is not enabled in this namespace disappears immediately. Adding a 0.5-second hang allows the message to be displayed long enough for the user to notice and read it.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@AshokThangavel Ah right. I think it may be a better user experience to accumulate all namespaces where IPM is not enabled and print it at the end instead of them needing to hunt for lines in between possibly long output.

Copy link
Contributor Author

@AshokThangavel AshokThangavel Jan 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the feedback. However, the namespace, zn command already displays the ZPM-enabled details. The crash occurs only when we attempt to select a namespace where IPM is not enabled.

zpm:USER>zn

 1. %SYS>                
 2. USER>                zpm               0.10.5-SNAPSHOT
                         testify           1.0.2
                         web-fslog         1.0.2
                         objectscript-math 0.0.5
 3. USER-VERIFY>         zpm               0.10.5-SNAPSHOT
 4. USER-VERIFY-HISTORY> simplest-module   1.0.0
 5. USER-VERIFY-VERIFY>  testmodule        1.0.0

As you suggested, Can we display this existing message at the end by default

%SYS>zpm

IPM is not enabled in this namespace.
Change namespace to one of the following to run the "zpm" command
USER>                zpm 0.10.5-SNAPSHOT
USER-VERIFY>         zpm 0.10.5-SNAPSHOT
USER-VERIFY-HISTORY> zpm 0.10.5-SNAPSHOT
                     Installed In: USER-VERIFY 
USER-VERIFY-VERIFY>  zpm 0.10.5-SNAPSHOT
                     Installed In: USER-VERIFY 
https://pm.community.intersystems.com/ - 1.0.6
If you want to map IPM globally, switch to one of the namespaces above and run: zpm "enable -map -globally".
If you want to reset repository and map IPM globally along with repository settings, switch to one of the namespaces above and run: zpm "enable -community".

or simple summary of namespace and whether IPM enabled or not

1. %SYS>                       IPM not enabled
2. USER>                       IPM enabled
....

write $char(13),*27,"[K",*27,"[A"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add a comment if writing out unicode chars. We have the $$$FormattedLine and other macros that add semantic meaning to the chars so see if any of those suffice/add to them (I notice the same pattern is used below so worth fixing it there too)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Unicode escape sequences are used to clear the current line after displaying the error message. Without clearing the line, the message would be repeatedly printed below the prompt, resulting in output such as:

Enter number or name where to go: 1 IPM is not enabled in this %SYS namespace.
Enter number or name where to go: 1 IPM is not enabled in this %SYS namespace.

Since there were no existing macros for clearing the current line, I created a macro ($$$ClearLineAndMoveUp) to encapsulate this behavior. This adds semantic meaning to the escape sequences

continue
}
set $namespace = selectedNamespace
} catch e {
write $char(13),*27,"[K",*27,"[A"
continue
Expand Down Expand Up @@ -3845,7 +3856,8 @@ ClassMethod DisplayModules(
if pNumbered {
write $justify(i, numbersWidth - 2), ". "
}
write $$$FormattedLinePadRight($$$Magenta, tNS _ "> ", nsWidth)
set ipmStatus=$select('..IsIPMEnabled(tNS):"(IPM not enabled)",1:"")
write $$$FormattedLinePadRight($$$Magenta, tNS _ "> "_ipmStatus, nsWidth)
set tPrefix = $justify("", numbersWidth) _ tNS
kill tModulesList
merge tModulesList = pList(i, "modules")
Expand Down Expand Up @@ -3924,6 +3936,13 @@ ClassMethod DisplayModules(
}
}

ClassMethod IsIPMEnabled(pNamespace As %String = {$namespace}) As %Boolean
{
new $namespace
set $namespace = pNamespace
return $system.CLS.IsMthd("%IPM.Main", "Shell")
}

ClassMethod GetUpstreamPackageVersions(Output list)
{
set query = "SELECT %DLIST(Name) AS Repos FROM %IPM_Repo.Definition"
Expand Down