Skip to content

Commit 7ab34a7

Browse files
committed
Merge branch 'main' into instance-wide-uncommitted-queue
2 parents 338556e + b700b2c commit 7ab34a7

File tree

11 files changed

+431
-62
lines changed

11 files changed

+431
-62
lines changed

CHANGELOG.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,20 @@ 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+
89
## [2.5.0] - Unreleased
910

1011
### Added
12+
- New UI for the basic mode Sync (#415)
1113
- Files in uncommitted queue in any namespace warn users when opened except for in VSCode (#370)
1214

13-
## [2.4.1] - Unreleased
15+
### Fixed
16+
- Instance wide settings are placed in proper global (#444)
17+
18+
## [2.4.1] - 2024-08-02
19+
20+
### Added
21+
- New API endpoint that accepts git commands as array instead of string (#437)
1422

1523
### Fixed
1624
- Fixed JS errors in Studio on certain operations (#416)

cls/SourceControl/Git/Change.cls

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -277,4 +277,3 @@ Storage Default
277277
}
278278

279279
}
280-

cls/SourceControl/Git/Extension.cls

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -412,4 +412,3 @@ Method AddToSourceControl(InternalName As %String, Description As %String = "")
412412
}
413413

414414
}
415-

cls/SourceControl/Git/Utils.cls

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ Parameter GitContextMenuItems = ",%Diff,%Blame,";
1818

1919
ClassMethod %SYSNamespaceStorage() As %String [ CodeMode = expression ]
2020
{
21-
$Replace(..#Storage,"^","^["""_..#InstallNamespace_"""]")
21+
$Replace(..#Storage,"^SYS","^%SYS")
2222
}
2323

2424
/// Returns root temp folder
@@ -183,6 +183,14 @@ ClassMethod IsImportAfter(menuItemName As %String) As %Boolean [ CodeMode = expr
183183
$Find(..#ImportAfterGitMenuItems, ","_menuItemName_",") > 0
184184
}
185185

186+
ClassMethod MigrateInstanceSettings()
187+
{
188+
if $data(^["%SYS"]SYS("SourceControl", "Git")) {
189+
merge ^%SYS("SourceControl", "Git") = ^["%SYS"]SYS("SourceControl", "Git")
190+
kill ^["%SYS"]SYS("SourceControl", "Git")
191+
}
192+
}
193+
186194
ClassMethod UserAction(InternalName As %String, MenuName As %String, ByRef Target As %String, ByRef Action As %String, ByRef Reload As %Boolean, ByRef Msg As %String) As %Status
187195
{
188196
#define Force 1
@@ -253,17 +261,8 @@ ClassMethod UserAction(InternalName As %String, MenuName As %String, ByRef Targe
253261
set Action = 7
254262
quit $$$OK
255263
} elseif (menuItemName = "Sync") {
256-
if ..CheckForUncommittedFiles() {
257-
set Target = "Enter a commit message for the sync operation"
258-
set Action = 7
259-
set Msg = ..PreSync()
260-
} else {
261-
set Target = ""
262-
do ..Sync("",.Target)
263-
if (Target '= "") {
264-
set Action = 6
265-
}
266-
}
264+
set Action = 2 + externalBrowser
265+
set Target = urlPrefix _ "/isc/studio/usertemplates/gitsourcecontrol/sync.csp?Namespace="_$NAMESPACE
267266

268267
quit $$$OK
269268
} elseif (menuItemName = "Push") {
@@ -1786,7 +1785,7 @@ ClassMethod RunGitCommandWithInput(command As %String, inFile As %String = "", O
17861785
set buffer = ##class(SourceControl.Git.Util.Buffer).%New()
17871786
do buffer.BeginCaptureOutput()
17881787
set st = ..SyncIrisWithRepoThroughCommand(.outStream)
1789-
set out = ##class(%Stream.Global).%New()
1788+
set out = ##class(%Stream.GlobalCharacter).%New()
17901789
do buffer.EndCaptureOutput(.out)
17911790
if $$$ISOK(st) {
17921791
while 'out.AtEnd {
@@ -1947,7 +1946,7 @@ ClassMethod GenerateCommitMessageFromFiles(filesWithActions) As %String
19471946
set commitMsg = commitMsg_$LISTBUILD(oneFileMsg)
19481947

19491948
}
1950-
quit $LISTTOSTRING(commitMsg, ",")
1949+
quit $LISTTOSTRING(commitMsg, ", ")
19511950
}
19521951

19531952
ClassMethod GitStatus(ByRef files, IncludeAllFiles = 0)
@@ -2629,4 +2628,3 @@ ClassMethod BaselineExport(pCommitMessage = "", pPushToRemote = "") As %Status
26292628
}
26302629

26312630
}
2632-

cls/SourceControl/Git/WebUIDriver.cls

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ ClassMethod HandleRequest(pagePath As %String, InternalName As %String = "", Out
2727
if $isobject($get(responseJSON)) {
2828
do responseJSON.%ToJSON(%data)
2929
}
30-
} elseif $match(pathStart,"git|dirname|hostname|viewonly") {
30+
} elseif $match(pathStart,"git-command|git|dirname|hostname|viewonly") {
3131
if (%request.Method = "GET") {
3232
set %data = ##class(%Stream.TmpCharacter).%New()
3333
// Things not handled from Python backend:
@@ -159,6 +159,40 @@ ClassMethod HandleRequest(pagePath As %String, InternalName As %String = "", Out
159159
do ##class(SourceControl.Git.Change).RefreshUncommitted(,,,1)
160160
}
161161
set handled = 1
162+
} elseif (pathStart = "git-command") {
163+
set requestBody = ##class(%Library.DynamicObject).%FromJSON(%request.Content)
164+
set command = requestBody.command
165+
166+
set argsArr = ""
167+
set argsArr($increment(argsArr)) = "color.ui=true"
168+
set iterator = command.%GetIterator()
169+
while iterator.%GetNext(,.value) {
170+
set argsArr($increment(argsArr)) = value
171+
}
172+
173+
set inFile = ""
174+
175+
set returnCode = ##class(SourceControl.Git.Utils).RunGitCommandWithInput("-c", inFile, .errStream, .outStream, argsArr...)
176+
set %data = ##class(%Stream.TmpCharacter).%New()
177+
set changeTerminators = (%data.LineTerminator '= $char(13,10))
178+
set %data.LineTerminator = $char(13,10) // For the CSPGateway.
179+
while 'outStream.AtEnd {
180+
do %data.WriteLine(outStream.ReadLine())
181+
}
182+
183+
set nLines = 0
184+
while 'errStream.AtEnd {
185+
do %data.WriteLine(errStream.ReadLine())
186+
set:changeTerminators nLines = nLines + 1
187+
}
188+
189+
// Need to write out two lines or we get an infinite loop in JavaScript...
190+
do %data.WriteLine()
191+
do %data.WriteLine()
192+
do %data.WriteLine("Git-Stderr-Length: " _ (errStream.Size + nLines))
193+
do %data.Write("Git-Return-Code: " _ returnCode) // No ending newline expected
194+
do %data.Rewind()
195+
set handled = 1
162196
}
163197
}
164198
}
@@ -235,4 +269,3 @@ ClassMethod GetPackageVersion() As %Library.DynamicObject
235269
}
236270

237271
}
238-

csp/sync.csp

Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<meta charset="utf-8">
5+
<meta http-equiv="X-UA-Compatible" content="IE=edge">
6+
<meta name="viewport" content="width=device-width, initial-scale=1">
7+
<link rel="stylesheet" type="text/css" href="css/bootstrap.min.css" />
8+
<link rel="stylesheet" type="text/css" href="css/git-webui.css" />
9+
#(##class(SourceControl.Git.Utils).GetSourceControlInclude())#
10+
<style type="text/css">
11+
h1, h2 {
12+
margin-top: 10px
13+
}
14+
15+
.A::after {
16+
content: "Added";
17+
position: absolute;
18+
right: 10px;
19+
}
20+
21+
.D::after {
22+
content: "Deleted";
23+
position: absolute;
24+
right: 10px;
25+
}
26+
27+
.M::after {
28+
content: "Modified";
29+
position: absolute;
30+
right: 10px;
31+
}
32+
33+
.R::after {
34+
content: "Renamed";
35+
position: absolute;
36+
right: 10px;
37+
}
38+
39+
.section-header {
40+
margin: 20px 0 15px 0
41+
}
42+
43+
#syncBtn {
44+
position: absolute;
45+
right: 15px;
46+
margin-top: 10px;
47+
}
48+
49+
.output-header {
50+
margin-top: 120px;
51+
}
52+
.output {
53+
54+
margin-bottom: 20px;
55+
border: 1.5px solid darkgray;
56+
padding: 10px;
57+
border-radius: 4px;
58+
}
59+
60+
</style>
61+
</head>
62+
<body>
63+
<server>
64+
set settings = ##class(SourceControl.Git.Settings).%New()
65+
66+
set uncommittedWithAction = ##class(SourceControl.Git.Utils).UncommittedWithAction().%Get("user")
67+
set commitMsg = ##class(SourceControl.Git.Utils).GenerateCommitMessageFromFiles(uncommittedWithAction)
68+
set filesToSync = ($length(commitMsg) > 0)
69+
set fileSectionDisplay = $select(
70+
filesToSync = 1: "block",
71+
1: "none"
72+
)
73+
set noFileDisplay = $select(
74+
filesToSync = 0: "block",
75+
1: "none"
76+
)
77+
78+
set outputDisplay = "none"
79+
80+
</server>
81+
82+
<div class="container">
83+
<h1 class="text-center">Sync Repository</h1>
84+
<div class="row">
85+
<div class="offset-sm-2 col-sm-8">
86+
<div style="display: #(fileSectionDisplay)#">
87+
<h3 class="section-header">Files to be committed with sync:</h3>
88+
<ul class="list-group">
89+
<server>
90+
set iterator = uncommittedWithAction.%GetIterator()
91+
while iterator.%GetNext(,.uncommitted) {
92+
set action = uncommitted.%Get("action")
93+
set file = uncommitted.%Get("file")
94+
&html<<li class="list-group-item #(..EscapeHTML(action))#">#(..EscapeHTML(file))#</li>>
95+
}
96+
</server>
97+
</ul>
98+
<h3 class="section-header">Sync commit message:</h3>
99+
<input class="form-control" type="text" name="syncMsg" id="syncMsg" value="#(..EscapeHTML(commitMsg))#">
100+
</div>
101+
<div style="display: #(noFileDisplay)#">
102+
<h2 class="text-center">No files to commit with sync</h2>
103+
</div>
104+
<h3 class="section-header">Sync details:</h3>
105+
<p>Upon syncing, the local repository will pull the changes from remote and commit the newest changes before committing and pushing</p>
106+
<server>
107+
108+
if settings.defaultMergeBranch '= "" {
109+
&html<<p>Local changes will be merged with #(..EscapeHTML(settings.defaultMergeBranch))# after receiving the latest changes</p>>
110+
}
111+
</server>
112+
113+
<button class="btn btn-lg btn-primary" id="syncBtn" onClick="disableInput(); #server(..PerformSync(self.document.getElementById('syncMsg').value))#">Sync</button>
114+
<div>
115+
<h3 class="output-header" id="outputHeader" style="display: #(outputDisplay)#">Sync output: </h3>
116+
<div class="container output" id="outputContainer" style="display: #(outputDisplay)#">
117+
<pre id="outputBox"></pre>
118+
</div>
119+
</div>
120+
</div>
121+
</div>
122+
123+
</div>
124+
</body>
125+
<script type="text/javascript">
126+
function disableInput() {
127+
document.getElementById('syncMsg').disabled = true;
128+
document.getElementById('syncBtn').innerHTML = 'Syncing...';
129+
document.getElementById('syncBtn').disabled = true;
130+
}
131+
</script>
132+
<script language="cache" method="PerformSync" arguments="syncMsg:%String">
133+
&js<document.getElementById('outputContainer').style.display = 'block'>
134+
&js<document.getElementById('outputHeader').style.display = 'block'>
135+
set buffer = ##class(SourceControl.Git.Util.Buffer).%New()
136+
do buffer.BeginCaptureOutput()
137+
138+
set st = ##class(SourceControl.Git.Utils).Sync(syncMsg)
139+
140+
set out = ##class(%Stream.GlobalCharacter).%New()
141+
do buffer.EndCaptureOutput(.out)
142+
while 'out.AtEnd {
143+
set line = out.ReadLine()
144+
set escapedLine = ..EscapeHTML(line)
145+
set escapedLine = $replace(escapedLine, $char(10), "<br>")
146+
147+
&js<
148+
var outputContainer = document.getElementById('outputBox');
149+
var lineText = "#(escapedLine)#";
150+
var lineTextNode = document.createTextNode(lineText);
151+
outputContainer.innerHTML += lineText + "<br>";
152+
>
153+
}
154+
&js<document.getElementById('syncBtn').innerHTML = 'Synced'>
155+
</script>
156+
</html>
157+
<script method='OnPreHTTP' language='cache' runat='server' returntype='%Boolean'>
158+
try {
159+
set %session.UseSessionCookie = 1 // Always set back to autodetect
160+
set %session.CookiePath = "" // Always clear
161+
if (%request.UserAgent [ " Code/") {
162+
// Workaround for VSCode webview
163+
set %session.SessionScope = 0 // none; allowed because...
164+
set %session.SecureSessionCookie = 1 // secure flag on session cookie - will be ignored over http, but that's OK because we already have it
165+
}
166+
} catch e {
167+
// ignore; may occur on platform versions without the above properties
168+
}
169+
quit 1
170+
</script>
171+
<script method='OnPreHyperEvent' arguments="class:%String,method:%String" language='cache' runat='server' returntype='%Status'>
172+
try {
173+
set %session.UseSessionCookie = 1 // Always set back to autodetect
174+
set %session.CookiePath = "" // Always clear
175+
if (%request.UserAgent [ " Code/") {
176+
// Workaround for VSCode webview
177+
set %session.SessionScope = 0 // none; allowed because...
178+
set %session.SecureSessionCookie = 1 // secure flag on session cookie - will be ignored over http, but that's OK because we already have it
179+
}
180+
} catch e {
181+
// ignore; may occur on platform versions without the above properties
182+
}
183+
quit 1
184+
</script>
Lines changed: 1 addition & 0 deletions
Loading
Lines changed: 1 addition & 0 deletions
Loading

0 commit comments

Comments
 (0)