diff --git a/extensions/sql-database-projects/src/models/project.ts b/extensions/sql-database-projects/src/models/project.ts
index 9d11e151cb..d5d7be147b 100644
--- a/extensions/sql-database-projects/src/models/project.ts
+++ b/extensions/sql-database-projects/src/models/project.ts
@@ -122,13 +122,15 @@ export class Project implements ISqlProject {
// check if this is an sdk style project https://docs.microsoft.com/en-us/dotnet/core/project-sdk/overview
this._isSdkStyleProject = this.CheckForSdkStyleProject();
+ // get pre and post deploy scripts specified in the sqlproj
+ this._preDeployScripts = this.readPreDeployScripts();
+ this._postDeployScripts = this.readPostDeployScripts();
+ this._noneDeployScripts = this.readNoneDeployScripts();
+
// get files and folders
this._files = await this.readFilesInProject();
this.files.push(...await this.readFolders());
- this._preDeployScripts = this.readPreDeployScripts();
- this._postDeployScripts = this.readPostDeployScripts();
- this._noneDeployScripts = this.readNoneDeployScripts();
this._databaseReferences = this.readDatabaseReferences();
this._importedTargets = this.readImportedTargets();
@@ -225,6 +227,13 @@ export class Project implements ISqlProject {
}
}
+ if (this.isSdkStyleProject) {
+ // remove any pre/post/none deploy scripts that were specified in the sqlproj so they aren't counted twice
+ this.preDeployScripts.forEach(f => filesSet.delete(f.relativePath));
+ this.postDeployScripts.forEach(f => filesSet.delete(f.relativePath));
+ this.noneDeployScripts.forEach(f => filesSet.delete(f.relativePath));
+ }
+
// create a FileProjectEntry for each file
const fileEntries: FileProjectEntry[] = [];
filesSet.forEach(f => {
diff --git a/extensions/sql-database-projects/src/test/baselines/openSdkStyleSqlProjectWithGlobsSpecifiedBaseline.xml b/extensions/sql-database-projects/src/test/baselines/openSdkStyleSqlProjectWithGlobsSpecifiedBaseline.xml
index e93de1e8c3..88a388508a 100644
--- a/extensions/sql-database-projects/src/test/baselines/openSdkStyleSqlProjectWithGlobsSpecifiedBaseline.xml
+++ b/extensions/sql-database-projects/src/test/baselines/openSdkStyleSqlProjectWithGlobsSpecifiedBaseline.xml
@@ -20,6 +20,13 @@
+
+
+
+
+
+
+
False
diff --git a/extensions/sql-database-projects/src/test/project.test.ts b/extensions/sql-database-projects/src/test/project.test.ts
index 7e8f32d21f..50310f8e7d 100644
--- a/extensions/sql-database-projects/src/test/project.test.ts
+++ b/extensions/sql-database-projects/src/test/project.test.ts
@@ -844,7 +844,7 @@ describe('Project: sdk style project content operations', function (): void {
// Files and folders
should(project.files.filter(f => f.type === EntryType.Folder).length).equal(3);
- should(project.files.filter(f => f.type === EntryType.File).length).equal(17);
+ should(project.files.filter(f => f.type === EntryType.File).length).equal(13);
// SqlCmdVariables
should(Object.keys(project.sqlCmdVariables).length).equal(2);
@@ -883,6 +883,27 @@ describe('Project: sdk style project content operations', function (): void {
should(project.files.filter(f => f.relativePath === 'folder1\\').length).equal(1);
});
+ it('Should handle pre/post/none deploy scripts outside of project folder', async function (): Promise {
+ const testFolderPath = await testUtils.generateTestFolderPath();
+ const mainProjectPath = path.join(testFolderPath, 'project');
+ const otherFolderPath = path.join(testFolderPath, 'other');
+ projFilePath = await testUtils.createTestSqlProjFile(baselines.openSdkStyleSqlProjectWithGlobsSpecifiedBaseline, mainProjectPath);
+ await testUtils.createDummyFileStructure(false, undefined, path.dirname(projFilePath));
+
+ // create files outside of project folder that are included in the project file
+ await fs.mkdir(otherFolderPath);
+ await testUtils.createOtherDummyFiles(otherFolderPath);
+
+ const project: Project = await Project.openProject(projFilePath);
+
+ // verify files, folders, pre/post/none deploy scripts were loaded correctly
+ should(project.files.filter(f => f.type === EntryType.Folder).length).equal(2);
+ should(project.files.filter(f => f.type === EntryType.File).length).equal(18);
+ should(project.preDeployScripts.length).equal(1);
+ should(project.postDeployScripts.length).equal(1);
+ should(project.noneDeployScripts.length).equal(1);
+ });
+
it('Should handle globbing patterns listed in sqlproj', async function (): Promise {
const testFolderPath = await testUtils.generateTestFolderPath();
const mainProjectPath = path.join(testFolderPath, 'project');
@@ -1056,15 +1077,17 @@ describe('Project: sdk style project content operations', function (): void {
const project: Project = await Project.openProject(projFilePath);
- should(project.files.filter(f => f.type === EntryType.File).length).equal(17);
+ 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.noneDeployScripts.length).equal(2);
// try to exclude a glob included folder
await project.exclude(project.files.find(f => f.relativePath === 'folder1\\')!);
// verify folder and contents are excluded
should(project.files.filter(f => f.type === EntryType.Folder).length).equal(1);
- should(project.files.filter(f => f.type === EntryType.File).length).equal(9);
+ should(project.files.filter(f => f.type === EntryType.File).length).equal(6);
+ should(project.noneDeployScripts.length).equal(1, 'Script.PostDeployment2.sql should have been excluded');
should(project.files.find(f => f.relativePath === 'folder1\\')).equal(undefined);
// verify sqlproj has glob exclude for folder, but not for files and inner folder
@@ -1082,7 +1105,7 @@ describe('Project: sdk style project content operations', function (): void {
const project: Project = await Project.openProject(projFilePath);
- should(project.files.filter(f => f.type === EntryType.File).length).equal(17);
+ should(project.files.filter(f => f.type === EntryType.File).length).equal(13);
should(project.files.filter(f => f.type === EntryType.Folder).length).equal(3);
// try to exclude a glob included folder
@@ -1090,7 +1113,7 @@ describe('Project: sdk style project content operations', function (): void {
// verify folder and contents are excluded
should(project.files.filter(f => f.type === EntryType.Folder).length).equal(2);
- should(project.files.filter(f => f.type === EntryType.File).length).equal(15);
+ should(project.files.filter(f => f.type === EntryType.File).length).equal(11);
should(project.files.find(f => f.relativePath === 'folder1\\nestedFolder\\')).equal(undefined);
// verify sqlproj has glob exclude for folder, but not for files
diff --git a/extensions/sql-database-projects/src/test/testUtils.ts b/extensions/sql-database-projects/src/test/testUtils.ts
index e1242be5c0..a298a42b1a 100644
--- a/extensions/sql-database-projects/src/test/testUtils.ts
+++ b/extensions/sql-database-projects/src/test/testUtils.ts
@@ -198,6 +198,9 @@ export async function createListOfFiles(filePath?: string): Promise {
* - folder2
* -file1.sql
* -file2.sql
+ * - Script.PreDeployment1.sql
+ * - Script.PostDeployment1.sql
+ * - Script.PostDeployment2.sql
*
*/
export async function createOtherDummyFiles(testFolderPath: string): Promise {
@@ -221,5 +224,13 @@ export async function createOtherDummyFiles(testFolderPath: string): Promise