From 4627d0c07fa71b9dc1f47682dd649b53e547ff9f Mon Sep 17 00:00:00 2001 From: Emma Neil Date: Thu, 31 Oct 2024 15:10:06 -0400 Subject: [PATCH] HSIEO-11006: Fix conditions for marking code as deployed --- CHANGELOG.md | 1 + src/cls/IPM/Lifecycle/Base.cls | 70 ++++++++++++++++++++++++-------- src/cls/IPM/Lifecycle/Module.cls | 10 ----- src/cls/IPM/Main.cls | 18 +++++++- src/cls/IPM/Storage/Module.cls | 12 +++++- 5 files changed, 79 insertions(+), 32 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 158a2472..29af85a9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - #454: IPM 0.9.x+ uses different globals for storage vs. 0.7.0 and previous. Installation will automatically migrate data from the old globals to the new ones. The old globals are left around in case the user decides to revert to an earlier version. ### Fixed +- HSIEO-11006: Fix conditions for marking code as deployed - HSIEO-9269, HSIEO-9402: % percent perforce directories are no longer necessary - HSIEO-9269, HSIEO-9404: Repo check should happen in the order to repo creation, not by repo name - HSIEO-9269, HSIEO-9411: Make sure can load and export xml Package-type resource diff --git a/src/cls/IPM/Lifecycle/Base.cls b/src/cls/IPM/Lifecycle/Base.cls index 4662e01a..866ed30c 100644 --- a/src/cls/IPM/Lifecycle/Base.cls +++ b/src/cls/IPM/Lifecycle/Base.cls @@ -55,8 +55,11 @@ Method OnAfterResourceProcessing(pPhase As %String, ByRef pParams) As %Status Method %DispatchMethod(pMethod As %String, ByRef pParams, Args...) [ ServerOnly = 1 ] { - if $listfind(..#PHASES,pMethod)=0 do $zu(96,3,$$$ERNOMETHOD,1,"","method "_pMethod_" of class "_$classname()) - quit ..Module.ExecutePhases(..Module.Name,$lb(pMethod),1,.pParams) + // Match method name with CamelCased lifecycle method + set convertedMethod = ..MatchSinglePhase(pMethod) + + if $listfind(..#PHASES,convertedMethod)=0 do $zu(96,3,$$$ERNOMETHOD,1,"","method "_convertedMethod_" of class "_$classname()) + quit ..Module.ExecutePhases(..Module.Name,$lb(convertedMethod),1,.pParams) } /// Merges default parameters into pParams @@ -131,22 +134,48 @@ ClassMethod GetCompletePhases(pPhases As %List) As %List /// This method defines what a complete phase means for a given phase ClassMethod GetCompletePhasesForOne(pOnePhase As %String) As %List { + set pOnePhase = $ZCONVERT(pOnePhase, "L") + + Quit $Case(pOnePhase, + "clean": $ListBuild("Clean"), + "reload": $ListBuild("Reload","*"), + "validate": $ListBuild("Reload","*","Validate"), + "exportdata": $ListBuild("ExportData"), + "compile": $ListBuild("Reload","*","Validate","Compile"), + "activate": $ListBuild("Reload","*","Validate","Compile","Activate"), + "document": $ListBuild("Document"), + "makedeployed": $ListBuild("MakeDeployed"), + "test": $ListBuild("Reload","*","Validate","Compile","Activate","Test"), + "package": $ListBuild("Reload","*","Validate","Compile","Activate","Package"), + "verify": $ListBuild("Reload","*","Validate","Compile","Activate","Package","Verify"), + "register": $ListBuild("Reload","*","Validate","Compile","Activate","Package","Register"), + "publish": $ListBuild("Reload","*","Validate","Compile","Activate","Package","Register","Publish"), + "configure": $ListBuild("Configure"), + "unconfigure": $ListBuild("Unconfigure"), + : "" + ) +} + +/// Match single inputted phase to the correctly CamelCased lifecycle phase
+ClassMethod MatchSinglePhase(pOnePhase As %String) As %String +{ + set pOnePhase = $ZCONVERT(pOnePhase, "L") Quit $Case(pOnePhase, - "Clean": $ListBuild("Clean"), - "Reload": $ListBuild("Reload","*"), - "Validate": $ListBuild("Reload","*","Validate"), - "ExportData": $ListBuild("ExportData"), - "Compile": $ListBuild("Reload","*","Validate","Compile"), - "Activate": $ListBuild("Reload","*","Validate","Compile","Activate"), - "Document": $ListBuild("Document"), - "MakeDeployed": $ListBuild("MakeDeployed"), - "Test": $ListBuild("Reload","*","Validate","Compile","Activate","Test"), - "Package": $ListBuild("Reload","*","Validate","Compile","Activate","Package"), - "Verify": $ListBuild("Reload","*","Validate","Compile","Activate","Package","Verify"), - "Register": $ListBuild("Reload","*","Validate","Compile","Activate","Package","Register"), - "Publish": $ListBuild("Reload","*","Validate","Compile","Activate","Package","Register","Publish"), - "Configure": $ListBuild("Configure"), - "Unconfigure": $ListBuild("Unconfigure"), + "clean": "Clean", + "reload": "Reload", + "validate": "Validate", + "exportdata": "ExportData", + "compile": "Compile", + "activate": "Activate", + "document": "Document", + "makedeployed": "MakeDeployed", + "test": "Test", + "package": "Package", + "verify": "Verify", + "register": "Register", + "publish": "Publish", + "configure": "Configure", + "unconfigure": "Unconfigure", : "" ) } @@ -1400,13 +1429,18 @@ Method %MakeDeployed(ByRef pParams) As %Status Try { Set tDev = ..Module.DeveloperMode Set tVerbose = $Get(pParams("Verbose")) + + // If the recurse parameter is set, then this lifecycle method should recursively deploy all of the + // module's dependencies marked for deployment + Set tLockedDependencies = $Get(pParams("Recurse"),0) // Indicates whether entire dependency graph should be traversed and deployed + If tDev && tVerbose { Write !,"Module is in developer mode; will only report what WOULD be deployed unless packaging, in which case items WILL be deployed." } // Default implementation: see which resources are expicitly flagged with Deploy = true. // Build an array of those, then mark them as deployed. - $$$ThrowOnError(..Module.GetResolvedReferences(.tResourceArray,1,..PhaseList,1,.pDependencyGraph)) + $$$ThrowOnError(..Module.GetResolvedReferences(.tResourceArray,tLockedDependencies,..PhaseList,1,.pDependencyGraph)) Set tResourceKey = "" For { diff --git a/src/cls/IPM/Lifecycle/Module.cls b/src/cls/IPM/Lifecycle/Module.cls index 74ec785e..69dfbb42 100644 --- a/src/cls/IPM/Lifecycle/Module.cls +++ b/src/cls/IPM/Lifecycle/Module.cls @@ -38,16 +38,6 @@ Method %Activate(ByRef pParams) As %Status Set tSC = ..Configure(.pParams) $$$ThrowOnError(tSC) - - If '$ListFind(..PhaseList,"Package") { - // Code cannot be deployed if it is to be reexported and packaged. - Set tDevMode = $Get(pParams("DeveloperMode"), ..Module.DeveloperMode) - Set isKitBuild = $Get(pParams("IsKitBuild"),0) - If ('tDevMode && isKitBuild) { - Set tSC = ..MakeDeployed(.pParams) - $$$ThrowOnError(tSC) - } - } // Create Studio project for package if it is loaded in developer mode and no explicit statement to not create it Set tNoStudioProject = $Get(pParams("NoStudioProject"), 0) diff --git a/src/cls/IPM/Main.cls b/src/cls/IPM/Main.cls index 547af35f..8d1e47eb 100644 --- a/src/cls/IPM/Main.cls +++ b/src/cls/IPM/Main.cls @@ -7,7 +7,7 @@ Class %IPM.Main Extends %IPM.CLI Parameter DOMAIN = "ZPM"; -Parameter STANDARDPHASES = {$ListBuild("reload","compile","test","package","verify","publish")}; +Parameter STANDARDPHASES = {$ListBuild("reload","compile","test","package","verify","publish","makedeployed")}; /// Description of commands to use for this CLI XData Commands [ XMLNamespace = "http://www.intersystems.com/PackageManager/CLI" ] @@ -45,6 +45,7 @@ resources exported to the filesystem (and possible to source control) are consis with what is in the database. * compile: compiles all resources within the module. * activate: performs post-compilation installation/configuration steps. +* makedeployed: deploys resources within the module for which deployment is enabled. * document: regenerates the API documentation for the module * test: runs any unit tests associated with the module, in the current namespace. * package: exports the module's resources and bundles them into a module artifact (.tgz file). @@ -156,6 +157,18 @@ This command is an alias for `module-action module-name publish` + + +This command is an alias for `module-action module-name makedeployed` + + + + + + + + + Delete package from registry @@ -2037,7 +2050,8 @@ ClassMethod RunOnePhase(ByRef pCommandInfo) [ Internal ] Set tModName = $Get(pCommandInfo("parameters","module")) Set tPhases = $ListBuild($ZConvert(pCommandInfo, "w")) Set tIsComplete = '$$$HasModifier(pCommandInfo,"only") - Set tParams("cmd") = pCommandInfo + Set tParams("Recurse") = $$$HasModifier(pCommandInfo,"recurse") + Set tParams("cmd") = pCommandInfo Merge tParams = pCommandInfo("data") $$$ThrowOnError(##class(%IPM.Storage.Module).ExecutePhases(tModName,tPhases,tIsComplete,.tParams)) } diff --git a/src/cls/IPM/Storage/Module.cls b/src/cls/IPM/Storage/Module.cls index ed5e2300..e74677c1 100644 --- a/src/cls/IPM/Storage/Module.cls +++ b/src/cls/IPM/Storage/Module.cls @@ -257,7 +257,7 @@ ClassMethod ExecutePhases(pModuleName As %String, pPhases As %List, pIsComplete Set tPhases = $ListBuild("PrepareDeploy") _ tPhases } } Else { - Set tPhases = pPhases + Set tPhases = $ListBuild(##class(%IPM.Lifecycle.Base).MatchSinglePhase($LISTTOSTRING(pPhases))) } // Lifecycle-provided default parameters @@ -330,7 +330,7 @@ ClassMethod ExecutePhases(pModuleName As %String, pPhases As %List, pIsComplete Quit } If $IsObject(tResource.Processor) { - Do tResource.Processor.SetParams(.pParams) + Do tResource.Processor.SetParams(.pParams) Set tSC = $Method(tResource.Processor,"OnBeforePhase",tOnePhase,.pParams) $$$ThrowOnError(tSC) } @@ -503,6 +503,7 @@ Method GetDefaultParameters(Output pParams) } } +/// Returns whether pScope is in the list of pPhases
ClassMethod HasScope(pPhases As %List, pScope As %String) [ Private ] { If (pScope = "") { @@ -940,6 +941,13 @@ ClassMethod GetKnownDependencies(pModuleName As %String) As %List Quit tKnownDependencyList } +/// Builds a module's immediate dependency graph and array of resources.
+/// Optionally loads uninstalled dependency modules and recurses over each module in the dependency graph.
+/// @Argument pReferenceArray Array of all module's resources (including resources that compose a resource) that contain the appropriate phase scope.
+/// @Argument pLockedDependencies Whether method should be recursively applied to the module's dependencies (true = yes).
+/// @Argument pPhases List of IPM lifecycle phases to be applied to the current module.
+/// @Argument pSkipDependencies Whether to skip loading uninstalled dependency modules.
+/// @Argument pDependencyGraph Tree of module's dependencies.
Method GetResolvedReferences(Output pReferenceArray, pLockedDependencies As %Boolean = 0, pPhases As %List = "", pSkipDependencies As %Boolean = 0, ByRef pDependencyGraph) As %Status { Set tSC = $$$OK