Skip to content

Commit adba035

Browse files
committed
added basic mode
1 parent c6cbad3 commit adba035

File tree

7 files changed

+168
-9607
lines changed

7 files changed

+168
-9607
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1212
- Pre-release support for IPM v0.9.0+
1313
- Items mapped from database other than namespace's default routine database are now ignored by default when exporting or adding files
1414
- New setting to configure whether mapped items should be should be treated as read-only
15+
- Added a basic mode to automatically perform functionality expected in basic use cases (#349)
16+
- New sync operation for basic mode that fetches, pulls, commits and then pushes (#349)
1517

1618
## [2.3.1] - 2024-04-30
1719

cls/SourceControl/Git/Extension.cls

Lines changed: 68 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ XData Menu
2020
<MenuItem Name="Revert" />
2121
<MenuItem Name="Commit" />
2222
<MenuItem Separator="true"/>
23+
<MenuItem Name="Sync" />
2324
<MenuItem Name="Push" />
2425
<MenuItem Name="Fetch" />
2526
<MenuItem Name="Pull" />
@@ -55,9 +56,9 @@ Method UserAction(Type As %Integer, Name As %String, InternalName As %String, Se
5556
quit $$$OK
5657
}
5758

58-
set InternalName = ##class(Utils).NormalizeInternalName(InternalName)
59+
set InternalName = ##class(SourceControl.Git.Utils).NormalizeInternalName(InternalName)
5960
set context = ##class(SourceControl.Git.PackageManagerContext).ForInternalName(InternalName)
60-
set ec = ##class(Utils).UserAction(InternalName, Name, .Target, .Action, .Reload)
61+
set ec = ##class(SourceControl.Git.Utils).UserAction(InternalName, Name, .Target, .Action, .Reload)
6162
quit ec
6263
}
6364

@@ -68,9 +69,9 @@ Method AfterUserAction(Type As %Integer, Name As %String, InternalName As %Strin
6869
if menu '= "%SourceMenu", menu'="%SourceContext" {
6970
quit $$$OK
7071
}
71-
set InternalName = ##class(Utils).NormalizeInternalName(InternalName)
72+
set InternalName = ##class(SourceControl.Git.Utils).NormalizeInternalName(InternalName)
7273
set context = ##class(SourceControl.Git.PackageManagerContext).ForInternalName(InternalName)
73-
set ec = ##class(Utils).AfterUserAction(Type, Name, InternalName, .Answer, .Msg, .Reload)
74+
set ec = ##class(SourceControl.Git.Utils).AfterUserAction(Type, Name, InternalName, .Answer, .Msg, .Reload)
7475
quit ec
7576
}
7677

@@ -90,6 +91,7 @@ Method LocalizeName(name As %String) As %String
9091
"SwitchBranch":$$$Text("@SwitchBranch@Check out an existing branch"),
9192
"Revert":$$$Text("@Revert@Discard changes to file"),
9293
"Commit":$$$Text("@Commit@Commit changes to file"),
94+
"Sync":$$$Text("@Sync@Sync"),
9395
"Push":$$$Text("@Push@Push to remote branch"),
9496
"Fetch":$$$Text("@Fetch@Fetch from remote"),
9597
"Pull":$$$Text("@Pull@Pull changes from remote branch"),
@@ -99,36 +101,52 @@ Method LocalizeName(name As %String) As %String
99101

100102
Method OnSourceMenuItem(name As %String, ByRef Enabled As %String, ByRef DisplayName As %String, InternalName As %String) As %Status
101103
{
104+
102105
if name = "Settings" {
103106
set Enabled = 1
104107
quit $$$OK
105108
}
106-
if ##class(Utils).NeedSettings() {
109+
if ##class(SourceControl.Git.Utils).NeedSettings() {
107110
set Enabled = -1
108111
quit $$$OK
109112
}
110-
if ##class(Utils).IsNamespaceInGit() {
111-
if $listfind($listbuild("AddToSC", "RemoveFromSC", "Revert", "Commit"), name) {
112-
quit ..OnSourceMenuContextItem(InternalName,name,.Enabled,.DisplayName)
113-
}
114-
set Enabled = $CASE(name,
115-
// cases
116-
"Status": 1,
117-
"GitWebUI" : 1,
118-
"Export": 1,
119-
"ExportForce": 1,
120-
"Import": 1,
121-
"ImportForce": 1,
122-
"NewBranch": 1,
123-
"SwitchBranch": 1,
124-
"Push": 1,
125-
"Fetch": 1,
126-
"Pull": 1,
127-
"": 1,
128-
:-1 // default
129-
)
113+
if ##class(SourceControl.Git.Utils).IsNamespaceInGit() {
114+
115+
if $listfind($listbuild("AddToSC", "RemoveFromSC", "Revert", "Commit"), name) {
116+
quit ..OnSourceMenuContextItem(InternalName,name,.Enabled,.DisplayName)
117+
}
118+
119+
if ##class(SourceControl.Git.Utils).BasicMode() {
120+
set Enabled = $CASE(name,
121+
"Status": 1,
122+
"GitWebUI" : 1,
123+
"Sync": 1,
124+
"": 1,
125+
:-1
126+
127+
)
128+
} else {
129+
set Enabled = $CASE(name,
130+
// cases
131+
"Status": 1,
132+
"GitWebUI" : 1,
133+
"Export": 1,
134+
"ExportForce": 1,
135+
"Import": 1,
136+
"ImportForce": 1,
137+
"NewBranch": 1,
138+
"SwitchBranch": 1,
139+
"Push": 1,
140+
"Fetch": 1,
141+
"Pull": 1,
142+
"Sync": -1,
143+
"": 1,
144+
:-1 // default
145+
)
146+
}
130147

131-
} elseif ##class(Utils).GitBinExists() {
148+
149+
} elseif ##class(SourceControl.Git.Utils).GitBinExists() {
132150
if name = "Init" {
133151
} else {
134152
set Enabled = -1
@@ -141,7 +159,7 @@ Method OnSourceMenuItem(name As %String, ByRef Enabled As %String, ByRef Display
141159

142160
Method OnSourceMenuContextItem(itemName As %String, menuItemName As %String, ByRef Enabled As %String, ByRef DisplayName As %String) As %Status
143161
{
144-
if (itemName = "") || '##class(Utils).IsNamespaceInGit() {
162+
if (itemName = "") || '##class(SourceControl.Git.Utils).IsNamespaceInGit() {
145163
set Enabled = -1
146164
} elseif (($find(itemName,",") > 0) || (##class(SourceControl.Git.Utils).Type(itemName) = "pkg")) {
147165
//if more than one item is selected, we can only add/remove, no diff or blame
@@ -150,16 +168,16 @@ Method OnSourceMenuContextItem(itemName As %String, menuItemName As %String, ByR
150168
} elseif menuItemName = "Revert" {
151169
set Enabled = 1
152170
do ..GetStatus(.itemName, .isInSourceControl, .isEditable,.isCheckedOut,.userCheckedOut)
153-
if '(##class(Change).IsUncommitted(##class(Utils).FullExternalName(itemName))) || ($username '= userCheckedOut) {
171+
if '(##class(SourceControl.Git.Change).IsUncommitted(##class(SourceControl.Git.Utils).FullExternalName(itemName))) || ($username '= userCheckedOut) {
154172
set Enabled = 0
155173
}
156174
} elseif menuItemName = "Commit" {
157175
set Enabled = 1
158176
do ..GetStatus(.itemName, .isInSourceControl, .isEditable,.isCheckedOut,.userCheckedOut)
159-
if '(##class(Change).IsUncommitted(##class(Utils).FullExternalName(itemName))) || ($username '= userCheckedOut) {
177+
if '(##class(SourceControl.Git.Change).IsUncommitted(##class(SourceControl.Git.Utils).FullExternalName(itemName))) || ($username '= userCheckedOut) {
160178
set Enabled = 0
161179
}
162-
} elseif ##class(Utils).IsInSourceControl(itemName) {
180+
} elseif ##class(SourceControl.Git.Utils).IsInSourceControl(itemName) {
163181
set Enabled = $case(menuItemName, "AddToSC":-1,:1)
164182
} else {
165183
set Enabled = $case(menuItemName, "AddToSC":1,:-1)
@@ -174,7 +192,7 @@ Method OnSourceMenuContextItem(itemName As %String, menuItemName As %String, ByR
174192
/// this menu item from the list totally, 0 will gray the menu item out and the default 1 will display the menu item as normal.
175193
Method OnMenuItem(MenuName As %String, InternalName As %String, SelectedText As %String, ByRef Enabled As %Boolean, ByRef DisplayName As %String) As %Status
176194
{
177-
set InternalName = ##class(Utils).NormalizeInternalName(InternalName)
195+
set InternalName = ##class(SourceControl.Git.Utils).NormalizeInternalName(InternalName)
178196
set context = ##class(SourceControl.Git.PackageManagerContext).ForInternalName(InternalName)
179197

180198
#dim menu as %String= $piece(MenuName,",")
@@ -200,9 +218,9 @@ Method OnMenuItem(MenuName As %String, InternalName As %String, SelectedText As
200218
Method OnBeforeLoad(InternalName As %String, verbose As %Boolean) As %Status
201219
{
202220
set context = ##class(SourceControl.Git.PackageManagerContext).ForInternalName(InternalName)
203-
set InternalName = ##class(Utils).NormalizeInternalName(InternalName)
204-
if ##class(Utils).IsInSourceControl(InternalName) {
205-
quit ##class(Utils).ImportItem(InternalName,,0)
221+
set InternalName = ##class(SourceControl.Git.Utils).NormalizeInternalName(InternalName)
222+
if ##class(SourceControl.Git.Utils).IsInSourceControl(InternalName) {
223+
quit ##class(SourceControl.Git.Utils).ImportItem(InternalName,,0)
206224
}
207225
quit $$$OK
208226
}
@@ -236,15 +254,17 @@ Method OnAfterSave(InternalName As %String, Object As %RegisteredObject = {$$$NU
236254
{
237255
set sc = $$$OK
238256
try {
239-
set InternalName = ##class(Utils).NormalizeInternalName(.InternalName)
257+
set InternalName = ##class(SourceControl.Git.Utils).NormalizeInternalName(.InternalName)
240258
set context = ##class(SourceControl.Git.PackageManagerContext).ForInternalName(InternalName)
241-
if ##class(Utils).IsNamespaceInGit() && ..IsInSourceControl(InternalName) {
242-
set filename = ##class(Utils).FullExternalName(InternalName)
243-
$$$ThrowOnError(##class(Utils).RemoveRoutineTSH(InternalName))
244-
$$$ThrowOnError(##class(Utils).ExportItem(InternalName))
259+
if ##class(SourceControl.Git.Utils).IsNamespaceInGit() && ..IsInSourceControl(InternalName) {
260+
set filename = ##class(SourceControl.Git.Utils).FullExternalName(InternalName)
261+
$$$ThrowOnError(##class(SourceControl.Git.Utils).RemoveRoutineTSH(InternalName))
262+
$$$ThrowOnError(##class(SourceControl.Git.Utils).ExportItem(InternalName))
245263
if '##class(SourceControl.Git.Change).IsUncommitted(filename) {
246264
$$$ThrowOnError(##class(SourceControl.Git.Change).SetUncommitted(filename, "edit", InternalName, $username, "", 1, "", "", 0))
247265
}
266+
} elseif ##class(SourceControl.Git.Utils).BasicMode() {
267+
do ..AddToSourceControl(InternalName)
248268
}
249269
} catch e {
250270
do e.Log()
@@ -262,7 +282,7 @@ Method OnAfterCompile(InternalName As %String) As %Status
262282
/// Returns true if this item is in source control and false otherwise.
263283
Method IsInSourceControl(InternalName As %String) As %Boolean [ CodeMode = expression ]
264284
{
265-
InternalName'="" && ##class(Utils).IsInSourceControl(##class(Utils).NormalizeInternalName(InternalName))
285+
InternalName'="" && ##class(SourceControl.Git.Utils).IsInSourceControl(##class(SourceControl.Git.Utils).NormalizeInternalName(InternalName))
266286
}
267287

268288
/// Called before an item is deleted.
@@ -273,10 +293,10 @@ Method OnBeforeDelete(InternalName As %String) As %Status
273293
Throw ##class(%Exception.General).%New("Can't delete in locked environment")
274294
} else {
275295
set context = ##class(SourceControl.Git.PackageManagerContext).ForInternalName(InternalName)
276-
set InternalName = ##class(Utils).NormalizeInternalName(InternalName)
277-
set Filename = ##class(Utils).FullExternalName(InternalName)
278-
if ##class(Utils).IsInSourceControl(InternalName) && ##class(%File).Exists(Filename) {
279-
quit ##class(Change).AddDeletedToUncommitted(Filename, InternalName)
296+
set InternalName = ##class(SourceControl.Git.Utils).NormalizeInternalName(InternalName)
297+
set Filename = ##class(SourceControl.Git.Utils).FullExternalName(InternalName)
298+
if ##class(SourceControl.Git.Utils).IsInSourceControl(InternalName) && ##class(%File).Exists(Filename) {
299+
quit ##class(SourceControl.Git.Change).AddDeletedToUncommitted(Filename, InternalName)
280300
}
281301
quit $$$OK
282302
}
@@ -286,9 +306,9 @@ Method OnBeforeDelete(InternalName As %String) As %Status
286306
Method OnAfterDelete(InternalName As %String) As %Status
287307
{
288308
set context = ##class(SourceControl.Git.PackageManagerContext).ForInternalName(InternalName)
289-
set InternalName = ##class(Utils).NormalizeInternalName(InternalName)
290-
if ##class(Utils).IsInSourceControl(InternalName) {
291-
quit ##class(Utils).DeleteExternalFile(InternalName)
309+
set InternalName = ##class(SourceControl.Git.Utils).NormalizeInternalName(InternalName)
310+
if ##class(SourceControl.Git.Utils).IsInSourceControl(InternalName) {
311+
quit ##class(SourceControl.Git.Utils).DeleteExternalFile(InternalName)
292312
}
293313
quit $$$OK
294314
}
@@ -297,7 +317,7 @@ Method OnAfterDelete(InternalName As %String) As %Status
297317
/// the routine/class/csp item. This is often a filename to write the file out to.
298318
Method ExternalName(InternalName As %String) As %String
299319
{
300-
quit ##class(Utils).ExternalName(InternalName)
320+
quit ##class(SourceControl.Git.Utils).ExternalName(InternalName)
301321
}
302322

303323
Method IsReadOnly(InternalName As %String) As %Boolean

cls/SourceControl/Git/Settings.cls

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,11 @@ Property gitUserEmail As %String(MAXLEN = 255) [ InitialExpression = {##class(So
3232
/// Attribution: Whether mapped items should be read-only, preventing them from being added to source control
3333
Property mappedItemsReadOnly As %Boolean [ InitialExpression = {##class(SourceControl.Git.Utils).MappedItemsReadOnly()} ];
3434

35+
/// Attribution: Whether basic mode should be enabled for user ${username}, greatly simplifying the functionality of the package, requiring no knowledge of git
36+
Property basicMode As %Boolean [ InitialExpression = {##class(SourceControl.Git.Utils).BasicMode()} ];
37+
38+
Property systemBasicMode As %Boolean [ InitialExpression = {##class(SourceControl.Git.Utils).SystemBasicMode()} ];
39+
3540
Property Mappings [ MultiDimensional ];
3641

3742
Method %OnNew() As %Status
@@ -84,6 +89,8 @@ Method %Save() As %Status
8489
set @storage@("settings","percentClassReplace") = ..percentClassReplace
8590
set @storage@("settings","settingsUIReadOnly") = ..settingsUIReadOnly
8691
set @storage@("settings", "mappedItemsReadOnly") = ..mappedItemsReadOnly
92+
set @storage@("settings", "user", $username, "basicMode") = ..basicMode
93+
set @storage@("settings", "basicMode") = ..systemBasicMode
8794

8895
kill @##class(SourceControl.Git.Utils).MappingsNode()
8996
merge @##class(SourceControl.Git.Utils).MappingsNode() = ..Mappings

cls/SourceControl/Git/Utils.cls

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@ Parameter InstallNamespace = "%SYS";
1010
Parameter Slash = {$case($system.Version.GetOS(),"Windows":"\",:"/")};
1111

1212
/// Name of the file with version controlled items
13-
Parameter GitMenuItems = ",Settings,Commit,Pull,Fetch,Push,Revert,";
13+
Parameter GitMenuItems = ",Settings,Commit,Sync,Pull,Fetch,Push,Revert,";
1414

15-
Parameter ImportAfterGitMenuItems = ",Commit,Pull,Fetch,Push,";
15+
Parameter ImportAfterGitMenuItems = ",Commit,Sync,Pull,Fetch,Push,";
1616

1717
Parameter GitContextMenuItems = ",%Diff,%Blame,";
1818

@@ -113,6 +113,16 @@ ClassMethod GitBinPath(Output isDefault) As %String
113113
quit $case($extract(binPath),"""":binPath,:""""_binPath_"""")
114114
}
115115

116+
ClassMethod BasicMode() As %Boolean
117+
{
118+
quit $get(@..#Storage@("settings", "user", $username, "basicMode"), ..SystemBasicMode())
119+
}
120+
121+
ClassMethod SystemBasicMode() As %Boolean
122+
{
123+
quit $get(@..#Storage@("settings", "basicMode"), 0)
124+
}
125+
116126
ClassMethod MappedItemsReadOnly() As %Boolean
117127
{
118128
quit $get(@..#Storage@("settings", "mappedItemsReadOnly"), 1)
@@ -227,6 +237,8 @@ ClassMethod UserAction(InternalName As %String, MenuName As %String, ByRef Targe
227237
set Target = "Please enter a commit message"
228238
set Action = 7
229239
quit $$$OK
240+
} elseif (menuItemName = "Sync") {
241+
quit ..Sync()
230242
} elseif (menuItemName = "Push") {
231243
quit ..Push()
232244
} elseif (menuItemName = "Fetch") {
@@ -322,6 +334,22 @@ ClassMethod SwitchBranch(targetBranchName As %String) As %Status
322334
quit $$$OK
323335
}
324336

337+
ClassMethod Sync() As %Status
338+
{
339+
write "Syncing local repository..."
340+
if '..HasRemoteRepo() {
341+
write "No remote repository configured: skipping fetch, pull and push"
342+
do ..Commit("", "Committing all files through sync command")
343+
} else {
344+
do ..Fetch()
345+
do ..Pull()
346+
do ..Commit("", "Committing all files through sync command")
347+
do ..Push()
348+
}
349+
350+
quit $$$OK
351+
}
352+
325353
ClassMethod Push(remote As %String = "origin") As %Status
326354
{
327355
do ##class(SourceControl.Git.Utils).RunGitCommandWithInput("branch",,.errStream,.outstream,"--show-current")
@@ -1456,6 +1484,15 @@ ClassMethod RemoveFolderIfEmpty(path As %String) As %Boolean
14561484
quit 'fileCount
14571485
}
14581486

1487+
ClassMethod HasRemoteRepo() As %Boolean
1488+
{
1489+
do ..RunGitCommand("remote", .errStream,.outStream)
1490+
if outStream.SizeGet() = 0 {
1491+
quit 0
1492+
}
1493+
quit 1
1494+
}
1495+
14591496
ClassMethod RunGitWithArgs(Output errStream, Output outStream, args...) As %Integer
14601497
{
14611498
set command = args(1)
@@ -1473,7 +1510,7 @@ ClassMethod RunGitCommand(command As %String, Output errStream, Output outStream
14731510
ClassMethod RunGitCommandWithInput(command As %String, inFile As %String = "", Output errStream, Output outStream, args...) As %Integer
14741511
{
14751512
// Special case: git --version is used internally even when the settings incorporated here may be invalid/unspecified.
1476-
if (command '= "--version") {
1513+
if (command '= "--version") && (command '= "remote") {
14771514
set newArgs($increment(newArgs)) = "-C"
14781515
set newArgs($increment(newArgs)) = ..TempFolder()
14791516

0 commit comments

Comments
 (0)