diff --git a/CHANGELOG.md b/CHANGELOG.md index 3401b442..cc466298 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - #959: In ORAS repos, external name can now be used interchangeably with (default) name for `install` and `update`, i.e. a module published with its (default) name can be installed using its external name. - #951: The `unpublish` command will skip user confirmation prompt if the `-force` flag is provided. - #1018: Require module name for uninstall when not using the -all flag +- #1027: Add -bypass-deps flag to skip install the IPM dependencies ### Changed - #316: All parameters, except developer mode, included with a `load`, `install` or `update` command will be propagated to dependencies diff --git a/src/cls/IPM/Main.cls b/src/cls/IPM/Main.cls index a9392916..bc6da2fc 100644 --- a/src/cls/IPM/Main.cls +++ b/src/cls/IPM/Main.cls @@ -287,7 +287,8 @@ load C:\module\root\path -env C:\path\to\env1.json;C:\path\to\env2.json - + + @@ -414,7 +415,8 @@ install -env /path/to/env1.json;/path/to/env2.json example-package - + + @@ -452,7 +454,8 @@ reinstall -env /path/to/env1.json;/path/to/env2.json example-package - + + diff --git a/src/cls/IPM/Utils/Module.cls b/src/cls/IPM/Utils/Module.cls index 6181ba6f..39b82c4a 100644 --- a/src/cls/IPM/Utils/Module.cls +++ b/src/cls/IPM/Utils/Module.cls @@ -1202,7 +1202,13 @@ ClassMethod LoadNewModule( if $get(params("CreateLockFile"), 0) && '$data(params("LockFileModule")){ set params("LockFileModule") = tModule.Name } - do ..LoadDependencies(tModule, .params) + if $get(params("BypassDeps")) { + if tVerbose { + write !, $$$FormattedLine($$$Yellow,"Skipping installation of IPM dependencies because -bypass-deps is set.") + } + } else { + do ..LoadDependencies(tModule, .params) + } set tSC = $system.OBJ.Load(pDirectory_"module.xml",$select(tVerbose:"d",1:"-d"),,.tLoadedList) $$$ThrowOnError(tSC) diff --git a/tests/unit_tests/Test/PM/Unit/CLI.cls b/tests/unit_tests/Test/PM/Unit/CLI.cls index 7cf0e6ca..f57a9074 100644 --- a/tests/unit_tests/Test/PM/Unit/CLI.cls +++ b/tests/unit_tests/Test/PM/Unit/CLI.cls @@ -315,6 +315,72 @@ Method TestListPython() As %Status quit sc } +/// Verifies the behavior of the -bypass-deps (and alias -bd) flag during the load and install process. +/// Ensures that the primary module is loaded but the dependency resolution graph is skipped. +Method TestByPassIPMDepsModifier() +{ + set testRoot = ##class(%File).NormalizeDirectory($get(^UnitTestRoot)) + set dependencyModules = $listbuild("objectscript-math","LocalizationLab","irisjwt") + + set ptr = 0 + while $listnext(dependencyModules,ptr,module) { + set exists = ##class(%IPM.Storage.Module).NameExists(module) + if exists{ + do $$$AssertTrue(exists, module_" is already installed. So uninstalling for testing -bypass-deps.") + set status = ##class(%IPM.Main).Shell("uninstall "_module) + do $$$AssertStatusOK(status,"Uninstalled module: "_module) + } + } + set moduleStr=""_ + "demo-module11.0.0"_ + "description"_ + "objectscript-math0.0.5LocalizationLab1.0.0"_ + "irisjwt1.0.0"_ + "modulesrc" + set moduleDir = ##class(%File).NormalizeDirectory(##class(%File).GetDirectory(testRoot)_"/_data/bypass-deps/") + + if '##class(%File).Exists(moduleDir) { + set status = ##class(%File).CreateDirectoryChain(moduleDir,.status) + do $$$AssertStatusOK(status,"Created module.xml file in directory: "_moduleDir) + set fileStream = ##class(%Stream.FileBinary).%New() + set fileStream.Filename = ##class(%File).NormalizeFilename("module.xml",moduleDir) + do fileStream.Write(moduleStr) + set status = fileStream.%Save() + do $$$AssertStatusOK(status,"module file created on directory "_moduleDir) + } + set status = ##class(%IPM.Main).Shell("load " _ moduleDir_" -bypass-deps") + do $$$AssertStatusOK(status,"Loaded SimpleApp demo-module1 with -bypass-deps successfully." _ moduleDir) + + do $$$LogMessage("Verifying that dependencies were not installed...") + set ptr=0 + while $listnext(dependencyModules,ptr,module) { + set found = 0 + set exists = ##class(%IPM.Storage.Module).NameExists(module) + do $$$AssertTrue('exists, "Dependency module '"_module_"' not installed when loading with -bypass-deps.") + } + + do $$$LogMessage("Now loading the module without -bypass-deps to verify dependencies get installed...") + + // Now load again without -bypass-deps to verify dependencies get installed + set status = ##class(%IPM.Main).Shell("load " _ moduleDir) + do $$$AssertStatusOK(status,"Module demo-module1 is loaded without -bypass-deps") + + set ptr=0 + while $listnext(dependencyModules,ptr,module) { + set found = 0 + set exists = ##class(%IPM.Storage.Module).NameExists(module) + do $$$AssertTrue(exists, "Dependency module '"_module_"' should be installed when loading without -bypass-deps.") + } + + do $$$LogMessage("uninstalling the demo-module1 and its dependencies...") + set status = ##class(%IPM.Main).Shell("uninstall demo-module1 -r") + do $$$AssertStatusOK(status,"Uninstalled demo-module1 and its dependencies successfully.") + + do $$$LogMessage("Deleting the created directory...") + set status = ##class(%File).RemoveDirectoryTree(moduleDir) + do $$$AssertStatusOK(status, "Directory deleted successfully") +} + Method TestUninstallWithoutModuleName() { do $$$LogMessage("Run Uninstall command without module name")