Adding move and exclude folder to SqlProjectService (#2027)

* Adding move and exclude folder

* Fixing cross-plat path bug in test
This commit is contained in:
Benjin Dubishar
2023-04-21 11:46:11 -07:00
committed by GitHub
parent a254020558
commit c5cdc4712a
7 changed files with 102 additions and 5 deletions

View File

@@ -23,7 +23,7 @@
<PackageReference Update="Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider" Version="1.1.1" /> <PackageReference Update="Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider" Version="1.1.1" />
<PackageReference Update="Microsoft.SqlServer.Management.SmoMetadataProvider" Version="170.12.0" /> <PackageReference Update="Microsoft.SqlServer.Management.SmoMetadataProvider" Version="170.12.0" />
<PackageReference Update="Microsoft.SqlServer.DacFx" Version="162.0.15-preview" /> <PackageReference Update="Microsoft.SqlServer.DacFx" Version="162.0.15-preview" />
<PackageReference Update="Microsoft.SqlServer.DacFx.Projects" Version="162.0.28-alpha" /> <PackageReference Update="Microsoft.SqlServer.DacFx.Projects" Version="162.0.32-alpha" />
<PackageReference Update="Microsoft.Azure.Kusto.Data" Version="9.0.4" /> <PackageReference Update="Microsoft.Azure.Kusto.Data" Version="9.0.4" />
<PackageReference Update="Microsoft.Azure.Kusto.Language" Version="9.0.4" /> <PackageReference Update="Microsoft.Azure.Kusto.Language" Version="9.0.4" />
<PackageReference Update="Microsoft.SqlServer.Assessment" Version="[1.1.17]" /> <PackageReference Update="Microsoft.SqlServer.Assessment" Version="[1.1.17]" />

View File

@@ -0,0 +1,18 @@
//
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
using Microsoft.SqlTools.Hosting.Protocol.Contracts;
using Microsoft.SqlTools.ServiceLayer.Utility;
namespace Microsoft.SqlTools.ServiceLayer.SqlProjects.Contracts
{
/// <summary>
/// Exclude a folder and its contents from a project
/// </summary>
public class ExcludeFolderRequest
{
public static readonly RequestType<FolderParams, ResultStatus> Type = RequestType<FolderParams, ResultStatus>.Create("sqlProjects/excludeFolder");
}
}

View File

@@ -0,0 +1,31 @@
//
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
#nullable disable
using Microsoft.SqlTools.Hosting.Protocol.Contracts;
using Microsoft.SqlTools.ServiceLayer.Utility;
namespace Microsoft.SqlTools.ServiceLayer.SqlProjects.Contracts
{
/// <summary>
/// Parameters for moving a folder
/// </summary>
public class MoveFolderParams : FolderParams
{
/// <summary>
/// Path of the folder, typically relative to the .sqlproj file
/// </summary>
public string DestinationPath { get; set; }
}
/// <summary>
/// Move a folder and its contents within a project
/// </summary>
public class MoveFolderRequest
{
public static readonly RequestType<MoveFolderParams, ResultStatus> Type = RequestType<MoveFolderParams, ResultStatus>.Create("sqlProjects/moveFolder");
}
}

View File

@@ -81,6 +81,8 @@ namespace Microsoft.SqlTools.ServiceLayer.SqlProjects
serviceHost.SetRequestHandler(GetFoldersRequest.Type, HandleGetFoldersRequest, isParallelProcessingSupported: true); serviceHost.SetRequestHandler(GetFoldersRequest.Type, HandleGetFoldersRequest, isParallelProcessingSupported: true);
serviceHost.SetRequestHandler(AddFolderRequest.Type, HandleAddFolderRequest, isParallelProcessingSupported: false); serviceHost.SetRequestHandler(AddFolderRequest.Type, HandleAddFolderRequest, isParallelProcessingSupported: false);
serviceHost.SetRequestHandler(DeleteFolderRequest.Type, HandleDeleteFolderRequest, isParallelProcessingSupported: false); serviceHost.SetRequestHandler(DeleteFolderRequest.Type, HandleDeleteFolderRequest, isParallelProcessingSupported: false);
serviceHost.SetRequestHandler(ExcludeFolderRequest.Type, HandleExcludeFolderRequest, isParallelProcessingSupported: false);
serviceHost.SetRequestHandler(MoveFolderRequest.Type, HandleMoveFolderRequest, isParallelProcessingSupported: false);
// SQLCMD variable functions // SQLCMD variable functions
serviceHost.SetRequestHandler(GetSqlCmdVariablesRequest.Type, HandleGetSqlCmdVariablesRequest, isParallelProcessingSupported: true); serviceHost.SetRequestHandler(GetSqlCmdVariablesRequest.Type, HandleGetSqlCmdVariablesRequest, isParallelProcessingSupported: true);
@@ -343,6 +345,16 @@ namespace Microsoft.SqlTools.ServiceLayer.SqlProjects
await RunWithErrorHandling(() => GetProject(requestParams.ProjectUri).Folders.Delete(requestParams.Path), requestContext); await RunWithErrorHandling(() => GetProject(requestParams.ProjectUri).Folders.Delete(requestParams.Path), requestContext);
} }
internal async Task HandleExcludeFolderRequest(FolderParams requestParams, RequestContext<ResultStatus> requestContext)
{
await RunWithErrorHandling(() => GetProject(requestParams.ProjectUri).Folders.Exclude(requestParams.Path), requestContext);
}
internal async Task HandleMoveFolderRequest(MoveFolderParams requestParams, RequestContext<ResultStatus> requestContext)
{
await RunWithErrorHandling(() => GetProject(requestParams.ProjectUri).Folders.Move(requestParams.Path, requestParams.DestinationPath), requestContext);
}
#endregion #endregion
#endregion #endregion

View File

@@ -372,7 +372,7 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.SqlProjects
} }
[Test] [Test]
public async Task TestPostDeploymentScriptAddDeleteExcludeMove() public async Task TestPostDeploymentScriptOperations()
{ {
// Setup // Setup
SqlProjectsService service = new(); SqlProjectsService service = new();
@@ -816,9 +816,9 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.SqlProjects
requestMock.AssertSuccess(nameof(service.HandleAddFolderRequest)); requestMock.AssertSuccess(nameof(service.HandleAddFolderRequest));
Assert.AreEqual(1, service.Projects[projectUri].Folders.Count, "Folder count after add"); Assert.AreEqual(1, service.Projects[projectUri].Folders.Count, "Folder count after add");
Assert.IsTrue(Directory.Exists(Path.Join(Path.GetDirectoryName(projectUri), folderParams.Path)), $"Subfolder '{folderParams.Path}' expected to exist on disk"); Assert.IsTrue(Directory.Exists(Path.Join(Path.GetDirectoryName(projectUri), folderParams.Path)), $"Subfolder '{folderParams.Path}' expected to exist on disk");
Assert.IsTrue(service.Projects[projectUri].Folders.Contains(folderParams.Path), $"SqlObjectScripts expected to contain {folderParams.Path}"); Assert.IsTrue(service.Projects[projectUri].Folders.Contains(folderParams.Path), $"Folders expected to contain {folderParams.Path}");
// Validate getting a list of the post-deployment scripts // Validate getting a list of the folders
MockRequest<GetFoldersResult> getMock = new(); MockRequest<GetFoldersResult> getMock = new();
await service.HandleGetFoldersRequest(new SqlProjectParams() await service.HandleGetFoldersRequest(new SqlProjectParams()
{ {
@@ -829,12 +829,48 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.SqlProjects
Assert.AreEqual(1, getMock.Result.Folders.Length); Assert.AreEqual(1, getMock.Result.Folders.Length);
Assert.AreEqual(folderParams.Path, getMock.Result.Folders[0]); Assert.AreEqual(folderParams.Path, getMock.Result.Folders[0]);
// Validate moving a folder
requestMock = new();
const string parentFolder = "NewParentFolder";
MoveFolderParams moveFolderParams = new MoveFolderParams()
{
ProjectUri = projectUri,
Path = folderParams.Path,
DestinationPath = $@"{parentFolder}\{folderParams.Path}"
};
await service.HandleMoveFolderRequest(moveFolderParams, requestMock.Object);
requestMock.AssertSuccess(nameof(service.HandleMoveFolderRequest));
Assert.AreEqual(2, service.Projects[projectUri].Folders.Count, "Folder count after move");
Assert.IsTrue(service.Projects[projectUri].Folders.Contains(parentFolder), $"Folders expected to contain '{parentFolder}' after move");
Assert.IsTrue(service.Projects[projectUri].Folders.Contains(moveFolderParams.DestinationPath), $"Folders expected to contain '{moveFolderParams.DestinationPath}' after move");
// Validate excluding a folder
requestMock = new();
await service.HandleExcludeFolderRequest(new FolderParams()
{
ProjectUri = projectUri,
Path = moveFolderParams.DestinationPath
}, requestMock.Object);
requestMock.AssertSuccess(nameof(service.HandleExcludeFolderRequest));
Assert.AreEqual(1, service.Projects[projectUri].Folders.Count, "Folder count after exclude");
Assert.IsTrue(service.Projects[projectUri].Folders.Contains(parentFolder), $"Folders expected to still contain '{parentFolder}' after exclude");
Assert.IsFalse(service.Projects[projectUri].Folders.Contains(moveFolderParams.DestinationPath), $"Folders expected to no longer contain '{moveFolderParams.DestinationPath}' after exclude");
Assert.IsTrue(Directory.Exists(Path.Join(service.Projects[projectUri].DirectoryPath, parentFolder, folderParams.Path)), "Folder should still exist on disk after exclude");
// Validate deleting a folder // Validate deleting a folder
requestMock = new(); requestMock = new();
await service.HandleDeleteFolderRequest(folderParams, requestMock.Object); await service.HandleDeleteFolderRequest(new FolderParams()
{
ProjectUri = projectUri,
Path = parentFolder
}, requestMock.Object);
requestMock.AssertSuccess(nameof(service.HandleDeleteFolderRequest)); requestMock.AssertSuccess(nameof(service.HandleDeleteFolderRequest));
Assert.AreEqual(0, service.Projects[projectUri].Folders.Count, "Folder count after delete"); Assert.AreEqual(0, service.Projects[projectUri].Folders.Count, "Folder count after delete");
Assert.IsFalse(Directory.Exists(Path.Join(service.Projects[projectUri].DirectoryPath, parentFolder)), "Folder should have been deleted from disk");
} }
[Test] [Test]