Skip to content
Open
Show file tree
Hide file tree
Changes from all 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 @@ -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
- #1081: Implement locate-resource command for resource-to-module mapping

### Fixed
- #1001: The `unmap` and `enable` commands will now only activate CPF merge once after all namespaces have been configured instead after every namespace
Expand Down
23 changes: 23 additions & 0 deletions src/cls/IPM/Main.cls
Original file line number Diff line number Diff line change
Expand Up @@ -794,6 +794,13 @@ generate /my/path -export 00000,PacketName2,IgnorePacket2^00000,PacketName3,Igno
<example description="Display the current history retention setting.">config get HistoryRetain</example>
</command>

<command name="locate-resource">
<description>Find the module that owns a specific resource.</description>
<parameter name="resource" required="true" description="resource: The full name of the resource (e.g., My.Class.cls, Utils.inc)." />
<example description="Finds the module containing the specified class.">locate-resource %IPM.Main.cls</example>
<example description="Finds the module containing the specified include file.">locate-resource %IPM.Common.inc</example>
</command>

</commands>
}

Expand Down Expand Up @@ -1082,6 +1089,8 @@ ClassMethod ShellInternal(
do ..Information(.tCommandInfo)
} elseif (tCommandInfo = "history") {
do ..History(.tCommandInfo)
} elseif (tCommandInfo = "locate-resource") {
do ..LocateResource(.tCommandInfo)
}
} catch pException {
if (pException.Code = $$$ERCTRLC) {
Expand Down Expand Up @@ -4171,6 +4180,20 @@ ClassMethod Update(ByRef pCommandInfo)
}
}

ClassMethod LocateResource(ByRef CommandInfo)
{
set resource = $get(CommandInfo("parameters","resource"))
set moduleName = ##class(%IPM.ExtensionBase.Utils).GetHomeModuleName(resource)
if (moduleName="") {
write $$$FormattedLine($$$Red, "Resource '"_ resource_"' is not currently part of an installed module.")
quit
}
set showFields = ""
write !
do ..GetListModules(,moduleName, .list)
do ..DisplayModules(.list,,,, .tModifiers)
}

ClassMethod GetPythonInstalledLibs(Output list)
{
set target = ##class(%File).NormalizeDirectory("python", $system.Util.ManagerDirectory())
Expand Down
19 changes: 19 additions & 0 deletions tests/unit_tests/Test/PM/Unit/CLI.cls
Original file line number Diff line number Diff line change
Expand Up @@ -352,4 +352,23 @@ Method TestUninstallWithoutModuleName()
do $$$AssertNotTrue(exists, "Module removed successfully.")
}

Method TestLocateCommand()
{
do $$$LogMessage("Testing 'locate-resource' alias with .inc resource")
set status = ..RunCommand("locate-resource %IPM.Common.inc")
do $$$AssertStatusOK(status, "Alias 'loc' executed successfully")

do $$$LogMessage("Testing 'locate-resource' command with .cls resource")
set status = ..RunCommand("locate-resource %IPM.Main.cls")
do $$$AssertStatusOK(status, "Command 'locate-resource' executed successfully")

do $$$LogMessage("Testing locate-resource with non-existing resource")
set status = ..RunCommand("locate-resource Test.Sample.inc")
do $$$AssertStatusOK(status, "Gracefully handled non-existing resource")

do $$$LogMessage("Testing locate-resource without required argument")
set status = ..RunCommand("locate-resource")
do $$$AssertStatusNotOK(status, "Handled missing argument")
}

}