Skip to content

No folders fix #138

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Mar 22, 2022
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 25 additions & 31 deletions cls/SourceControl/Git/Utils.cls
Original file line number Diff line number Diff line change
Expand Up @@ -450,7 +450,7 @@ ClassMethod AddToSourceControl(InternalName As %String) As %Status
set @..#Storage@("items", item) = ""
}

#dim sc as %Status = ..ExportItem(item,,,.filenames)
#dim sc as %Status = ..ExportItem(item,,1,.filenames)
if 'sc {
set ec = $$$ADDSC(ec, sc)
}
Expand Down Expand Up @@ -1437,7 +1437,7 @@ ClassMethod Name(InternalName As %String) As %String
quit ""
}

set default=1
set default=0
set p=$order($$$SourceMapping(ext,nam))
for{
set p=$order($$$SourceMapping(ext,p),-1)
Expand All @@ -1447,9 +1447,10 @@ ClassMethod Name(InternalName As %String) As %String
}
}

if ($data(found)=0) && ($data($$$SourceMapping(ext,"*"),found)) && ('$$$GetSourceMapping(ext,"*","NoFolders")){
if ($data(found)=0) && ($data($$$SourceMapping(ext,"*"),found)=1) && ('$$$GetSourceMapping(ext,"*","NoFolders")){
set default=1
} elseif ($data(found)=0) && ($data($$$SourceMapping(ext,"*","NoFolders"), found)){
set default=0

} elseif $data(found)=0{
set found = $zconvert(ext,"L")_"/"
}
Expand All @@ -1466,14 +1467,14 @@ ClassMethod Name(InternalName As %String) As %String

} elseif ext="CLS"||(ext="PRJ")||(usertype&&(##class(%RoutineMgr).UserType(InternalName))) {
set nam=$translate(nam,"%", ..PercentClassReplace())
if '$$$GetSourceMapping(ext,"*","NoFolders"){
if '$data($$$SourceMapping(ext,"*","NoFolders")){
set nam=$translate(nam,".","/")
}
#; If match ends in '`' character use UDL/CLS format rather than XML format
return $translate(found_nam_"."_$zconvert(ext, "l"),"\","/")
}

if ('default){
if (default){
quit $translate($get(found)_$translate(nam,"%.","_/")_"."_$zconvert(ext,"l"),"\","/")
} else {
quit $translate($get(found)_nam_"."_$zconvert(ext,"l"),"\","/")
Expand Down Expand Up @@ -1503,35 +1504,28 @@ ClassMethod NameToInternalName(Name, IgnorePercent = 1, IgnoreNonexistent = 1) A
&sql(SELECT internalName into :InternalName FROM SourceControl_Git.Change where ItemFile = :Name)
if (SQLCODE = 100) {
set InternalName = ""
} else{
set Deleted = 1
}
set Deleted = 1
}
if (InternalName="") {
if ($zconvert(Name,"U")'[$zconvert($$$SourceRoot,"U")) {
quit "" // file is not in ^Sources so translation cannot occur
}
set name=$extract(Name,$length($$$SourceRoot)+1,*)
set name=$replace(name,"\","/") // standardize slash direction
if (name["/") {
//file is in a subdirectory under the ^Sources root
set nam=$piece(name,"/",2,$length(name,"/")),extDir=$piece(name,"/")_"/"
if nam="" quit ""

set queryary=$query($$$SourceMapping(""),-1,dir), subscript=$qsubscript(queryary,1)
while (queryary'="")&&(subscript'=0) {
if (dir["/")&&(dir=extDir) {
set ext=subscript
quit
}
set queryary=$query(@queryary,-1,dir)
if (queryary="") {
quit
}
set subscript=$qsubscript(queryary,1)
//file is in a subdirectory under the ^Sources root
set nam = name

set queryary=$query($$$SourceMapping(""),-1,dir), mappingsSubscript = $qsubscript(queryary,4), subscript=$qsubscript(queryary,5)
while (queryary'="")&&(mappingsSubscript="mappings") {
if (dir["/")&&(dir=$extract(name, 1, $length(dir))) {
set ext=subscript
set nam = $extract(name, $length(dir)+1, *)
quit
}
} else {
//there is no leading directory to remove
set nam=name
set queryary=$query(@queryary,-1,dir)
if (queryary="") {
quit
}
set mappingsSubscript = $qsubscript(queryary,4), subscript=$qsubscript(queryary,5)
}

if ($get(ext)="/CSP/") {
Expand All @@ -1556,7 +1550,7 @@ ClassMethod NameToInternalName(Name, IgnorePercent = 1, IgnoreNonexistent = 1) A
}
}
set fileExt=$zconvert($piece(nam,".",$length(nam,".")),"L")
if (InternalName="")&&('$data(ext)=0)&&('$listfind($listbuild("xml","rtn"),fileExt)) {
if (InternalName="")&&($data(ext)=0)&&('$listfind($listbuild("xml","rtn"),fileExt)) {
//no match found yet, and this is in a subdir for a specific document type (ext), however it is not in a typical export format
//so treat it as a non-mapped file
kill ext
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If $data(ext)=0 then killing it is a no-op.

Expand All @@ -1566,7 +1560,7 @@ ClassMethod NameToInternalName(Name, IgnorePercent = 1, IgnoreNonexistent = 1) A
}
if (InternalName="") {
//take our best guess based on the document extension mapped to that subdirectory
set nam=$piece(nam,".",1*-1)
set nam=$piece(nam,".",1,*-1)
set nam=$translate(nam,"_/","%.")
set InternalName=nam_"."_fileExt
if (fileExt="cls") {
Expand Down
80 changes: 41 additions & 39 deletions csp/gitprojectsettings.csp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ body {
border-left: none;
border-radius: 0 0.25rem 0.25rem 0;
}

#NoFolders {
display: none;
}
#webuiURL {
display: none;
}
Expand All @@ -42,10 +46,6 @@ body {
border: 1px solid #ced4da;
border-left: 0px;
}

hr {
opacity: 0.15
}
</style>
</head>
<body>
Expand All @@ -64,14 +64,15 @@ hr {
set $Property(settings,param) = $Get(%request.Data(param,1))
}
set i = 1
set param = "MappingsPath"
set param = "NoFolders"
kill settings.Mappings
while ( $Get(%request.Data(param,i)) '= "" ){

while ( $Get(%request.Data("MappingsExt",i)) '= "" ){
if ($Get(%request.Data(param,i)) = "NoFolders"){
set settings.Mappings($Get(%request.Data("MappingsExt",i)), $Get(%request.Data("MappingsCov",i)), $Get(%request.Data(param,i))) = 1
set settings.Mappings($Get(%request.Data("MappingsExt",i)), $Get(%request.Data("MappingsCov",i)), $Get(%request.Data(param,i))) = $Get(%request.Data("MappingsPath",i))
}
else{
set settings.Mappings($Get(%request.Data("MappingsExt",i)), $Get(%request.Data("MappingsCov",i))) = $Get(%request.Data(param,i))
set settings.Mappings($Get(%request.Data("MappingsExt",i)), $Get(%request.Data("MappingsCov",i))) = $Get(%request.Data("MappingsPath",i))
}
set i = i+1
}
Expand All @@ -97,7 +98,7 @@ hr {
</div>
</div>
</div>
<br/>
<div class="col-md-10"><hr></div>
<h3>Settings for namespace #(..EscapeHTML(namespace))#</h3><br/>

<div class="form-group row mb-3">
Expand Down Expand Up @@ -180,22 +181,27 @@ hr {
if ($DATA(settings.Mappings(extKey, covKey)) = 1){
set checked = "checked"
set activated = " active"
set readOnly = ""
set readOnly = "readonly"
set mapPath = settings.Mappings(extKey, covKey)
set noFolders = """"""
set tooltipTitle = """Switch off to store files in a flat directory structure."""

} else {
set checked = ""
set activated = ""
set readOnly = "readonly"
set mapPath = "NoFolders"
set mapPath = settings.Mappings(extKey, covKey, "NoFolders")
set noFolders = """NoFolders"""
set tooltipTitle = """Switch on to store files in folders split by '.'s in the name."""
}

&html<<div class="voca col-sm-7">
<div class = "input-group mb-1">
<input type="text" class="form-control" id="MappingsExt" name="MappingsExt" value=#(extKey)# placeholder="Extension">
<input type="text" class="form-control" id="MappingsCov" name="MappingsCov" value=#(covKey)# placeholder="Coverage">
<input type="text" class="form-control" id="MappingsPath" name="MappingsPath" value=#(mapPath)# placeholder="Relative path" #(readOnly)#>
<div class="custom-control custom-switch" data-delay='{"show":"1000", "hide":"100"}' data-toggle="tooltip" data-placement="top" title="Switch off to store files in a flat directory structure.">
<input type="text" class="form-control" id="MappingsPath" name="MappingsPath" value=#(mapPath)# placeholder="Relative path">
<input type="text" class="form-control" id="NoFolders" name="NoFolders" value=#(noFolders)# placeholder="To folder, or not to folder, that is the question." #(readOnly)#>
<div class="custom-control custom-switch" data-delay='{"show":"1000", "hide":"100"}' data-toggle="tooltip" data-placement="top" title=#(tooltipTitle)#>
<input type="checkbox" class="#("custom-control-input"_activated)#" id=#("noFoldersSwitch"_idx)# #(checked)#>
<label class="custom-control-label" for=#("noFoldersSwitch"_idx)#>>

Expand Down Expand Up @@ -225,10 +231,7 @@ hr {
set idx = idx + 1
}
}
</script>
<!--<button type="button" class="btn-sm btn btn-success btn-add mx-auto d-block" >
<span class="glyphicon glyphicon-plus-sign" aria-hidden="true"></span>&nbsp&nbsp&nbspAdd&nbsp&nbsp&nbsp
</button>-->
</script>
</div>


Expand Down Expand Up @@ -270,12 +273,11 @@ hr {
<script src="js/bootstrap.min.js"></script>
<script type="text/javascript">

previous_path = new Array($(".voca").length);
$(function () {
$('[data-toggle="tooltip"]').tooltip({
trigger: 'hover'
});
})
});
$(function()
{
$(document).on('click', '.btn-add', function(e)
Expand All @@ -285,15 +287,20 @@ $(function()
var controlForm = $('.mapping-input-group');
$('<div class="col-sm-3" id="indent-div"> </div>').appendTo(controlForm);

var currentEntry = $(this).parent().siblings('.voca:first');
var newEntry = $(currentEntry.clone()).appendTo(controlForm);
var currentEntry = $(this).parent().siblings('.voca:last');
var newEntry = $(currentEntry.clone())

var currentID = newEntry.children().children(".custom-control").children()[0].id
var idx = parseInt(currentID.split("noFoldersSwitch")[1]);
var newID = "noFoldersSwitch"+(idx+1);

$(newEntry.children().children(".custom-control").children()[1]).attr("for", newID)
newEntry.children().children(".custom-control").children()[0].id = newID
newEntry.find('input').val('');
//controlForm.find('.btn-add:not(:last)')
//.removeClass('btn-default').addClass('btn-danger')
//.removeClass('btn-add').addClass('btn-remove')

//.html('<span class="glyphicon glyphicon-minus" aria-hidden="true"></span> Remove ');

newEntry.appendTo(controlForm);
$(("#"+newID)).click(toggleNoFolders);

}).on('click', '.btn-remove', function(e)
{
$(this).parent().parent().parent().prev('#indent-div').remove();
Expand All @@ -310,35 +317,30 @@ $(function()
})
});

$('[id^=noFoldersSwitch]').click(function(e) {

function toggleNoFolders(e){
$(this).siblings("label").empty()
var idx = parseInt($(this)[0].id.split("noFoldersSwitch")[1]);

if (!$(this).hasClass("active")) {
$(this).addClass("active");
$(this).siblings("label").append('<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="#007bff" class="bi bi-folder-fill" viewBox="0 0 16 16">'+
'<path d="M9.828 3h3.982a2 2 0 0 1 1.992 2.181l-.637 7A2 2 0 0 1 13.174 14H2.825a2 2 0 0 1-1.991-1.819l-.637-7a1.99 1.99 0 0 1 .342-1.31L.5 3a2 2 0 0 1 2-2h3.672a2 2 0 0 1 1.414.586l.828.828A2 2 0 0 0 9.828 3zm-8.322.12C1.72 3.042 1.95 3 2.19 3h5.396l-.707-.707A1 1 0 0 0 6.172 2H2.5a1 1 0 0 0-1 .981l.006.139z"/>'+
'</svg>');

if(!previous_path[idx-1]){
previous_path[idx-1] = "";
}
$(this).parent().siblings("#MappingsPath")[0].value = previous_path[idx-1];
$(this).parent().siblings("#MappingsPath")[0].readOnly = false;

$(this).parent().siblings("#NoFolders")[0].value = ""
$(this).parent().attr('data-original-title', 'Switch off to store files in a flat directory structure.');
} else {
$(this).removeClass("active");
$(this).siblings("label").append('<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="currentColor" class="bi bi-folder-x" viewBox="0 0 16 16">'+
'<path d="M.54 3.87.5 3a2 2 0 0 1 2-2h3.672a2 2 0 0 1 1.414.586l.828.828A2 2 0 0 0 9.828 3h3.982a2 2 0 0 1 1.992 2.181L15.546 8H14.54l.265-2.91A1 1 0 0 0 13.81 4H2.19a1 1 0 0 0-.996 1.09l.637 7a1 1 0 0 0 .995.91H9v1H2.826a2 2 0 0 1-1.991-1.819l-.637-7a1.99 1.99 0 0 1 .342-1.31zm6.339-1.577A1 1 0 0 0 6.172 2H2.5a1 1 0 0 0-1 .981l.006.139C1.72 3.042 1.95 3 2.19 3h5.396l-.707-.707z"/>'+
'<path d="M11.854 10.146a.5.5 0 0 0-.707.708L12.293 12l-1.146 1.146a.5.5 0 0 0 .707.708L13 12.707l1.146 1.147a.5.5 0 0 0 .708-.708L13.707 12l1.147-1.146a.5.5 0 0 0-.707-.708L13 11.293l-1.146-1.147z"/>'+
'</svg>');

previous_path[idx-1] = $(this).parent().siblings("#MappingsPath").val()
$(this).parent().siblings("#MappingsPath")[0].value = "NoFolders";
$(this).parent().siblings("#MappingsPath")[0].readOnly = true;
$(this).parent().siblings("#NoFolders")[0].value = "NoFolders";
$(this).parent().attr('data-original-title', "Switch on to store files in folders split by the '.' s in the name.");
}
});
}

$('[id^=noFoldersSwitch]').click(toggleNoFolders);

</script>
</body>
Expand Down
68 changes: 68 additions & 0 deletions test/UnitTest/SourceControl/Git/NameToInternalNameTest.cls
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
Import SourceControl.Git

Include SourceControl.Git

Class UnitTest.SourceControl.Git.NameToInternalNameTest Extends %UnitTest.TestCase
{

Property Mappings [ MultiDimensional ];

Method TestRegularClassNames()
{
// Regular class that exists
do $$$AssertEquals(##class(Utils).NameToInternalName("cls\SourceControl\Git\Utils.cls"),"SourceControl.Git.Utils.CLS")
// Regular class that doesn't exist and we ignore non-existent classes
do $$$AssertEquals(##class(Utils).NameToInternalName("cls\SourceControl\Git\DoesNotExist.cls"),"")
// Regular class that doesn't exist and we don't ignore non-existent classes
do $$$AssertEquals(##class(Utils).NameToInternalName("cls\SourceControl\Git\DoesNotExist.cls", 1, 0),"SourceControl.Git.DoesNotExist.CLS")
}

Method TestPercentClassNames()
{
// % class that exists but we ignore % classes
do $$$AssertEquals(##class(Utils).NameToInternalName("cls\%Studio\Extension\Base.cls"),"")
// % class that exists and we don't ignore % classes
do $$$AssertEquals(##class(Utils).NameToInternalName("cls\%Studio\Extension\Base.cls", 0),"%Studio.Extension.Base.CLS")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In all of these cases, we shouldn't have % in the folder name. (I believe this is illegal in Windows which is why we generally don't do it.) But it should still work.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right. I forgot about that. I'll change the tests.

// % class that doesn't exist and we ignore non-existent classes
do $$$AssertEquals(##class(Utils).NameToInternalName("cls\%Studio\Extension\DoesNotExist.cls", 0),"")
// % class that doesn't exist and we don't ignore non-existent classes
do $$$AssertEquals(##class(Utils).NameToInternalName("cls\%Studio\Extension\DoesNotExist.cls", 0, 0),"%Studio.Extension.DoesNotExist.CLS")
}

Method TestAbstractDocumentClassNames()
{
// %Studio.AbstractDocument type that exists
do $$$AssertEquals(##class(Utils).NameToInternalName("nspace\hl7\TestSchema.hl7"),"TestSchema.HL7")
// %Studio.AbstractDocument type that exists with '.' in the name
do $$$AssertEquals(##class(Utils).NameToInternalName("nspace\hl7\2.1.1.1.1.hl7"),"2.1.1.1.1.HL7")
// %Studio.AbstractDocument type that does not exist and we ignore non-existent classes
do $$$AssertEquals(##class(Utils).NameToInternalName("nspace\hl7\DoesNotExist.hl7"),"")
// %Studio.AbstractDocument type that doesn't exist and we don't ignore non-existent classes
do $$$AssertEquals(##class(Utils).NameToInternalName("nspace\hl7\DoesNotExist.hl7", 1, 0),"DoesNotExist.HL7")
}

Method TestStaticFileNames()
{
// Static file that shouldn't be on the server
do $$$AssertEquals(##class(Utils).NameToInternalName("git-webui\src\js\git-webui.js"),"")
// Static file that shouldn't be on the server but we don't ignore non-existent classes
do $$$AssertEquals(##class(Utils).NameToInternalName("git-webui\src\js\git-webui.js", 1, 0),"")
}

Method OnBeforeAllTests() As %Status
{
merge ..Mappings = @##class(SourceControl.Git.Utils).MappingsNode()
kill @##class(SourceControl.Git.Utils).MappingsNode()
set $$$SourceMapping("CLS", "*") = "cls/"
set $$$SourceMapping("HL7", "*", "NoFolders") = "nspace/hl7/"
quit $$$OK
}

Method %OnClose() As %Status
{
merge @##class(SourceControl.Git.Utils).MappingsNode() = ..Mappings
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should kill the mappings node as well (first). As it stands it'll leave the nspace/hl7/ in place.

quit $$$OK
}

}