Skip to content

Commit 30cb595

Browse files
authored
Merge pull request #912 from intersystems/generated-read-only-option
Option to make generated files read-only
2 parents 1c9072c + 8752edd commit 30cb595

File tree

7 files changed

+84
-4
lines changed

7 files changed

+84
-4
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1010
### Added
1111
- Import All has been added to public-facing API (#891)
1212
- Web UI workspace view now has an option to abort merge in progress (#895)
13+
- New setting lets you treat generated classes as read-only in Studio/VS Code (#712)
1314

1415
## Fixed
1516
- Web UI workspace view labels changes as Merge Conflict if there are unmerged changes (#890)

cls/SourceControl/Git/Extension.cls

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -474,6 +474,8 @@ Method IsReadOnly(InternalName As %String) As %Boolean
474474
set settings = ##class(SourceControl.Git.Settings).%New()
475475
quit (##class(SourceControl.Git.Utils).Locked()
476476
&& '$get(^IRIS.Temp("sscProd",$job,"bypassLock")))
477+
|| (settings.generatedFilesReadOnly
478+
&& ##class(SourceControl.Git.Utils).ItemIsGenerated(InternalName))
477479
|| (##class(SourceControl.Git.Utils).ItemIsProductionToDecompose($get(InternalName))
478480
&& 'settings.decomposeProdAllowIDE
479481
&& '##class(SourceControl.Git.Production).IsEnsPortal())
@@ -588,3 +590,4 @@ Method CheckBusinessProcessesAndRules(InternalName As %String) As %Status
588590
}
589591

590592
}
593+

cls/SourceControl/Git/Settings.cls

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

54+
/// Whether generated files should be read-only within Studio/VS Code
55+
Property generatedFilesReadOnly As %Boolean [ InitialExpression = {##class(SourceControl.Git.Utils).GeneratedFilesReadOnly()} ];
56+
5457
/// Whether basic mode should be enabled for user ${username}, greatly simplifying the functionality of the package, requiring no knowledge of git
5558
Property basicMode As %String [ InitialExpression = {##class(SourceControl.Git.Utils).BasicMode()} ];
5659

@@ -179,6 +182,7 @@ Method %Save() As %Status
179182
set @storage@("settings","percentClassReplace") = ..percentClassReplace
180183
set @storage@("settings","settingsUIReadOnly") = ..settingsUIReadOnly
181184
set @storage@("settings", "mappedItemsReadOnly") = ..mappedItemsReadOnly
185+
set @storage@("settings", "generatedFilesReadOnly") = ..generatedFilesReadOnly
182186
set @storage@("settings", "defaultMergeBranch") = ..defaultMergeBranch
183187
set @storage@("settings", "compileOnImport") = ..compileOnImport
184188
set @storage@("settings", "warnInstanceWideUncommitted") = ..warnInstanceWideUncommitted
@@ -224,6 +228,7 @@ Method ToDynamicObject() As %DynamicObject [ Internal ]
224228
set settingsJSON = {
225229
"pullEventClass": (..pullEventClass),
226230
"percentClassReplace": (..percentClassReplace),
231+
"generatedFilesReadOnly": (..generatedFilesReadOnly),
227232
"Mappings": {}
228233
}
229234
do settingsJSON.%Set("decomposeProductions",..decomposeProductions,"boolean")
@@ -248,6 +253,7 @@ Method ImportDynamicObject(pSettingsDyn As %DynamicObject) [ Internal ]
248253
set ..pullEventClass = pSettingsDyn.%Get("pullEventClass")
249254
set ..percentClassReplace = pSettingsDyn.%Get("percentClassReplace")
250255
set ..decomposeProductions = pSettingsDyn.%Get("decomposeProductions")
256+
set ..generatedFilesReadOnly = pSettingsDyn.%Get("generatedFilesReadOnly")
251257
kill ..Mappings
252258
set mappingsDyn = pSettingsDyn.%Get("Mappings", {})
253259
set i1 = mappingsDyn.%GetIterator()
@@ -546,7 +552,7 @@ Method RetrieveDefaults() As %Boolean [ Internal ]
546552
Method SaveDefaults() As %Boolean
547553
{
548554
set defaults = {}
549-
set items = $lb("gitBinPath", "pullEventClass", "percentClassReplace", "environmentName", "systemBasicMode", "defaultMergeBranch", "mappedItemsReadOnly", "compileOnImport")
555+
set items = $lb("gitBinPath", "pullEventClass", "percentClassReplace", "environmentName", "systemBasicMode", "defaultMergeBranch", "mappedItemsReadOnly", "generatedFilesReadOnly", "compileOnImport")
550556
for i=1:1:$LISTLENGTH(items) {
551557
set property = $listget(items,i)
552558
do defaults.%Set(property, $property($this, property))
@@ -555,4 +561,3 @@ Method SaveDefaults() As %Boolean
555561
}
556562

557563
}
558-

cls/SourceControl/Git/Utils.cls

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,11 @@ ClassMethod MappedItemsReadOnly() As %Boolean
155155
quit $get(@..#Storage@("settings", "mappedItemsReadOnly"), 1)
156156
}
157157

158+
ClassMethod GeneratedFilesReadOnly() As %Boolean
159+
{
160+
quit $get(@..#Storage@("settings", "generatedFilesReadOnly"), 0)
161+
}
162+
158163
ClassMethod GitUserName() As %String
159164
{
160165
quit $get(@..#Storage@("settings","user",$username,"gitUserName"),$username)
@@ -1103,6 +1108,11 @@ ClassMethod Type(InternalName As %String) As %String
11031108
quit type
11041109
}
11051110

1111+
ClassMethod ItemIsGenerated(InternalName As %String) As %Boolean
1112+
{
1113+
return ##class(%RoutineMgr).IsGenerated(..NormalizeInternalName(InternalName))
1114+
}
1115+
11061116
ClassMethod NameWithoutExtension(InternalName As %String) As %String [ CodeMode = expression ]
11071117
{
11081118
$Piece(InternalName, ".", 1, $Length(InternalName,".")-1)
@@ -3341,4 +3351,3 @@ ClassMethod IsSchemaStandard(pName As %String = "") As %Boolean [ Internal ]
33413351
}
33423352

33433353
}
3344-

csp/gitprojectsettings.csp

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,12 @@ body {
130130
set settings.mappedItemsReadOnly = 0
131131
}
132132

133+
if ($Get(%request.Data("generatedFilesReadOnly", 1)) = 1) {
134+
set settings.generatedFilesReadOnly = 1
135+
} else {
136+
set settings.generatedFilesReadOnly = 0
137+
}
138+
133139

134140
set settings.compileOnImport = ($Get(%request.Data("compileOnImport", 1)) = 1)
135141
set settings.decomposeProductions = ($Get(%request.Data("decomposeProductions", 1)) = 1)
@@ -502,6 +508,18 @@ body {
502508
</div>
503509

504510

511+
</div>
512+
<div class="form-group row mb-3">
513+
<label for="generatedFilesReadOnly" class="offset-sm-1 col-sm-3 col-form-label" data-toggle="tooltip" data-placement="top" title="When enabled, classes marked as generated (for example, by the IRIS compiler) are treated as read-only and cannot be edited from Studio/VS Code."><b> Treat Generated Files as Read-only</b></label>
514+
<div class="col-sm-7">
515+
<div class="custom-control custom-switch custom-switch-no-border">
516+
<input class="custom-control-input" name="generatedFilesReadOnly" type="checkbox" id="generatedFilesReadOnly"
517+
#($select(settings.generatedFilesReadOnly:"checked", 1: ""))# value="1">
518+
<label class="custom-control-label" for="generatedFilesReadOnly"></label>
519+
</div>
520+
</div>
521+
522+
505523
</div>
506524
<div class="form-group row mb-3">
507525
<label for="compileOnImport" class="offset-sm-1 col-sm-3 col-form-label" data-toggle="tooltip" data-placement="top" title="If true, the Import All options will compile imported options using the configured pull event handler"><b>Compile Items on Import</b></label>
@@ -986,4 +1004,4 @@ $('.mapping-input-group').children('.voca').each(function(){
9861004
// ignore; may occur on platform versions without the above properties
9871005
}
9881006
quit 1
989-
</script>
1007+
</script>
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
Class UnitTest.SourceControl.Git.Extension Extends UnitTest.SourceControl.Git.AbstractTest
2+
{
3+
4+
Method TestGeneratedFilesReadOnlyOption()
5+
{
6+
set sc = $$$OK
7+
set classCreated = 0
8+
try {
9+
do $System.OBJ.Delete("UnitTest.SourceControl.Git.GeneratedReadOnly")
10+
set classDef = ##class(%Dictionary.ClassDefinition).%New()
11+
set classDef.Name = "UnitTest.SourceControl.Git.GeneratedReadOnly"
12+
set classDef.GeneratedBy = "UnitTest.SourceControl.Git.GeneratedBy"
13+
$$$ThrowOnError(classDef.%Save())
14+
$$$ThrowOnError($System.OBJ.Compile("UnitTest.SourceControl.Git.GeneratedReadOnly", "ck"))
15+
set classCreated = 1
16+
17+
set settings = ##class(SourceControl.Git.Settings).%New()
18+
set settings.generatedFilesReadOnly = 0
19+
$$$ThrowOnError(settings.%Save())
20+
set extension = ##class(SourceControl.Git.Extension).%New("")
21+
do $$$AssertNotTrue(extension.IsReadOnly("UnitTest.SourceControl.Git.GeneratedReadOnly.cls"))
22+
23+
set settings.generatedFilesReadOnly = 1
24+
$$$ThrowOnError(settings.%Save())
25+
do $$$AssertTrue(extension.IsReadOnly("UnitTest.SourceControl.Git.GeneratedReadOnly.cls"))
26+
} catch err {
27+
set sc = err.AsStatus()
28+
}
29+
if classCreated {
30+
do $System.OBJ.Delete("UnitTest.SourceControl.Git.GeneratedReadOnly")
31+
}
32+
$$$ThrowOnError(sc)
33+
}
34+
35+
}

test/UnitTest/SourceControl/Git/Settings.cls

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ Method SampleSettingsJSON()
1111
"pullEventClass": "pull event class",
1212
"percentClassReplace": "x",
1313
"decomposeProductions": true,
14+
"generatedFilesReadOnly": true,
1415
"Mappings": {
1516
"TUV": {
1617
"*": {
@@ -37,10 +38,12 @@ Method TestJSONImportExport()
3738
set settings.decomposeProductions = ""
3839
set settings.percentClassReplace = ""
3940
set settings.pullEventClass = ""
41+
set settings.generatedFilesReadOnly = 0
4042
do settings.ImportDynamicObject(settingsDynObj)
4143
do $$$AssertEquals(settings.decomposeProductions, 1)
4244
do $$$AssertEquals(settings.percentClassReplace, "x")
4345
do $$$AssertEquals(settings.pullEventClass, "pull event class")
46+
do $$$AssertEquals(settings.generatedFilesReadOnly, 1)
4447
do $$$AssertEquals($get(settings.Mappings("TUV","*")),"tuv/")
4548
do $$$AssertEquals($get(settings.Mappings("TUV","UnitTest")),"tuv2/")
4649
do $$$AssertTrue($get(settings.Mappings("TUV","UnitTest","NoFolders")))
@@ -52,6 +55,7 @@ Method TestJSONImportExport()
5255
do $$$AssertEquals(settingsDynObj.decomposeProductions, 1)
5356
do $$$AssertEquals(settingsDynObj.percentClassReplace, "x")
5457
do $$$AssertEquals(settingsDynObj.pullEventClass, "pull event class")
58+
do $$$AssertEquals(settingsDynObj.generatedFilesReadOnly, 1)
5559
do $$$AssertEquals(settingsDynObj.Mappings."TUV"."*".directory,"tuv/")
5660
do $$$AssertEquals(settingsDynObj.Mappings."TUV"."UnitTest".directory,"tuv2/")
5761
do $$$AssertTrue(settingsDynObj.Mappings."TUV"."UnitTest".noFolders)
@@ -66,6 +70,7 @@ Method TestSaveAndImportSettings()
6670
set settings.pullEventClass = "SourceControl.Git.PullEventHandler.Default"
6771
set settings.percentClassReplace = "_"
6872
set settings.decomposeProductions = 1
73+
set settings.generatedFilesReadOnly = 1
6974
$$$ThrowOnError(settings.SaveWithSourceControl())
7075
do $$$AssertStatusOK(##class(SourceControl.Git.Utils).AddToSourceControl("embedded-git-config.GSC"))
7176
// settings file should be in source control
@@ -78,24 +83,28 @@ Method TestSaveAndImportSettings()
7883
do $$$AssertEquals(^SYS("SourceControl","Git","settings","pullEventClass"),"SourceControl.Git.PullEventHandler.Default")
7984
do $$$AssertEquals(^SYS("SourceControl","Git","settings","percentClassReplace"),"_")
8085
do $$$AssertEquals(^SYS("SourceControl","Git","settings","decomposeProductions"),"1")
86+
do $$$AssertEquals(^SYS("SourceControl","Git","settings","generatedFilesReadOnly"),"1")
8187
// change and save settings
8288
set settings.Mappings("CLS","Foo") = "foo2/"
8389
set settings.pullEventClass = "SourceControl.Git.PullEventHandler.IncrementalLoad"
8490
set settings.percentClassReplace = "x"
8591
set settings.decomposeProductions = 0
92+
set settings.generatedFilesReadOnly = 0
8693
$$$ThrowOnError(settings.SaveWithSourceControl())
8794
// new setting should be in the global
8895
do $$$AssertEquals(^SYS("SourceControl","Git","settings","mappings","CLS","Foo"),"foo2/")
8996
do $$$AssertEquals(^SYS("SourceControl","Git","settings","pullEventClass"),"SourceControl.Git.PullEventHandler.IncrementalLoad")
9097
do $$$AssertEquals(^SYS("SourceControl","Git","settings","percentClassReplace"),"x")
9198
do $$$AssertEquals(^SYS("SourceControl","Git","settings","decomposeProductions"),"0")
99+
do $$$AssertEquals(^SYS("SourceControl","Git","settings","generatedFilesReadOnly"),"0")
92100
// revert change to settings
93101
do $$$AssertStatusOK(##class(SourceControl.Git.Utils).Revert("embedded-git-config.GSC"))
94102
// old setting should be in the global
95103
do $$$AssertEquals(^SYS("SourceControl","Git","settings","mappings","CLS","Foo"),"foo/")
96104
do $$$AssertEquals(^SYS("SourceControl","Git","settings","pullEventClass"),"SourceControl.Git.PullEventHandler.Default")
97105
do $$$AssertEquals(^SYS("SourceControl","Git","settings","percentClassReplace"),"_")
98106
do $$$AssertEquals(^SYS("SourceControl","Git","settings","decomposeProductions"),"1")
107+
do $$$AssertEquals(^SYS("SourceControl","Git","settings","generatedFilesReadOnly"),"1")
99108
}
100109

101110
Method OnBeforeAllTests() As %Status

0 commit comments

Comments
 (0)