Skip to content

Commit cedb88b

Browse files
authored
Merge pull request #476 from intersystems/fix-467-and-others
Various fixes for git pull
2 parents 82d740a + e1ca853 commit cedb88b

File tree

4 files changed

+109
-50
lines changed

4 files changed

+109
-50
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1212
- Allow changing namespaces and IPM package context from web UI (#280)
1313
- Support for editing repo from filesystem perspective via web application (#464)
1414
- Support for downloading a VSCode workspace file from web UI
15+
- IncrementalLoad pull event handler will update the running production, if any (#473)
1516

1617
### Fixed
1718
- Instance wide settings are placed in proper global (#444)
1819
- Avoid delay/errors in loading interop JS when there is a URL prefix (e.g., instance name in multi-instance webserver configuration)
1920
- Added proper JS escaping in sync output
2021
- Added support to switch branch in basic mode from menu (#451)
22+
- Pull event handler will not fail when change set includes unmapped files (#453)
23+
- Pull event handler will attempt compile even if there are failures to load (#457)
24+
- Improved logging in preview and when errors occur via WebSocket commands (#467)
25+
- Fixed pull event handler handling of extremely long class names from diff (#467)
2126

2227
## [2.4.1] - 2024-08-02
2328

cls/SourceControl/Git/PullEventHandler/IncrementalLoad.cls

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,33 +9,38 @@ Parameter DESCRIPTION = "Performs an incremental load and compile of all changes
99

1010
Method OnPull() As %Status
1111
{
12-
set loadSC = $$$OK
12+
set sc = $$$OK
1313
set nFiles = 0
1414

1515
for i=1:1:$get(..ModifiedFiles){
1616
set internalName = ..ModifiedFiles(i).internalName
1717
if ((internalName = "") && (..ModifiedFiles(i).changeType '= "D")) {
1818
write !, ..ModifiedFiles(i).externalName, " was not imported into the database and will not be compiled. "
1919
} elseif (..ModifiedFiles(i).changeType = "D") {
20-
set sc = ..DeleteFile(internalName)
21-
if sc {
20+
set delSC = ..DeleteFile(internalName)
21+
if delSC {
2222
write !, ..ModifiedFiles(i).externalName, " was deleted."
2323
} else {
2424
write !, "WARNING: Deletion of ", ..ModifiedFiles(i).externalName, " failed."
2525
}
2626
} else {
2727
set compilelist(internalName) = ""
2828
set nFiles = nFiles + 1
29-
set loadSC = $$$ADDSC(loadSC,##class(SourceControl.Git.Utils).ImportItem(internalName, 1))
30-
$$$ThrowOnError(loadSC)
29+
set sc = $$$ADDSC(sc,##class(SourceControl.Git.Utils).ImportItem(internalName, 1))
3130
}
3231
}
3332

3433
if (nFiles = 0) {
3534
write !, "Nothing to compile."
3635
quit $$$OK
3736
}
38-
quit $system.OBJ.CompileList(.compilelist, "ck")
37+
set sc = $$$ADDSC(sc,$system.OBJ.CompileList(.compilelist, "ck"))
38+
if $$$comClassDefined("Ens.Director") && ##class(Ens.Director).IsProductionRunning() {
39+
write !,"Updating production... "
40+
set sc = $$$ADDSC(sc,##class(Ens.Director).UpdateProduction())
41+
write "done."
42+
}
43+
quit sc
3944
}
4045

4146
Method DeleteFile(item As %String) As %Status
@@ -71,4 +76,3 @@ Method DeleteFile(item As %String) As %Status
7176
}
7277

7378
}
74-

cls/SourceControl/Git/Utils.cls

Lines changed: 53 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -546,14 +546,19 @@ ClassMethod GetCurrentBranch() As %String
546546

547547
ClassMethod Pull(remote As %String = "origin") As %Status
548548
{
549+
New %gitSCOutputFlag
550+
Set %gitSCOutputFlag = 1
549551
#define Force 1
550552
do ##class(SourceControl.Git.Utils).RunGitCommandWithInput("branch",,.errStream,.outStream,"--show-current")
551553
set branchName = outStream.ReadLine(outStream.Size)
552554
write !, "Pulling from branch: ", branchName
553555
kill errStream, outStream
554556
set returnCode = ..RunGitWithArgs(.errStream, .outStream, "pull", remote, branchName)
555-
556-
w !, "Pull ran with return code: " _ returnCode
557+
write !
558+
do outStream.OutputToDevice()
559+
write !
560+
do errStream.OutputToDevice()
561+
write !, "Pull ran with return code: " _ returnCode
557562
quit $$$OK
558563
}
559564

@@ -626,10 +631,13 @@ ClassMethod ExternalName(InternalName As %String, ByRef MappingExists As %Boolea
626631

627632
ClassMethod AddToServerSideSourceControl(InternalName As %String) As %Status
628633
{
629-
#dim i as %Integer
634+
#dim i as %Integer
630635
#dim ec as %Status = $$$OK
631636
for i = 1:1:$length(InternalName, ",") {
632637
#dim item as %String = ..NormalizeExtension($piece(InternalName, ",", i))
638+
if (item = "") {
639+
continue
640+
}
633641
set @..#Storage@("items", item) = ""
634642
#dim sc as %Status = ..ImportItem(item, 1)
635643
if 'sc {
@@ -1791,12 +1799,16 @@ ClassMethod RunGitCommandWithInput(command As %String, inFile As %String = "", O
17911799
}
17921800
}
17931801
} elseif syncIrisWithCommand {
1794-
do ..PrintStreams(errStream, outStream)
1802+
if '$data(%gitSCOutputFlag)#2 {
1803+
do ..PrintStreams(errStream, outStream)
1804+
}
17951805
set buffer = ##class(SourceControl.Git.Util.Buffer).%New()
17961806
do buffer.BeginCaptureOutput()
17971807
set st = ..SyncIrisWithRepoThroughCommand(.outStream)
17981808
set out = ##class(%Stream.GlobalCharacter).%New()
17991809
do buffer.EndCaptureOutput(.out)
1810+
do outStream.MoveToEnd()
1811+
do errStream.MoveToEnd()
18001812
if $$$ISOK(st) {
18011813
while 'out.AtEnd {
18021814
do outStream.WriteLine(out.ReadLine())
@@ -1836,11 +1848,31 @@ ClassMethod SyncIrisWithRepoThroughCommand(ByRef outStream) As %Status
18361848
}
18371849
} elseif (line [ "|") {
18381850
set externalName = $zstrip($piece(line,"|",1),"<>W")
1839-
set modification = ##class(SourceControl.Git.Modification).%New()
1840-
set modification.changeType = "C"
1841-
set modification.internalName = ##class(SourceControl.Git.Utils).NameToInternalName(externalName,,0)
1842-
set modification.externalName = externalName
1843-
set files($i(files)) = modification
1851+
if $Extract(externalName,1,3) = "..." {
1852+
// For extremely long file names, git may truncate the path.
1853+
// Simplifying assumption: this is a class, because nothing else would have that long a name.
1854+
// In other cases, we'll just end up logging the invalid externalName.
1855+
if $Piece(externalName,".",*) = "cls" {
1856+
set possibleClasses = ..ExpandClasses(externalName)
1857+
set pointer = 0
1858+
while $ListNext(possibleClasses,pointer,class) {
1859+
set modification = ##class(SourceControl.Git.Modification).%New()
1860+
set modification.changeType = "C"
1861+
set modification.internalName = class_".CLS"
1862+
set modification.externalName = ..ExternalName(modification.internalName)
1863+
set files($i(files)) = modification
1864+
}
1865+
} else {
1866+
write !,"WARNING: unable to translate external name ",externalName
1867+
continue
1868+
}
1869+
} else {
1870+
set modification = ##class(SourceControl.Git.Modification).%New()
1871+
set modification.changeType = "C"
1872+
set modification.internalName = ##class(SourceControl.Git.Utils).NameToInternalName(externalName,,0)
1873+
set modification.externalName = externalName
1874+
set files($i(files)) = modification
1875+
}
18441876
}
18451877
}
18461878

@@ -1858,6 +1890,18 @@ ClassMethod SyncIrisWithRepoThroughCommand(ByRef outStream) As %Status
18581890
quit ##class(SourceControl.Git.PullEventHandler).ForModifications(.files)
18591891
}
18601892

1893+
ClassMethod ExpandClasses(externalName As %String) As %List
1894+
{
1895+
set internalName = $Piece(externalName,".",1,*-1)
1896+
set internalName = $Extract(internalName,4,*)
1897+
set internalName = $Translate(internalName,"/\%",".."_..PercentClassReplace())
1898+
&sql(select %DLIST(Name) into :classes from %Dictionary.ClassDefinition where Name like '%'||:internalName)
1899+
if (SQLCODE < 0) {
1900+
Throw ##class(%Exception.SQL).CreateFromSQLCODE(SQLCODE,%msg)
1901+
}
1902+
quit classes
1903+
}
1904+
18611905
ClassMethod ParseDiffStream(stream As %Stream.Object, verbose As %Boolean = 1, Output files)
18621906
{
18631907
kill files

cls/_zpkg/isc/sc/git/Socket.cls

Lines changed: 40 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -11,36 +11,40 @@ Property OriginalDevice;
1111

1212
ClassMethod Run()
1313
{
14-
If %request.Get("method") = "preview" {
15-
set branchName = ##class(SourceControl.Git.Utils).GetCurrentBranch()
16-
do ##class(SourceControl.Git.Utils).RunGitWithArgs(.errStream, .outStream, "fetch")
17-
kill errStream, outStream
18-
do ##class(SourceControl.Git.Utils).RunGitWithArgs(.errStream, .outStream, "log", "HEAD..origin", "--name-status")
19-
do ##class(SourceControl.Git.Utils).PrintStreams(errStream, outStream)
20-
} ElseIf %request.Get("method") = "pull" {
21-
Do ##class(SourceControl.Git.API).Pull()
22-
} ElseIf %request.Get("method") = "init" {
23-
Do ##class(SourceControl.Git.Utils).Init()
14+
If %request.Get("method") = "preview" {
15+
Set branchName = ##class(SourceControl.Git.Utils).GetCurrentBranch()
16+
Write !,"Current branch: ",branchName
17+
Do ##class(SourceControl.Git.Utils).RunGitWithArgs(.errStream, .outStream, "fetch")
18+
Kill errStream, outStream
19+
Do ##class(SourceControl.Git.Utils).RunGitWithArgs(.errStream, .outStream, "log", "HEAD..origin", "--name-status")
20+
Do ##class(SourceControl.Git.Utils).PrintStreams(errStream, outStream)
21+
If (outStream.Size = 0) && (errStream.Size = 0) {
22+
Write !,"Already up to date."
23+
}
24+
} ElseIf %request.Get("method") = "pull" {
25+
Do ##class(SourceControl.Git.API).Pull()
26+
} ElseIf %request.Get("method") = "init" {
27+
Do ##class(SourceControl.Git.Utils).Init()
2428
Write !,"Done."
25-
} ElseIf %request.Get("method") = "clone" {
26-
Set remote = %request.Get("remote")
27-
Do ##class(SourceControl.Git.Utils).Clone(remote)
29+
} ElseIf %request.Get("method") = "clone" {
30+
Set remote = %request.Get("remote")
31+
Do ##class(SourceControl.Git.Utils).Clone(remote)
2832
Write !,"Done."
29-
} ElseIf %request.Get("method") = "sshkeygen" {
30-
Do ##class(SourceControl.Git.Utils).GenerateSSHKeyPair()
33+
} ElseIf %request.Get("method") = "sshkeygen" {
34+
Do ##class(SourceControl.Git.Utils).GenerateSSHKeyPair()
3135
Write !,"Done."
32-
} Else {
33-
Write !!,"Invalid method selected.",!!
34-
}
36+
} Else {
37+
Write !!,"Invalid method selected.",!!
38+
}
3539
}
3640

3741
Method OnPreServer() As %Status
3842
{
39-
If '$System.Security.Check("%Development","USE") {
40-
Quit $$$ERROR($$$AccessDenied)
41-
}
43+
If '$SYSTEM.Security.Check("%Development","USE") {
44+
Quit $$$ERROR($$$AccessDenied)
45+
}
4246
If (%request.Get("$NAMESPACE") '= "") {
43-
Set $Namespace = %request.Get("$NAMESPACE")
47+
Set $NAMESPACE = %request.Get("$NAMESPACE")
4448
}
4549
Quit $$$OK
4650
}
@@ -56,9 +60,11 @@ Method Server() As %Status
5660

5761
// In subclasses: Do Something that produces output to the current device.
5862
// It will be sent back to the client, Base64-encoded, over the web socket connection.
59-
Do ..Run()
63+
Do ..Run()
6064
} Catch e {
6165
Do e.Log()
66+
Write !,"An error occurred. More details can be found in the Application error log."
67+
Write !,$SYSTEM.Status.GetErrorText(e.AsStatus())
6268
Set tSC = e.AsStatus()
6369
}
6470

@@ -77,7 +83,7 @@ Method StartOutputCapture() [ ProcedureBlock = 0 ]
7783
#dim tSC As %Status = $$$OK
7884
#dim tRedirected As %Boolean = 0
7985
Try {
80-
Set %server = $this
86+
Set %server = $THIS
8187
Set ..OriginallyRedirected = 0
8288
Set ..OriginalMnemonic = ""
8389
Set ..OriginalDevice = $IO
@@ -107,27 +113,27 @@ Method StartOutputCapture() [ ProcedureBlock = 0 ]
107113
#; Public entry points for I/O redirection
108114
wstr(s) Do write(s)
109115
Quit
110-
wchr(a) Do write($char(a))
116+
wchr(a) Do write($CHAR(a))
111117
Quit
112118
wnl Do write($$$EOL)
113119
Set $X = 0
114120
Quit
115121
wff Do wnl Quit
116122
wtab(n) New tTab
117-
Set tTab = $J("",$S(n>$X:n-$X,1:0))
123+
Set tTab = $JUSTIFY("",$SELECT(n>$X:n-$X,1:0))
118124
Do write(tTab)
119125
Quit
120126
write(str)
121127
// If there was an argumentless NEW, cache the output and leave it at that.
122128
// This will be output next time there's a write with %server in scope.
123-
If '$IsObject($Get(%server)) {
124-
Set ^||OutputCapture.Cache($i(^||OutputCapture.Cache)) = str
129+
If '$ISOBJECT($GET(%server)) {
130+
Set ^||OutputCapture.Cache($INCREMENT(^||OutputCapture.Cache)) = str
125131
Quit
126132
}
127133

128134
// Restore previous I/O redirection settings.
129135
New tOriginalDevice,i
130-
Set tOriginalDevice = $io
136+
Set tOriginalDevice = $IO
131137
If ##class(%Library.Device).ReDirectIO(0) {
132138
Use tOriginalDevice
133139
}
@@ -138,8 +144,8 @@ write(str)
138144
Do ##class(%Library.Device).ReDirectIO(1)
139145
}
140146

141-
If $Data(^||OutputCapture.Cache) {
142-
For i=1:1:$Get(^||OutputCapture.Cache) {
147+
If $DATA(^||OutputCapture.Cache) {
148+
For i=1:1:$GET(^||OutputCapture.Cache) {
143149
Do reallywrite(^||OutputCapture.Cache(i))
144150
}
145151
Kill ^||OutputCapture.Cache
@@ -155,7 +161,7 @@ write(str)
155161
reallywrite(pString)
156162
New tMsg
157163
Set tMsg = {"content":(pString)} // This is handy because it handles escaping of newlines, etc.
158-
Do %server.Write($System.Encryption.Base64Encode(tMsg.%ToJSON()))
164+
Do %server.Write($SYSTEM.Encryption.Base64Encode(tMsg.%ToJSON()))
159165
Quit
160166
rstr(len, time) Quit ""
161167
rchr(time) Quit ""
@@ -179,7 +185,7 @@ Method EndOutputCapture()
179185

180186
Method SendJSON(pObject As %DynamicAbstractObject)
181187
{
182-
Set tOriginalDevice = $io
188+
Set tOriginalDevice = $IO
183189
If ##class(%Library.Device).ReDirectIO(0) {
184190
Use tOriginalDevice
185191
}
@@ -189,7 +195,7 @@ Method SendJSON(pObject As %DynamicAbstractObject)
189195
If ..OriginallyRedirected {
190196
Do ##class(%Library.Device).ReDirectIO(1)
191197
}
192-
Do ..Write($System.Encryption.Base64Encode(pObject.%ToJSON()))
198+
Do ..Write($SYSTEM.Encryption.Base64Encode(pObject.%ToJSON()))
193199
Do ##class(%Library.Device).ReDirectIO(1)
194200
Use tOriginalDevice::("^"_$ZNAME)
195201
}

0 commit comments

Comments
 (0)