Skip to content
Merged
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 @@ -18,6 +18,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Edits to a decomposed production in VS Code fixed after changes to the VS Code ObjectScript extension (#949)
- Configure prompt no longer quits out with an unhelpful error if existing boolean settings are null (#962)
- Branch names are now constrained to a reasonable set of allowed characters, fixing an issue where branch names with special characters were hidden without explanation (#914)
- PTD documents that are not decomposed production items may now be added to source control (#965)

## [2.16.0] - 2026-03-06

Expand Down
6 changes: 6 additions & 0 deletions cls/SourceControl/Git/Production.cls
Original file line number Diff line number Diff line change
Expand Up @@ -726,6 +726,12 @@ ClassMethod CreateInternalName(productionName As %String = "", itemName As %Stri
)
}

/// Returns true if the PTD document with given internal name should be treated as a decomposed production item.
ClassMethod IsPTDDecomposedProductionItem(internalName) As %Boolean
{
return internalName [ "||"
}

/// Given an external name for a PTD item, removes that item from the production.
ClassMethod RemoveItemByExternalName(externalName As %String, nameMethod As %String) As %Status
{
Expand Down
6 changes: 4 additions & 2 deletions cls/SourceControl/Git/PullEventHandler/IncrementalLoad.cls
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ Method OnPull() As %Status
set delList(delIndex, internalName) = tExternalName
} else {
set nFiles = nFiles + 1
if (##class(SourceControl.Git.Utils).Type(internalName) = "ptd") {
if (##class(SourceControl.Git.Utils).Type(internalName) = "ptd") && ##class(SourceControl.Git.Production).IsPTDDecomposedProductionItem(internalName) {
set ptdList(internalName) = ""
} else {
set compilelist(internalName) = ""
Expand Down Expand Up @@ -78,7 +78,9 @@ Method OnPull() As %Status
set start = $zhorolog
set key = $order(ptdList(""))
while (key '= "") {
set sc = $$$ADDSC(sc, ##class(SourceControl.Git.Utils).ImportItem(key,1))
if ##class(SourceControl.Git.Production).IsPTDDecomposedProductionItem(key) {
set sc = $$$ADDSC(sc, ##class(SourceControl.Git.Utils).ImportItem(key,1))
}
set key = $order(ptdList(key))
}
write !,"Production items imported in ",($zhorolog-start),"s"
Expand Down
15 changes: 8 additions & 7 deletions cls/SourceControl/Git/Utils.cls
Original file line number Diff line number Diff line change
Expand Up @@ -1481,7 +1481,7 @@ ClassMethod ImportItem(InternalName As %String, force As %Boolean = 0, verbose A
set type = ..Type(InternalName)
set imported = 1
if ..IsRoutineOutdated(InternalName) || force || (type = "ptd"){
if (type = "ptd") && settings.decomposeProductions && ##class(%Library.EnsembleMgr).IsEnsembleNamespace() {
if (type = "ptd") && settings.decomposeProductions && ##class(%Library.EnsembleMgr).IsEnsembleNamespace() && ##class(SourceControl.Git.Production).IsPTDDecomposedProductionItem(InternalName) {
if ##class(%File).Exists(filename) {
// Deployment manager should not reexport because studio project file includes timestamp
// ideally we could just new %SourceControl, but Ens portal config pages do not use %SourceControl
Expand Down Expand Up @@ -1595,9 +1595,11 @@ ClassMethod ListItemsInFiles(ByRef itemList, ByRef err) As %Status
if (mappingFileType = "/CSP/") {
do ..ListItemsRecursively(mappingFileType,"*",mappedFilePath,.itemList)
} elseif ..UserTypeCached("foo."_mappingFileType, .userTypeClass) {
set fileSpec = $select(
userTypeClass="Ens.Util.ProjectTextDocument": "*.xml;*.XML",
1: "*."_$zcvt(mappingFileType,"L")_";*."_$zconvert(mappingFileType,"U"))
set fileSpec = "*."_$zcvt(mappingFileType,"L")_";*."_$zconvert(mappingFileType,"U")
// PTDs may be decomposed production items, which are represented as xml
if (userTypeClass="Ens.Util.ProjectTextDocument") {
set fileSpec = fileSpec _ ";*.xml;*.XML"
}
do ..ListItemsRecursively(mappingFileType, fileSpec, mappedFilePath, .itemList)
} else {
set res = $system.OBJ.ImportDir(mappedFilePath,,"-d",.err,1, .tempItemList, $$$DoNotLoad)
Expand Down Expand Up @@ -1795,7 +1797,7 @@ ClassMethod ExportItem(InternalName As %String, expand As %Boolean = 1, force As
quit $$$OK
}
write !, "exporting new version of ", InternalName, " to ", filename
if (type = "ptd") {
if (type = "ptd") && (##class(SourceControl.Git.Production).IsPTDDecomposedProductionItem(InternalName)) {
$$$QuitOnError(##class(SourceControl.Git.Production).ExportPTD(InternalName,"FullExternalName"))
} elseif (..ItemIsProductionToDecompose(InternalName, .productionName)) {
write !, "Production decomposition enabled, skipping export of production class"
Expand Down Expand Up @@ -2559,7 +2561,7 @@ ClassMethod Name(InternalName As %String, ByRef MappingExists As %Boolean) As %S
// If no specific mapping was specified (p=""), then return the whole csp filename; otherwise return the name without the mapped piece
set relativeInternalName=$extract(InternalName,$length(p)+2,*)
quit $translate(found_$translate(relativeInternalName,"%","_"),"\","/")
} elseif (..Type(InternalName) = "ptd") {
} elseif (..Type(InternalName) = "ptd") && ##class(SourceControl.Git.Production).IsPTDDecomposedProductionItem(InternalName) {
do ##class(SourceControl.Git.Production).ParseInternalName(InternalName,'default,.filename)
return $translate(found_filename, "\","/")
} elseif ext="CLS"||(ext="PRJ")||usertype {
Expand Down Expand Up @@ -3417,4 +3419,3 @@ ClassMethod IsSchemaStandard(pName As %String = "") As %Boolean [ Internal ]
}

}

10 changes: 10 additions & 0 deletions test/UnitTest/SourceControl/Git/ProductionDecomposition.cls
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,16 @@ Method TestImportItemsWithError()
do $$$AssertStatusOK(##class(SourceControl.Git.Utils).ImportItem("UnitTest.SampleProduction||Settings-a|Ens.Activity.Operation.Local.PTD"))
}

/// PTD documents that do not represent decomposed production items may be added to source control as .PTD files
Method TestNonHostPTD()
{
do ##class(Ens.Util.ProjectTextDocument).Delete("UnitTest.SourceControl.Git.SamplePTD.PTD")
$$$ThrowOnError(##class(Ens.Util.ProjectTextDocument).Create("Some text","UnitTest.SourceControl.Git.SamplePTD","Descriptive text"))
do $$$AssertStatusOK(##class(SourceControl.Git.Utils).AddToSourceControl("UnitTest.SourceControl.Git.SamplePTD.PTD"))
do $$$AssertTrue(##class(SourceControl.Git.Utils).IsInSourceControl("UnitTest.SourceControl.Git.SamplePTD.PTD"))
do $$$AssertEquals(##class(SourceControl.Git.Utils).Name("UnitTest.SourceControl.Git.SamplePTD.PTD"),"ptd/UnitTest/SourceControl/Git/SamplePTD.ptd")
}

ClassMethod ReplaceProductionDefinition(pXDataName)
{
new %SourceControl
Expand Down
Loading