diff --git a/extensions/sql-database-projects/src/common/constants.ts b/extensions/sql-database-projects/src/common/constants.ts
index b596e825af..501ad8e649 100644
--- a/extensions/sql-database-projects/src/common/constants.ts
+++ b/extensions/sql-database-projects/src/common/constants.ts
@@ -4,6 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import * as nls from 'vscode-nls';
+import * as path from 'path';
import { SqlTargetPlatform } from 'sqldbproj';
import * as utils from '../common/utils';
@@ -455,6 +456,7 @@ export const Sdk: string = 'Sdk';
export const DatabaseSource = 'DatabaseSource';
export const VisualStudioVersion = 'VisualStudioVersion';
export const SSDTExists = 'SSDTExists';
+export const OutputPath = 'OutputPath';
export const BuildElements = localize('buildElements', "Build Elements");
export const FolderElements = localize('folderElements', "Folder Elements");
@@ -493,6 +495,8 @@ export const RoundTripSqlDbNotPresentCondition = '\'$(NetCoreBuild)\' != \'true\
export const DacpacRootPath = '$(DacPacRootPath)';
export const ProjJsonToClean = '$(BaseIntermediateOutputPath)\\project.assets.json';
+export function defaultOutputPath() { return path.join('bin', 'Debug'); }
+
// Sqlproj VS property conditions
export const VSVersionCondition = '\'$(VisualStudioVersion)\' == \'\'';
export const SsdtExistsCondition = '\'$(SSDTExists)\' == \'\'';
diff --git a/extensions/sql-database-projects/src/models/project.ts b/extensions/sql-database-projects/src/models/project.ts
index ce317aa992..26fc585481 100644
--- a/extensions/sql-database-projects/src/models/project.ts
+++ b/extensions/sql-database-projects/src/models/project.ts
@@ -36,9 +36,10 @@ export class Project implements ISqlProject {
private _postDeployScripts: FileProjectEntry[] = [];
private _noneDeployScripts: FileProjectEntry[] = [];
private _isSdkStyleProject: boolean = false; // https://docs.microsoft.com/en-us/dotnet/core/project-sdk/overview
+ private _outputPath: string = '';
public get dacpacOutputPath(): string {
- return path.join(this.projectFolderPath, 'bin', 'Debug', `${this._projectFileName}.dacpac`);
+ return path.join(this.outputPath, `${this._projectFileName}.dacpac`);
}
public get projectFolderPath() {
@@ -93,6 +94,10 @@ export class Project implements ISqlProject {
return this._isSdkStyleProject;
}
+ public get outputPath(): string {
+ return this._outputPath;
+ }
+
private projFileXmlDoc: Document | undefined = undefined;
constructor(projectFilePath: string) {
@@ -155,6 +160,16 @@ export class Project implements ISqlProject {
this.projFileXmlDoc!.documentElement.getElementsByTagName(constants.PropertyGroup)[0]?.appendChild(newProjectGuidNode);
await this.serializeToProjFile(this.projFileXmlDoc);
}
+
+ // get output path
+ const outputNodes = this.projFileXmlDoc!.documentElement.getElementsByTagName(constants.OutputPath);
+ if (outputNodes.length > 0) {
+ const outputPath = outputNodes[0].childNodes[0].nodeValue!;
+ this._outputPath = path.join(utils.getPlatformSafeFileEntryPath(this.projectFolderPath), utils.getPlatformSafeFileEntryPath(outputPath));
+ } else {
+ // If output path isn't specified in .sqlproj, set it to the default output path .\bin\Debug\
+ this._outputPath = path.join(utils.getPlatformSafeFileEntryPath(this.projectFolderPath), utils.getPlatformSafeFileEntryPath(constants.defaultOutputPath()));
+ }
}
/**
diff --git a/extensions/sql-database-projects/src/test/baselines/openSdkStyleSqlProjectBaseline.xml b/extensions/sql-database-projects/src/test/baselines/openSdkStyleSqlProjectBaseline.xml
index dbf2406a1a..a956694190 100644
--- a/extensions/sql-database-projects/src/test/baselines/openSdkStyleSqlProjectBaseline.xml
+++ b/extensions/sql-database-projects/src/test/baselines/openSdkStyleSqlProjectBaseline.xml
@@ -6,6 +6,7 @@
{2C283C5D-9E4A-4313-8FF9-4E0CEE20B063}
Microsoft.Data.Tools.Schema.Sql.Sql150DatabaseSchemaProvider
1033, CI
+ ..\otherFolder
diff --git a/extensions/sql-database-projects/src/test/project.test.ts b/extensions/sql-database-projects/src/test/project.test.ts
index 69d0650a78..db73657d62 100644
--- a/extensions/sql-database-projects/src/test/project.test.ts
+++ b/extensions/sql-database-projects/src/test/project.test.ts
@@ -13,7 +13,7 @@ import * as constants from '../common/constants';
import { promises as fs } from 'fs';
import { Project } from '../models/project';
-import { exists, convertSlashesForSqlProj, getWellKnownDatabaseSources } from '../common/utils';
+import { exists, convertSlashesForSqlProj, getWellKnownDatabaseSources, getPlatformSafeFileEntryPath } from '../common/utils';
import { Uri, window } from 'vscode';
import { IDacpacReferenceSettings, IProjectReferenceSettings, ISystemDatabaseReferenceSettings } from '../models/IDatabaseReferenceSettings';
import { EntryType, ItemType, SqlTargetPlatform } from 'sqldbproj';
@@ -1430,6 +1430,30 @@ describe('Project: sdk style project content operations', function (): void {
should(projFileText.includes(constants.ProjectGuid)).equal(true);
});
+ it('Should read OutputPath from sqlproj if there is one', async function (): Promise {
+ projFilePath = await testUtils.createTestSqlProjFile(baselines.openSdkStyleSqlProjectBaseline);
+ const projFileText = (await fs.readFile(projFilePath)).toString();
+
+ // Verify sqlproj has OutputPath
+ should(projFileText.includes(constants.OutputPath)).equal(true);
+
+ const project: Project = await Project.openProject(projFilePath);
+ should(project.outputPath).equal(path.join(getPlatformSafeFileEntryPath(project.projectFolderPath), getPlatformSafeFileEntryPath('..\\otherFolder')));
+ should(project.dacpacOutputPath).equal(path.join(getPlatformSafeFileEntryPath(project.projectFolderPath), getPlatformSafeFileEntryPath('..\\otherFolder'), `${project.projectFileName}.dacpac`));
+ });
+
+ it('Should use default output path if OutputPath is not specified in sqlproj', async function (): Promise {
+ projFilePath = await testUtils.createTestSqlProjFile(baselines.openSdkStyleSqlProjectWithGlobsSpecifiedBaseline);
+ const projFileText = (await fs.readFile(projFilePath)).toString();
+
+ // Verify sqlproj doesn't have OutputPath
+ should(projFileText.includes(constants.OutputPath)).equal(true);
+
+ const project: Project = await Project.openProject(projFilePath);
+ should(project.outputPath).equal(path.join(getPlatformSafeFileEntryPath(project.projectFolderPath), getPlatformSafeFileEntryPath(constants.defaultOutputPath())));
+ should(project.dacpacOutputPath).equal(path.join(getPlatformSafeFileEntryPath(project.projectFolderPath), getPlatformSafeFileEntryPath(constants.defaultOutputPath()), `${project.projectFileName}.dacpac`));
+ });
+
it('Should handle adding existing items to project', async function (): Promise {
projFilePath = await testUtils.createTestSqlProjFile(baselines.openSdkStyleSqlProjectBaseline);
const projectFolder = path.dirname(projFilePath);