Skip to content

Commit 9161b05

Browse files
committed
Merge branch 'main' into issue-688
2 parents 6c5d44f + 7dabf65 commit 9161b05

File tree

11 files changed

+233
-6
lines changed

11 files changed

+233
-6
lines changed

CHANGELOG.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,17 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8-
## [2.9.1] - Unreleased
8+
## [2.10.0] - Unreleased
9+
10+
### Added
11+
- LoadProductionsFromDirectory method to help custom deployment scripts load decomposed productions from the repository (#670)
912

1013
### Fixed
1114
- Fixed not showing warnings on Studio (#660)
1215
- Fixed business processes and rules not being added to source control automatically (#676)
1316
- Embedded Git commits settings when cloning empty repo to avert any issues
17+
- Fixed Import All options not importing the Embedded Git configuration file
18+
- Improved performance of IDE editing and baselining of decomposed productions
1419
- Fixed Discard / Stash not working on deletes (#688)
1520

1621
## [2.9.0] - 2025-01-09

cls/SourceControl/Git/API.cls

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,4 +82,12 @@ ClassMethod BaselineProductions()
8282
do ##class(SourceControl.Git.Util.Production).BaselineProductions()
8383
}
8484

85+
/// Given the path to a directory that contains production items, this method will import them all
86+
/// and delete any custom items from the production configuration that do not exist in the directory.
87+
/// This method may be called on a namespace that is not configured with Embedded Git for source control.
88+
ClassMethod LoadProductionsFromDirectory(pDirectoryName, Output pFailedItems) As %Status
89+
{
90+
return ##class(SourceControl.Git.Util.Production).LoadProductionsFromDirectory(pDirectoryName, .pFailedItems)
91+
}
92+
8593
}

cls/SourceControl/Git/Extension.cls

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -356,12 +356,15 @@ Method OnAfterSave(InternalName As %String, Object As %RegisteredObject = {$$$NU
356356
$$$ThrowOnError(##class(SourceControl.Git.Utils).DeleteExternalFile(key))
357357
}
358358
} elseif '..IsInSourceControl(key) {
359-
$$$ThrowOnError(##class(SourceControl.Git.Utils).AddToSourceControl(key))
359+
$$$ThrowOnError(##class(SourceControl.Git.Utils).AddToSourceControl(key,0))
360360
} else {
361361
$$$ThrowOnError(..OnAfterSave(key))
362362
}
363363
set key = $order(productionItems(key))
364364
}
365+
if $data(productionItems) {
366+
do ##class(SourceControl.Git.Change).RefreshUncommitted(,,,1)
367+
}
365368
}
366369
if ..IsInSourceControl(InternalName) {
367370
if fromWebApp {

cls/SourceControl/Git/Util/Production.cls

Lines changed: 76 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,13 @@ ClassMethod BaselineProduction(productionName, settings As SourceControl.Git.Set
1818
$$$ThrowOnError(st)
1919
set key = $order(itemInternalNames(""))
2020
while (key '= "") {
21-
set st = ##class(SourceControl.Git.Utils).AddToSourceControl(key)
21+
set st = ##class(SourceControl.Git.Utils).AddToSourceControl(key,0)
2222
$$$ThrowOnError(st)
2323
set key = $order(itemInternalNames(key))
2424
}
25+
if $data(itemInternalNames) {
26+
do ##class(SourceControl.Git.Change).RefreshUncommitted(,,,1)
27+
}
2528
} else {
2629
write !, "Exporting production in class format: " _ productionInternalName
2730
set st = ##class(SourceControl.Git.Utils).AddToSourceControl(productionInternalName)
@@ -70,4 +73,76 @@ ClassMethod ItemIsPTD(externalName) As %Boolean
7073
return 0
7174
}
7275

76+
/// Given the path to a directory that contains production items, this method will import them all
77+
/// and delete any custom items from the production configuration that do not exist in the directory.
78+
/// This method may be called on a namespace that is not configured with Embedded Git for source control.
79+
ClassMethod LoadProductionsFromDirectory(pDirectoryName, Output pFailedItems) As %Status
80+
{
81+
set st = $$$OK
82+
try {
83+
set rs = ##class(%File).FileSetFunc(pDirectoryName,,,1)
84+
throw:rs.%SQLCODE<0 ##class(%Exception.SQL).CreateFromSQLCODE(rs.%SQLCODE,rs.%Message)
85+
kill itemsOnDisk
86+
while rs.%Next() {
87+
continue:rs.Type'="D"
88+
set rs2 = ##class(%File).FileSetFunc(rs.Name,"*.xml",,0)
89+
throw:rs2.%SQLCODE<0 ##class(%Exception.SQL).CreateFromSQLCODE(rs2.%SQLCODE,rs2.%Message)
90+
while rs2.%Next() {
91+
set filePath = rs2.Name
92+
$$$ThrowOnError(##class(SourceControl.Git.Production).ParseExternalName(filePath,.internalName))
93+
set itemName = "", itemClassName = "", productionName = ""
94+
do ##class(SourceControl.Git.Production).ParseInternalName(internalName,,,.itemName,.itemClassName,.productionName)
95+
quit:productionName=""
96+
if (itemName'="") && (itemClassName'="") {
97+
set itemsOnDisk(productionName, itemName, itemClassName) = 1
98+
}
99+
// if production does not exist, create it
100+
if '$isobject(##class(Ens.Config.Production).%OpenId(productionName)) {
101+
$$$ThrowOnError(##class(SourceControl.Git.Production).CreateProduction(productionName))
102+
}
103+
set st = ##class(SourceControl.Git.Production).ImportPTD(filePath, productionName)
104+
if $$$ISERR(st) {
105+
set pFailedItems(filePath) = st
106+
}
107+
}
108+
}
109+
// handle deletes by iterating through XDATA of each production class. for every config item that is not in itemsOnDisk, delete it.
110+
set key = $order(itemsOnDisk(""))
111+
while (key '= "") {
112+
set classDef = ##class(%Dictionary.ClassDefinition).%OpenId(key)
113+
if $isobject(classDef) {
114+
set productionXData = $$$NULLOREF
115+
for i=1:1:classDef.XDatas.Count() {
116+
set xdata = classDef.XDatas.GetAt(i)
117+
if xdata.Name = "ProductionDefinition" {
118+
set productionXData = xdata
119+
quit
120+
}
121+
}
122+
if $isobject(productionXData) {
123+
$$$ThrowOnError(##class(%XML.XPATH.Document).CreateFromStream(productionXData.Data,.xdoc))
124+
$$$ThrowOnError(xdoc.EvaluateExpression("/Production","Item/@Name | Item/@ClassName",.results))
125+
for i=1:2:results.Count() {
126+
set itemName = results.GetAt(i).Value
127+
set itemClassName = results.GetAt(i+1).Value
128+
if (itemName'="") && (itemClassName'="") && '$get(itemsOnDisk(key,itemName, itemClassName)) {
129+
write !, "Removing item from production ", key, ": ", itemName, ":", itemClassName
130+
set internalName = ##class(SourceControl.Git.Production).CreateInternalName(key,itemName, itemClassName)
131+
set st = ##class(SourceControl.Git.Production).RemoveItem(internalName)
132+
if $$$ISERR(st) {
133+
set pFailedItems(itemName, itemClassName) = st
134+
}
135+
}
136+
}
137+
}
138+
}
139+
set key = $order(itemsOnDisk(key))
140+
}
141+
} catch err {
142+
set st = err.AsStatus()
143+
}
144+
if $data(pFailedItems) set st = $$$ADDSC($$$ERROR($$$GeneralError,"Some items failed to deploy."),st)
145+
return st
146+
}
147+
73148
}

cls/SourceControl/Git/Utils.cls

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -772,7 +772,7 @@ ClassMethod AddToServerSideSourceControl(InternalName As %String) As %Status
772772
quit ec
773773
}
774774

775-
ClassMethod AddToSourceControl(InternalName As %String) As %Status
775+
ClassMethod AddToSourceControl(InternalName As %String, refreshUncommitted As %Boolean = 1) As %Status
776776
{
777777
do ##class(SourceControl.Git.PackageManagerContext).ForInternalName(InternalName)
778778
set settings = ##class(SourceControl.Git.Settings).%New()
@@ -809,7 +809,9 @@ ClassMethod AddToSourceControl(InternalName As %String) As %Status
809809

810810
}
811811
}
812-
do ##class(SourceControl.Git.Change).RefreshUncommitted(,,,1)
812+
if refreshUncommitted {
813+
do ##class(SourceControl.Git.Change).RefreshUncommitted(,,,1)
814+
}
813815
quit ec
814816
}
815817

@@ -1491,6 +1493,12 @@ ClassMethod ListItemsInFiles(ByRef itemList, ByRef err) As %Status
14911493
{
14921494
#define DoNotLoad 1
14931495
set res = $$$OK
1496+
1497+
// Config file may exist at the root of the Git repo.
1498+
set configFilePath = ##class(%File).NormalizeFilename(##class(SourceControl.Git.Settings.Document).#EXTERNALNAME, ..TempFolder())
1499+
if ##class(%File).Exists(##class(%File).NormalizeFilename(configFilePath)) {
1500+
set itemList(..NameToInternalName(configFilePath)) = ""
1501+
}
14941502

14951503
set mappingFileType = $order($$$SourceMapping(""))
14961504
while (mappingFileType '= "") {

module.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
<Document name="git-source-control.ZPM">
44
<Module>
55
<Name>git-source-control</Name>
6-
<Version>2.9.1</Version>
6+
<Version>2.10.0</Version>
77
<Description>Server-side source control extension for use of Git on InterSystems platforms</Description>
88
<Keywords>git source control studio vscode</Keywords>
99
<Packaging>module</Packaging>

test/UnitTest/SourceControl/Git/Util/Production.cls

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,22 @@ Method TestItemIsPTD()
1515
do $$$AssertTrue(##class(SourceControl.Git.Util.Production).ItemIsPTD("ptd2\test.xml"))
1616
}
1717

18+
Method TestLoadProductionsFromDirectory()
19+
{
20+
// load a production from a class file under resources
21+
set packageRoot = ##class(SourceControl.Git.PackageManagerContext).ForInternalName("git-source-control.zpm").Package.Root
22+
$$$ThrowOnError($System.OBJ.Load(packageRoot_"test/_resources/cls/UnitTest/SampleProduction.cls","ck"))
23+
// call LoadProductionsFromDirectory on a directory under resources/ptd
24+
do $$$AssertStatusOK(##class(SourceControl.Git.Util.Production).LoadProductionsFromDirectory(packageRoot_"test/_resources/ptd"))
25+
// confirm items were deleted and added
26+
set itemA = ##class(Ens.Config.Production).OpenItemByConfigName("UnitTest.SampleProduction||a")
27+
do $$$AssertNotTrue($isobject(itemA),"item a was deleted")
28+
set itemB = ##class(Ens.Config.Production).OpenItemByConfigName("UnitTest.SampleProduction||b")
29+
do $$$AssertEquals(itemB.Settings.GetAt(1).Value,71)
30+
set itemB = ##class(Ens.Config.Production).OpenItemByConfigName("UnitTest.SampleProduction||c")
31+
do $$$AssertTrue($isobject(itemB),"item a was created")
32+
}
33+
1834
Method OnBeforeAllTests() As %Status
1935
{
2036
merge ..Mappings = @##class(SourceControl.Git.Utils).MappingsNode()
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
Class UnitTest.SampleProduction Extends Ens.Production
2+
{
3+
4+
XData ProductionDefinition
5+
{
6+
<Production Name="UnitTest.SampleProduction" LogGeneralTraceEvents="false">
7+
<Item Name="a" Category="" ClassName="Ens.Activity.Operation.Local" PoolSize="1" Enabled="true" Foreground="false" Comment="" LogTraceEvents="false" Schedule="">
8+
<Setting Target="Host" Name="RecordStatsInterval">60</Setting>
9+
</Item>
10+
<Item Name="b" Category="" ClassName="Ens.Activity.Operation.Local" PoolSize="1" Enabled="true" Foreground="false" Comment="" LogTraceEvents="false" Schedule="">
11+
<Setting Target="Host" Name="RecordStatsInterval">61</Setting>
12+
</Item>
13+
</Production>
14+
}
15+
16+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<Export generator="IRIS" version="26">
3+
<Project name="ProductionSettings-UnitTest_SampleProduction" LastModified="1841-01-01 00:00:00.0000000">
4+
<Items>
5+
<ProjectItem name="EnsExportNotes.ProductionSettings-UnitTest_SampleProduction.PTD" type="PTD"></ProjectItem>
6+
<ProjectItem name="ProductionSettings:UnitTest.SampleProduction.PTD" type="PTD"></ProjectItem>
7+
</Items>
8+
</Project>
9+
10+
11+
<Document name="EnsExportNotes.ProductionSettings-UnitTest_SampleProduction.PTD"><ProjectTextDocument name="EnsExportNotes.ProductionSettings-UnitTest_SampleProduction" description="Export Notes for export ProductionSettings-UnitTest_SampleProduction">
12+
<![CDATA[<Deployment>
13+
<Creation>
14+
<SourceProduction>UnitTest.SampleProduction</SourceProduction>
15+
<UTC>1841-01-01 00:00:00.000</UTC>
16+
</Creation>
17+
<Notes>
18+
</Notes>
19+
<Contents>
20+
<ExportProject>ProductionSettings-UnitTest_SampleProduction</ExportProject>
21+
<Item num="1">ProductionSettings:UnitTest.SampleProduction.PTD</Item>
22+
</Contents>
23+
<ProductionClassInExport></ProductionClassInExport>
24+
</Deployment>
25+
26+
]]></ProjectTextDocument>
27+
</Document>
28+
29+
<Document name="ProductionSettings:UnitTest.SampleProduction.PTD"><ProjectTextDocument name="ProductionSettings:UnitTest.SampleProduction" description="Settings for production UnitTest.SampleProduction">
30+
<![CDATA[<Production Name='UnitTest.SampleProduction' LogGeneralTraceEvents='false'/>
31+
]]></ProjectTextDocument>
32+
</Document></Export>
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<Export generator="IRIS" version="26">
3+
<Project name="Settings-b" LastModified="1841-01-01 00:00:00.0000000">
4+
<Items>
5+
<ProjectItem name="EnsExportNotes.Settings-b.PTD" type="PTD"></ProjectItem>
6+
<ProjectItem name="Settings:b.PTD" type="PTD"></ProjectItem>
7+
</Items>
8+
</Project>
9+
10+
11+
<Document name="EnsExportNotes.Settings-b.PTD"><ProjectTextDocument name="EnsExportNotes.Settings-b" description="Export Notes for export Settings-b">
12+
<![CDATA[<Deployment>
13+
<Creation>
14+
<SourceProduction>UnitTest.SampleProduction</SourceProduction>
15+
<UTC>1841-01-01 00:00:00.000</UTC>
16+
</Creation>
17+
<Notes>
18+
</Notes>
19+
<Contents>
20+
<ExportProject>Settings-b</ExportProject>
21+
<Item num="1">Settings:b.PTD</Item>
22+
</Contents>
23+
<ProductionClassInExport></ProductionClassInExport>
24+
</Deployment>
25+
26+
]]></ProjectTextDocument>
27+
</Document>
28+
29+
<Document name="Settings:b.PTD"><ProjectTextDocument name="Settings:b" description="Settings for b in Production UnitTest.SampleProduction">
30+
<![CDATA[<Item Name="b" Category="" ClassName="Ens.Activity.Operation.Local" PoolSize="1" Enabled="true" Foreground="false" Comment="" LogTraceEvents="false" Schedule=""><Setting Target="Host" Name="RecordStatsInterval">71</Setting></Item>
31+
]]></ProjectTextDocument>
32+
</Document></Export>

0 commit comments

Comments
 (0)