Skip to content

Commit 1b8317d

Browse files
authored
Merge pull request #768 from intersystems/improve-remote-management
Improve remote management on settings page
2 parents 88fb29b + 789b7d0 commit 1b8317d

File tree

3 files changed

+118
-86
lines changed

3 files changed

+118
-86
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
99

1010
### Added
1111
- Expanded Baseline Export to include custom HL7, X12, ASTM schemas and Lookup Tables (#693)
12+
- Settings page includes a test of the connection to the remote (#746)
1213

1314
### Fixed
1415
- Deletes are now properly owned by the user who did the delete (#729)
1516
- Pull page output now displays better when pull preview shows a lot of changes (#740)
17+
- Changing remotes in the git project settings pages now works if remote is not already defined (#746)
1618

1719
## [2.11.0] - 2025-04-23
1820

cls/SourceControl/Git/Utils.cls

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3019,15 +3019,23 @@ ClassMethod BaselineExport(pCommitMessage = "", pPushToRemote = "") As %Status
30193019
return sc
30203020
}
30213021

3022-
/// Returns the url for the remote repository (censoring the username)
3023-
ClassMethod GetConfiguredRemote() As %String
3024-
{
3025-
d ..RunGitCommand("remote",.err,.out,"-v")
3026-
set line = out.ReadLine()
3027-
set url = $piece($piece(line,$char(9),2)," ",1)
3022+
/// Returns the url for the "origin" remote repository
3023+
ClassMethod GetConfiguredRemote(Output remoteExists As %Boolean = 0) As %String
3024+
{
3025+
set exitCode = ..RunGitCommand("remote",.err,.out,"get-url","origin")
3026+
if (exitCode = 0) {
3027+
set remoteExists = 1
3028+
set url = out.ReadLine()
3029+
} elseif (exitCode = 2) {
3030+
set remoteExists = 0
3031+
set url = ""
3032+
} else {
3033+
$$$ThrowStatus($$$ERROR($$$GeneralError,"git reported failure"))
3034+
}
30283035
return url
30293036
}
30303037

3038+
/// Returns the url for the "origin" remote repository, redacting the username
30313039
ClassMethod GetRedactedRemote() As %String
30323040
{
30333041
set url = ..GetConfiguredRemote()
@@ -3038,7 +3046,15 @@ ClassMethod GetRedactedRemote() As %String
30383046

30393047
ClassMethod SetConfiguredRemote(url) As %String
30403048
{
3041-
do ##class(SourceControl.Git.Utils).RunGitCommandWithInput("remote",,.errStream,.outStream,"set-url","origin",url)
3049+
do ..GetConfiguredRemote(.remoteExists)
3050+
set returnCode = $select(
3051+
remoteExists&&(url=""): ##class(SourceControl.Git.Utils).RunGitCommandWithInput("remote",,.errStream,.outStream,"remove","origin"),
3052+
remoteExists&&(url'=""): ##class(SourceControl.Git.Utils).RunGitCommandWithInput("remote",,.errStream,.outStream,"set-url","origin",url),
3053+
'remoteExists&&(url'=""): ##class(SourceControl.Git.Utils).RunGitCommandWithInput("remote",,.errStream,.outStream,"add","origin",url),
3054+
1: 0)
3055+
if (returnCode '= 0) {
3056+
$$$ThrowStatus($$$ERROR($$$GeneralError,"git reported failure"))
3057+
}
30423058
set output = outStream.ReadLine(outStream.Size)
30433059
quit output
30443060
}
@@ -3198,4 +3214,3 @@ ClassMethod IsSchemaStandard(pName As %String = "") As %Boolean [ Internal ]
31983214
}
31993215

32003216
}
3201-

csp/gitprojectsettings.csp

Lines changed: 93 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
<style type='text/css'>
1212
.error {
1313
color: red;
14+
padding: 20px;
1415
}
1516

1617
body {
@@ -101,97 +102,105 @@ body {
101102
set homeURL = ##class(SourceControl.Git.WebUIDriver).GetHomeURL()
102103

103104
set settings = ##class(SourceControl.Git.Settings).%New()
104-
set remote = ##class(SourceControl.Git.Utils).GetRedactedRemote()
105-
/// After Save
106-
if (%request.Method="POST") && $Data(%request.Data("gitsettings",1)) {
107-
for param="gitUserName","gitUserEmail" {
108-
set $Property(settings,param) = $Get(%request.Data(param,1))
109-
}
110-
if ('settings.settingsUIReadOnly) {
111-
for param="gitBinPath","namespaceTemp","privateKeyFile","pullEventClass","percentClassReplace", "defaultMergeBranch","environmentName" {
105+
try {
106+
/// After Save
107+
if (%request.Method="POST") && $Data(%request.Data("gitsettings",1)) {
108+
for param="gitUserName","gitUserEmail" {
112109
set $Property(settings,param) = $Get(%request.Data(param,1))
113110
}
111+
if ('settings.settingsUIReadOnly) {
112+
for param="gitBinPath","namespaceTemp","privateKeyFile","pullEventClass","percentClassReplace", "defaultMergeBranch","environmentName" {
113+
set $Property(settings,param) = $Get(%request.Data(param,1))
114+
}
114115

115-
if ($Get(%request.Data("mappedItemsReadOnly", 1)) = 1) {
116-
set settings.mappedItemsReadOnly = 1
117-
} else {
118-
set settings.mappedItemsReadOnly = 0
119-
}
116+
if ($Get(%request.Data("mappedItemsReadOnly", 1)) = 1) {
117+
set settings.mappedItemsReadOnly = 1
118+
} else {
119+
set settings.mappedItemsReadOnly = 0
120+
}
120121

121-
set newRemote = $Get(%request.Data("remoteRepo",1))
122-
// If entry was modified, set new remote repo
123-
if (newRemote '= ##class(SourceControl.Git.Utils).GetRedactedRemote()) {
124-
do ##class(SourceControl.Git.Utils).SetConfiguredRemote(newRemote)
125-
}
122+
set newRemote = $Get(%request.Data("remoteRepo",1))
123+
// If entry was modified, set new remote repo
124+
if (newRemote '= ##class(SourceControl.Git.Utils).GetRedactedRemote()) {
125+
do ##class(SourceControl.Git.Utils).SetConfiguredRemote(newRemote)
126+
}
126127

127-
set settings.compileOnImport = ($Get(%request.Data("compileOnImport", 1)) = 1)
128-
set settings.decomposeProductions = ($Get(%request.Data("decomposeProductions", 1)) = 1)
129-
set settings.decomposeProdAllowIDE = ($Get(%request.Data("decomposeProdAllowIDE", 1)) = 1)
130-
set settings.lockBranch = ($Get(%request.Data("lockBranch", 1)) = 1)
131-
132-
if ($Get(%request.Data("basicMode", 1)) = 1) {
133-
set settings.basicMode = 1
134-
} elseif ($Get(%request.Data("basicMode", 1)) = "system"){
135-
set settings.basicMode = "system"
136-
} else {
137-
set settings.basicMode = 0
138-
}
128+
set settings.compileOnImport = ($Get(%request.Data("compileOnImport", 1)) = 1)
129+
set settings.decomposeProductions = ($Get(%request.Data("decomposeProductions", 1)) = 1)
130+
set settings.decomposeProdAllowIDE = ($Get(%request.Data("decomposeProdAllowIDE", 1)) = 1)
131+
set settings.lockBranch = ($Get(%request.Data("lockBranch", 1)) = 1)
132+
133+
if ($Get(%request.Data("basicMode", 1)) = 1) {
134+
set settings.basicMode = 1
135+
} elseif ($Get(%request.Data("basicMode", 1)) = "system"){
136+
set settings.basicMode = "system"
137+
} else {
138+
set settings.basicMode = 0
139+
}
139140

140-
if ($Get(%request.Data("systemBasicMode", 1)) = 1) {
141-
set settings.systemBasicMode = 1
142-
} else {
143-
set settings.systemBasicMode = 0
144-
}
145-
set i = 1
146-
set param = "NoFolders"
147-
kill settings.Mappings
148-
149-
while ( $Data(%request.Data("MappingsExt",i)) ){
150-
if ($get(%request.Data("MappingsExt",i)) '= "") {
151-
if ($Get(%request.Data(param,i)) = "NoFolders"){
152-
set settings.Mappings($Get(%request.Data("MappingsExt",i)), $Get(%request.Data("MappingsCov",i)), $Get(%request.Data(param,i))) = 1
153-
}
154-
set settings.Mappings($Get(%request.Data("MappingsExt",i)), $Get(%request.Data("MappingsCov",i))) = $Get(%request.Data("MappingsPath",i))
155-
}
156-
set i = i+1
157-
}
141+
if ($Get(%request.Data("systemBasicMode", 1)) = 1) {
142+
set settings.systemBasicMode = 1
143+
} else {
144+
set settings.systemBasicMode = 0
145+
}
146+
set i = 1
147+
set param = "NoFolders"
148+
kill settings.Mappings
149+
150+
while ( $Data(%request.Data("MappingsExt",i)) ){
151+
if ($get(%request.Data("MappingsExt",i)) '= "") {
152+
if ($Get(%request.Data(param,i)) = "NoFolders"){
153+
set settings.Mappings($Get(%request.Data("MappingsExt",i)), $Get(%request.Data("MappingsCov",i)), $Get(%request.Data(param,i))) = 1
154+
}
155+
set settings.Mappings($Get(%request.Data("MappingsExt",i)), $Get(%request.Data("MappingsCov",i))) = $Get(%request.Data("MappingsPath",i))
156+
}
157+
set i = i+1
158+
}
158159

159-
set i = 1
160-
set contexts = []
160+
set i = 1
161+
set contexts = []
161162

162-
while ( $Data(%request.Data("favNamespace",i)) ){
163-
if ($Get(%request.Data("favNamespace",i)) '= "") {
164-
do contexts.%Push($Get(%request.Data("favNamespace",i)))
165-
}
166-
set i = i+1
167-
}
163+
while ( $Data(%request.Data("favNamespace",i)) ){
164+
if ($Get(%request.Data("favNamespace",i)) '= "") {
165+
do contexts.%Push($Get(%request.Data("favNamespace",i)))
166+
}
167+
set i = i+1
168+
}
168169

169-
set settings.favoriteNamespaces = contexts
170+
set settings.favoriteNamespaces = contexts
170171

171-
if ($get(%request.Data("proxySubmitButton",1)) = "saveDefaults") {
172-
do settings.SaveDefaults()
172+
if ($get(%request.Data("proxySubmitButton",1)) = "saveDefaults") {
173+
do settings.SaveDefaults()
174+
}
173175
}
174-
}
175-
set err = ""
176-
try {
177-
set buffer = ##class(SourceControl.Git.Util.Buffer).%New()
178-
do buffer.BeginCaptureOutput()
179-
$$$ThrowOnError(settings.SaveWithSourceControl())
180-
do buffer.EndCaptureOutput(.out)
181-
if (out '= "") {
182-
&html<<div class="alert alert-primary">
183-
<div>#(..EscapeHTML(out))#</div>
184-
</div>>
176+
set err = ""
177+
try {
178+
set buffer = ##class(SourceControl.Git.Util.Buffer).%New()
179+
do buffer.BeginCaptureOutput()
180+
$$$ThrowOnError(settings.SaveWithSourceControl())
181+
do buffer.EndCaptureOutput(.out)
182+
if (out '= "") {
183+
&html<<div class="alert alert-primary">
184+
<div>#(..EscapeHTML(out))#</div>
185+
</div>>
186+
}
187+
} catch err {
188+
kill buffer
189+
throw err
185190
}
186-
} catch err {
187-
kill buffer
188-
do err.Log()
189-
&html<<div class="alert alert-danger">An error occurred and has been logged to the application error log.</div>>
191+
set successfullySavedSettings = 1
190192
}
193+
set remote = ##class(SourceControl.Git.Utils).GetRedactedRemote()
194+
if (remote'="") && (##class(SourceControl.Git.Utils).RunGitCommandWithInput("ls-remote",,.errStream,,"origin")'=0) {
195+
set remoteConnectionError = errStream.Read()
196+
}
197+
} catch err {
198+
do err.Log()
199+
&html<<div class="error alert-danger">An error occurred and has been logged to the application error log.</div>>
191200
}
192201
</server>
193202
<div class = 'container'>
194-
<csp:if condition='$D(%request.Data("gitsettings",1)) && (##class(SourceControl.Git.Utils).NeedSettings() = 0)'>
203+
<csp:if condition='$get(successfullySavedSettings) && (##class(SourceControl.Git.Utils).NeedSettings() = 0)'>
195204
<div class = "alert">
196205
<span class="closebtn" onclick="this.parentElement.style.display='none';">&times;</span>
197206
<strong>Success!</strong> Your changes have been saved.
@@ -318,7 +327,7 @@ body {
318327
set placeholder = $Select($system.Version.GetOS()="Windows":"(e.g. C:\Users\ExampleUser\.ssh\id_rsa)",
319328
1:"(e.g., /home/user/.ssh/id_rsa)")
320329
</server>
321-
<input type="text" class="#(class)#" id="privateKeyFile" name="privateKeyFile" value='#(..EscapeHTML(settings.privateKeyFile))#' placeholder=#(placeholder)#/>
330+
<input type="text" class="#(class)#" id="privateKeyFile" name="privateKeyFile" value='#(..EscapeHTML(settings.privateKeyFile))#' placeholder="#(..EscapeHTML(placeholder))#"/>
322331
<div class = "#(divClass)#">
323332
#(feedbackText)#
324333
<pre id="sshOutput"></pre>
@@ -416,12 +425,18 @@ body {
416425
</div>
417426

418427
<div class="form-group row mb-3">
419-
<label for="remoteRepo" class="offset-sm-1 col-sm-3 col-form-label" data-toggle="tooltip" data-placement="top" title="Url to Remote repository"><b>Remote Repository</b></label>
428+
<label for="remoteRepo" class="offset-sm-1 col-sm-3 col-form-label" data-toggle="tooltip" data-placement="top" title="Url to Remote repository (origin)"><b>Remote Repository</b></label>
420429
<div class="col-sm-7">
421-
<input type="text" class="form-control" id="remoteRepo" name="remoteRepo" value='#(..EscapeHTML(remote))#' placeholder="ex. git@github.com:User/UserRepo.git"/>
430+
<input type="text" class='form-control #($select($get(remote)="":"",$get(remoteConnectionError)="":"is-valid",1:"is-invalid"))#' id="remoteRepo" name="remoteRepo" value='#(..EscapeHTML($get(remote)))#' placeholder="e.g. git@github.com:User/UserRepo.git"/>
422431
<div class = "neutral-feedback">
423432
(Username is redacted)
424433
</div>
434+
<div class="invalid-feedback">
435+
Unable to contact remote: #(..EscapeHTML($get(remoteConnectionError)))#
436+
</div>
437+
<div class="valid-feedback">
438+
Connection successful
439+
</div>
425440
</div>
426441
</div>
427442

0 commit comments

Comments
 (0)