Skip to content

Commit 4123431

Browse files
authored
Merge pull request #16 from intersystems/lock-environment
Support locking environment
2 parents f3f74ac + 6394841 commit 4123431

File tree

4 files changed

+101
-63
lines changed

4 files changed

+101
-63
lines changed

cls/SourceControl/Git/API.cls

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
Class SourceControl.Git.API
22
{
33

4+
/// Configures settings for Git integration
45
ClassMethod Configure()
56
{
67
set sc = $$$OK
@@ -32,5 +33,19 @@ ClassMethod Configure()
3233
}
3334
}
3435

36+
/// Locks the environment to prevent changes to code other than through git pull.
37+
/// Returns 1 if the environment was already locked, 0 if it was previously unlocked.
38+
ClassMethod Lock()
39+
{
40+
quit ##class(SourceControl.Git.Utils).Locked(1)
41+
}
42+
43+
/// Unlocks the environment to allow changes through the IDE.
44+
/// Returns 1 if the environment was already locked, 0 if it was previously unlocked.
45+
ClassMethod Unlock()
46+
{
47+
quit ##class(SourceControl.Git.Utils).Locked(0)
48+
}
49+
3550
}
3651

cls/SourceControl/Git/Extension.cls

Lines changed: 49 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -93,22 +93,21 @@ Method OnSourceMenuItem(name As %String, ByRef Enabled As %String, ByRef Display
9393
if '(##class(Change).IsUncommitted(##class(Utils).FullExternalName(InternalName))) || ($username '= userCheckedOut) {
9494
set Enabled = 0
9595
}
96-
}elseif name = "%Push" {
96+
} elseif name = "%Push" {
9797
// TODO: Only display if there are no files checked out by other users
9898
set Enabled = 1
9999
set DisplayName = "Push"
100-
}elseif name = "%Fetch" {
100+
} elseif name = "%Fetch" {
101101
set Enabled = 1
102102
set DisplayName = "Fetch"
103-
}elseif name = "%Pull" {
103+
} elseif name = "%Pull" {
104104
set Enabled = 1
105105
set DisplayName = "Pull"
106-
}elseif ##class(Utils).IsMenuGitCommand(name) && ##class(Utils).GitBinExists() {
106+
} elseif ##class(Utils).IsMenuGitCommand(name) && ##class(Utils).GitBinExists() {
107107
set DisplayName = $case(name,"%StashSave":"Stash save",
108108
"%StashPop":"Stash pop",
109109
:$Extract(name, 2, *))
110-
}
111-
else {
110+
} else {
112111
set Enabled = -1
113112
}
114113
} elseif ##class(Utils).GitBinExists() {
@@ -132,9 +131,9 @@ Method OnSourceMenuContextItem(itemName As %String, menuItemName As %String, ByR
132131

133132
if (itemName = "") || '##class(Utils).IsNamespaceInGit() {
134133
set Enabled = -1
135-
}elseif $F(itemName,",") > 0 { //if more than one item is selected, we can only add/remove, no diff or blame
134+
} elseif $F(itemName,",") > 0 { //if more than one item is selected, we can only add/remove, no diff or blame
136135
set Enabled = $case(menuItemName,"%AddToSC":1,"%RemoveFromSC":1,:-1)
137-
}elseif ##class(Utils).IsInSourceControl(##class(Utils).NormalizeInternalName(itemName)) {
136+
} elseif ##class(Utils).IsInSourceControl(##class(Utils).NormalizeInternalName(itemName)) {
138137
set Enabled = $Case(menuItemName, "%AddToSC":-1,:1)
139138
} else {
140139
set Enabled = $Case(menuItemName, "%AddToSC":1,:-1)
@@ -161,10 +160,10 @@ Method OnMenuItem(MenuName As %String, InternalName As %String, SelectedText As
161160

162161
if menu = "%SourceMenu" {
163162
set ec = ..OnSourceMenuItem(name, .Enabled, .DisplayName, InternalName)
164-
}elseif menu = "%SourceContext" {
163+
} elseif menu = "%SourceContext" {
165164
set ec = ..OnSourceMenuContextItem(InternalName, name, .Enabled, .DisplayName)
166165
}
167-
Quit ec
166+
quit ec
168167
}
169168

170169
/// This is called before the actual load of data to give the chance
@@ -205,7 +204,7 @@ Method OnAfterSave(InternalName As %String, Object As %RegisteredObject = {$$$NU
205204
/// Called after the compile of the item is done.
206205
Method OnAfterCompile(InternalName As %String) As %Status
207206
{
208-
Quit ..OnAfterSave(InternalName)
207+
quit ..OnAfterSave(InternalName)
209208
}
210209

211210
/// Returns true if this item is in source control and false otherwise.
@@ -228,7 +227,12 @@ Method OnAfterDelete(InternalName As %String) As %Status
228227
/// the routine/class/csp item. This is often a filename to write the file out to.
229228
Method ExternalName(InternalName As %String) As %String
230229
{
231-
Quit ##class(Utils).Name(InternalName)
230+
quit ##class(Utils).Name(InternalName)
231+
}
232+
233+
Method IsReadOnly(InternalName As %String) As %Boolean
234+
{
235+
quit ##class(SourceControl.Git.Utils).Locked()
232236
}
233237

234238
/// Check the status of the given item
@@ -237,42 +241,41 @@ Method ExternalName(InternalName As %String) As %String
237241
Method GetStatus(InternalName As %String, ByRef IsInSourceControl As %Boolean, ByRef Editable As %Boolean, ByRef IsCheckedOut As %Boolean, ByRef UserCheckedOut As %String) As %Status
238242
{
239243
#; Quit ##super(InternalName,.IsInSourceControl,.Editable,.IsCheckedOut,.UserCheckedOut)
240-
Set Editable=1,IsCheckedOut=1,UserCheckedOut=""
241-
Set filename=##class(SourceControl.Git.Utils).FullExternalName(InternalName)
242-
Set IsInSourceControl=(filename'=""&&($$$FileExists(filename)))
243-
If filename="" Quit $$$OK
244-
If InternalName="" Quit $$$OK
245-
#; If the file does not exist then it must be a new item so it is editable.
246-
If '$$$FileExists(filename) {
247-
Set IsCheckedOut=0
248-
}
249-
do ##class(Utils).GitStatus(.files)
250-
if $Get(files(InternalName)) '= "" {
251-
///it's in source control, checked out, and should be locked to editing by other users
252-
///find out who has it edited
253-
set IsCheckedOut=1
254-
Set sc=##class(SourceControl.Git.Change).GetUncommitted(filename,.tAction,.tInternalName,.UncommittedUser,.tSource,.UncommittedLastUpdated)
255-
If $$$ISOK(sc) {
256-
if ($D(tAction)&&(UncommittedUser'=$USERNAME)){
257-
Set msg="NOTICE: "_InternalName_" is currently checked out by user '"_UncommittedUser_"', and was last updated at "_UncommittedLastUpdated
258-
Write !,msg
259-
Set Editable=0
260-
Set IsInSourceControl=0 ;set this to 0 to prevent user from being prompted to Check Out file
261-
}
262-
Set UserCheckedOut=UncommittedUser
263-
}
264-
}
265-
// If it doesn't show up in git status, there are no uncommitted changes so it should not be locked or checked out by any user
266-
else {
267-
set Editable=1, IsCheckedOut=0, UserCheckedOut=""
268-
if ##class(SourceControl.Git.Change).IsUncommitted(filename){
269-
#; Remove the item from the list of uncommitted changes;
270-
Set sc=##class(SourceControl.Git.Change).RemoveUncommitted(filename,1,1)
271-
If $$$ISERR(sc) Write "Error removing uncommitted file "_filename_" - "_$System.OBJ.DisplayError(sc)
244+
set Editable='..IsReadOnly(),IsCheckedOut=1,UserCheckedOut=""
245+
set filename=##class(SourceControl.Git.Utils).FullExternalName(InternalName)
246+
set IsInSourceControl=(filename'=""&&($$$FileExists(filename)))
247+
if filename="" Quit $$$OK
248+
if InternalName="" Quit $$$OK
249+
#; If the file does not exist then it must be a new item so it is editable.
250+
if '$$$FileExists(filename) {
251+
set IsCheckedOut=0
252+
}
253+
do ##class(Utils).GitStatus(.files)
254+
if $Get(files(InternalName)) '= "" {
255+
///it's in source control, checked out, and should be locked to editing by other users
256+
///find out who has it edited
257+
set IsCheckedOut=1
258+
set sc=##class(SourceControl.Git.Change).GetUncommitted(filename,.tAction,.tInternalName,.UncommittedUser,.tSource,.UncommittedLastUpdated)
259+
if $$$ISOK(sc) {
260+
if ($D(tAction)&&(UncommittedUser'=$USERNAME)){
261+
set msg="NOTICE: "_InternalName_" is currently checked out by user '"_UncommittedUser_"', and was last updated at "_UncommittedLastUpdated
262+
write !,msg
263+
set Editable=0
264+
set IsInSourceControl=0 ;set this to 0 to prevent user from being prompted to Check Out file
272265
}
266+
set UserCheckedOut=UncommittedUser
267+
}
268+
} else {
269+
// If it doesn't show up in git status, there are no uncommitted changes so it should not be locked or checked out by any user
270+
set Editable=1, IsCheckedOut=0, UserCheckedOut=""
271+
if ##class(SourceControl.Git.Change).IsUncommitted(filename){
272+
#; Remove the item from the list of uncommitted changes;
273+
set sc=##class(SourceControl.Git.Change).RemoveUncommitted(filename,1,1)
274+
if $$$ISERR(sc) Write "Error removing uncommitted file "_filename_" - "_$System.OBJ.DisplayError(sc)
273275
}
274-
275-
Quit $$$OK
276+
}
277+
278+
quit $$$OK
276279
}
277280

278281
}

cls/SourceControl/Git/Utils.cls

Lines changed: 35 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,16 @@ ClassMethod PullEventClass() As %String [ CodeMode = expression ]
4949
$Get(@..#Storage@("settings","pullEventClass"), ##class(SourceControl.Git.PullEventHandler.Default).%ClassName(1))
5050
}
5151

52+
/// Returns the current (or previous) value of the flag.
53+
ClassMethod Locked(newFlagValue As %Boolean) As %Boolean
54+
{
55+
set result = $Get(@..#Storage@("settings","locked"),0)
56+
if $Data(newFlagValue)#2 {
57+
set @..#Storage@("settings","locked") = ''newFlagValue
58+
}
59+
quit result
60+
}
61+
5262
ClassMethod GitBinExists() As %Boolean
5363
{
5464
#if $system.Version.GetOS()'="Windows"
@@ -121,8 +131,6 @@ ClassMethod UserAction(InternalName As %String, MenuName As %String, ByRef Targe
121131
#dim menuName As %String = $Piece(MenuName,",")
122132
#dim menuItemName As %String = $Piece(MenuName,",",2)
123133
#dim ec As %Status = $$$OK
124-
125-
set ^mtemptsl($i(^mtemptsl)) = $lb(menuName,menuItemName)
126134

127135
if ..GitBinExists() = 0 && (menuItemName'="%Cache-Git-Settings") &&
128136
($system.Version.GetOS()="Windows") {
@@ -133,7 +141,7 @@ ClassMethod UserAction(InternalName As %String, MenuName As %String, ByRef Targe
133141
if (menuItemName = "%Settings") {
134142
set Action = 2
135143
set Target = "/isc/studio/usertemplates/gitsourcecontrol/gitprojectsettings.csp?NSpace="_$namespace_"&Username="_$username
136-
}elseif (menuItemName = "%Init") {
144+
} elseif (menuItemName = "%Init") {
137145
if ##class(%File).CreateDirectoryChain(..TempFolder()) {
138146
// cleanup items info
139147
kill @..#Storage@("items")
@@ -146,41 +154,40 @@ ClassMethod UserAction(InternalName As %String, MenuName As %String, ByRef Targe
146154
} elseif (menuItemName = "%GitWebUI") {
147155
set Action = 2
148156
set Target = "/isc/studio/usertemplates/gitsourcecontrol/webuidriver.csp/"_$namespace
149-
}elseif (menuItemName = "%Export") || (menuItemName = "%ExportForce") {
157+
} elseif (menuItemName = "%Export") || (menuItemName = "%ExportForce") {
150158
write "==export start==",!
151159
set ec = ..ExportAll($case(menuItemName="%ExportForce",1:$$$Force,:0))
152160
if ec {
153161
write !,"==export done==",!
154162
}
155-
}elseif (menuItemName = "%Import") {
163+
} elseif (menuItemName = "%Import") {
156164
set ec = ..ImportAll()
157165
set Reload = 1
158-
}elseif (menuItemName = "%ImportForce") {
166+
} elseif (menuItemName = "%ImportForce") {
159167
set ec = ..ImportAll($$$Force)
160168
set Reload = 1
161-
}elseif (menuItemName = "%OpenRepoFolder") {
169+
} elseif (menuItemName = "%OpenRepoFolder") {
162170
set Action = 3
163171
set Target = ..TempFolder()
164-
}elseif (menuItemName = "%Revert") {
172+
} elseif (menuItemName = "%Revert") {
165173
set Reload = 1
166174
quit ..Revert(InternalName)
167-
}elseif (menuItemName = "%Commit") {
175+
} elseif (menuItemName = "%Commit") {
168176
set Target = "Please enter a commit message"
169177
set Action = 7
170178
quit $$$OK
171-
}elseif (menuItemName = "%Push") {
179+
} elseif (menuItemName = "%Push") {
172180
quit ..Push()
173-
}elseif (menuItemName = "%Fetch") {
181+
} elseif (menuItemName = "%Fetch") {
174182
$$$QuitOnError(..Fetch(.diffFiles))
175183
set pointer = 0
176184
while $ListNext(diffFiles, pointer, item){
177185
write !,item
178186
}
179187
write !
180-
}elseif (menuItemName = "%Pull") {
188+
} elseif (menuItemName = "%Pull") {
181189
quit ..Pull()
182-
}
183-
elseif ..IsMenuGitCommand(menuItemName) {
190+
} elseif ..IsMenuGitCommand(menuItemName) {
184191
set Action = 3
185192
#dim command As %String = $ZConvert($Extract(menuItemName, 2, *), "L")
186193
set ec = $$$OK
@@ -192,16 +199,20 @@ ClassMethod UserAction(InternalName As %String, MenuName As %String, ByRef Targe
192199
set Target = ..GitCommand(command)
193200
}
194201
}
195-
}elseif (menuName = "%SourceContext") {
202+
} elseif (menuName = "%SourceContext") {
196203

197204
if (..Type(InternalName) = "csp") && ($Extract(InternalName,1) '= "/") {
198205
set InternalName = "/" _ InternalName
199206
}
200207

201208
if (menuItemName = "%AddToSC") {
202209
set ec = ..AddToSourceControl(InternalName)
203-
}elseif (menuItemName = "%RemoveFromSC") {
210+
} elseif (menuItemName = "%RemoveFromSC") {
204211
set ec = ..RemoveFromSourceControl(InternalName)
212+
} elseif (menuItemName = "%Commit") {
213+
set Target = "Please enter a commit message"
214+
set Action = 7
215+
quit $$$OK
205216
}
206217
if ..IsContextMenuGitCommand(menuItemName) {
207218
set Action = 3
@@ -283,7 +294,6 @@ ClassMethod Fetch(ByRef diffFiles) As %Status
283294

284295
ClassMethod Pull(remote As %String = "origin") As %Status
285296
{
286-
287297
#define Force 1
288298
do ##class(SourceControl.Git.Utils).RunGitCommandWithInput("branch",,.errStream,.outStream,"--show-current")
289299
set branchName = outStream.ReadLine(outStream.Size)
@@ -1309,5 +1319,13 @@ ClassMethod NameToInternalName(Name, IgnorePercent = 1, IgnoreNonexistent = 1) A
13091319
Quit ..NormalizeInternalName(InternalName)
13101320
}
13111321

1322+
ClassMethod OutputConfigureMessage()
1323+
{
1324+
if '..IsNamespaceInGit() {
1325+
write !!,"NOTE: To configure settings for git-source-control, run the following command: ",!
1326+
write "do ##class(SourceControl.Git.API).Configure()",!
1327+
}
1328+
}
1329+
13121330
}
13131331

module.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
<FileCopy Name="csp/gitprojectsettings.csp" Target="${libdir}../devuser/studio/templates/gitsourcecontrol/gitprojectsettings.csp" />
2121
<FileCopy Name="csp/webuidriver.csp" Target="${libdir}../devuser/studio/templates/gitsourcecontrol/webuidriver.csp" />
2222
<FileCopy Name="git-webui/release/share/git-webui/webui/" Target="${libdir}../devuser/studio/templates/gitsourcecontrol/" Overlay="1" />
23+
24+
<Invoke Class="SourceControl.Git.Utils" Method="OutputConfigureMessage" />
2325
</Module>
2426
</Document>
2527
</Export>

0 commit comments

Comments
 (0)