diff --git a/extensions/sql-database-projects/src/models/project.ts b/extensions/sql-database-projects/src/models/project.ts
index d5d7be147b..b8843946d5 100644
--- a/extensions/sql-database-projects/src/models/project.ts
+++ b/extensions/sql-database-projects/src/models/project.ts
@@ -1052,9 +1052,8 @@ export class Project implements ISqlProject {
// again when they convert to an SDK-style project
if (this.isSdkStyleProject) {
// update sqlproj if a node was deleted and load files and folders again
- if (deleted) {
- await this.writeToSqlProjAndUpdateFilesFolders();
- }
+ await this.writeToSqlProjAndUpdateFilesFolders();
+
// get latest folders to see if it still exists
const currentFolders = await this.readFolders();
diff --git a/extensions/sql-database-projects/src/test/baselines/openSdkStyleSqlProjectWithFilesSpecifiedBaseline.xml b/extensions/sql-database-projects/src/test/baselines/openSdkStyleSqlProjectWithFilesSpecifiedBaseline.xml
index 8c6f83a0aa..d7eecc0273 100644
--- a/extensions/sql-database-projects/src/test/baselines/openSdkStyleSqlProjectWithFilesSpecifiedBaseline.xml
+++ b/extensions/sql-database-projects/src/test/baselines/openSdkStyleSqlProjectWithFilesSpecifiedBaseline.xml
@@ -35,7 +35,7 @@
-
+
diff --git a/extensions/sql-database-projects/src/test/project.test.ts b/extensions/sql-database-projects/src/test/project.test.ts
index 50310f8e7d..92de05b087 100644
--- a/extensions/sql-database-projects/src/test/project.test.ts
+++ b/extensions/sql-database-projects/src/test/project.test.ts
@@ -1253,6 +1253,97 @@ describe('Project: sdk style project content operations', function (): void {
should(project.files.find(f => f.relativePath === 'folder3\\')!).not.equal(undefined, 'folder3\\ should be loaded');
should(project.files.find(f => f.relativePath === 'folder3\\innerFolder\\')!).not.equal(undefined, 'folder3\\innerFolder\\ should be loaded');
});
+
+ it('Should handle deleting empty folders', async function (): Promise {
+ const testFolderPath = await testUtils.generateTestFolderPath();
+ projFilePath = await testUtils.createTestSqlProjFile(baselines.newSdkStyleProjectSdkNodeBaseline, testFolderPath);
+
+ const project: Project = await Project.openProject(projFilePath);
+ const beforeProjFileText = (await fs.readFile(projFilePath)).toString();
+
+ should(project.files.filter(f => f.type === EntryType.File).length).equal(0);
+ should(project.files.filter(f => f.type === EntryType.Folder).length).equal(0);
+
+ // add an empty folder
+ await project.addFolderItem('folder1');
+
+ // verify folder was added
+ should(project.files.filter(f => f.type === EntryType.Folder).length).equal(1);
+ should(project.files.filter(f => f.type === EntryType.File).length).equal(0);
+ should(project.files.find(f => f.relativePath === 'folder1\\')).not.equal(undefined, 'folder1 should have been added');
+
+ // verify entry was added for the new empty folder in the sqlproj
+ let projFileText = (await fs.readFile(projFilePath)).toString();
+ should(projFileText.includes('')).equal(true, projFileText);
+
+ // delete the empty folder
+ await project.deleteFileFolder(project.files.find(f => f.relativePath === 'folder1\\')!);
+
+ should(project.files.filter(f => f.type === EntryType.Folder).length).equal(0, 'folder1 should have been deleted');
+
+ // verify the folder entry was removed from the sqlproj and a Build Remove was not added
+ projFileText = (await fs.readFile(projFilePath)).toString();
+ should(projFileText.trimEnd() === beforeProjFileText.trimEnd()).equal(true, 'The sqlproj should not have changed after deleting folder1');
+ });
+
+ it('Should handle deleting not empty glob included folders', async function (): Promise {
+ const testFolderPath = await testUtils.generateTestFolderPath();
+ projFilePath = await testUtils.createTestSqlProjFile(baselines.openSdkStyleSqlProjectBaseline, testFolderPath);
+ await testUtils.createDummyFileStructureWithPrePostDeployScripts(false, undefined, path.dirname(projFilePath));
+
+ const project: Project = await Project.openProject(projFilePath);
+ const beforeProjFileText = (await fs.readFile(projFilePath)).toString();
+
+ should(project.files.filter(f => f.type === EntryType.File).length).equal(13);
+ should(project.files.filter(f => f.type === EntryType.Folder).length).equal(3);
+
+ // delete a folder with contents
+ await project.deleteFileFolder(project.files.find(f => f.relativePath === 'folder2\\')!);
+
+ should(project.files.filter(f => f.type === EntryType.File).length).equal(8);
+ should(project.files.filter(f => f.type === EntryType.Folder).length).equal(2);
+
+ // verify the folder entry was removed from the sqlproj and a Build Remove was not added
+ const projFileText = (await fs.readFile(projFilePath)).toString();
+ should(projFileText.trimEnd() === beforeProjFileText.trimEnd()).equal(true, 'The sqlproj should not have changed after deleting folder2');
+ });
+
+ it('Should handle deleting explicitly included folders', async function (): Promise {
+ const testFolderPath = await testUtils.generateTestFolderPath();
+ projFilePath = await testUtils.createTestSqlProjFile(baselines.openSdkStyleSqlProjectWithFilesSpecifiedBaseline, testFolderPath);
+ await testUtils.createDummyFileStructureWithPrePostDeployScripts(false, undefined, path.dirname(projFilePath));
+
+ const project: Project = await Project.openProject(projFilePath);
+
+ should(project.files.filter(f => f.type === EntryType.File).length).equal(13);
+ should(project.files.filter(f => f.type === EntryType.Folder).length).equal(3);
+ should(project.files.find(f => f.relativePath === 'folder1\\')!).not.equal(undefined);
+ should(project.files.find(f => f.relativePath === 'folder2\\')!).not.equal(undefined);
+
+ // try to delete an explicitly included folder with the trailing \ in sqlproj
+ await project.deleteFileFolder(project.files.find(f => f.relativePath === 'folder2\\')!);
+
+ // verify the project not longer has folder2 and its contents
+ should(project.files.filter(f => f.type === EntryType.Folder).length).equal(2);
+ should(project.files.filter(f => f.type === EntryType.File).length).equal(8);
+ should(project.files.find(f => f.relativePath === 'folder2\\')).equal(undefined);
+
+ // try to delete an explicitly included folder without trailing \ in sqlproj
+ await project.deleteFileFolder(project.files.find(f => f.relativePath === 'folder1\\')!);
+
+ // verify the project not longer has folder1 and its contents
+ should(project.files.filter(f => f.type === EntryType.Folder).length).equal(0);
+ should(project.files.filter(f => f.type === EntryType.File).length).equal(1);
+ should(project.files.find(f => f.relativePath === 'folder1\\')).equal(undefined);
+
+ // make sure both folders are removed from sqlproj and Build Remove entries were not added
+ const projFileText = (await fs.readFile(projFilePath)).toString();
+ should(projFileText.includes('')).equal(false, projFileText);
+ should(projFileText.includes('')).equal(false, projFileText);
+
+ should(projFileText.includes('')).equal(false, projFileText);
+ should(projFileText.includes('')).equal(false, projFileText);
+ });
});
describe('Project: add SQLCMD Variables', function (): void {