mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-16 18:46:40 -05:00
Don't show update project warning for new style sqlproj (#17490)
* don't show SSDT update warning for new style projects * update strings * add checks for the 2 other ways to specify msbuild sdk * add link to docs on how to use project sdk Co-authored-by: Kim Santiago <kisantia@Kims-MacBook-Pro.local>
This commit is contained in:
@@ -21,6 +21,7 @@ export const msdb = 'msdb';
|
|||||||
export const msdbDacpac = 'msdb.dacpac';
|
export const msdbDacpac = 'msdb.dacpac';
|
||||||
export const MicrosoftDatatoolsSchemaSqlSql = 'Microsoft.Data.Tools.Schema.Sql.Sql';
|
export const MicrosoftDatatoolsSchemaSqlSql = 'Microsoft.Data.Tools.Schema.Sql.Sql';
|
||||||
export const databaseSchemaProvider = 'DatabaseSchemaProvider';
|
export const databaseSchemaProvider = 'DatabaseSchemaProvider';
|
||||||
|
export const sqlMsbuildSdk = 'Microsoft.Build.Sql';
|
||||||
|
|
||||||
// Project Provider
|
// Project Provider
|
||||||
export const emptySqlDatabaseProjectTypeId = 'EmptySqlDbProj';
|
export const emptySqlDatabaseProjectTypeId = 'EmptySqlDbProj';
|
||||||
@@ -360,6 +361,7 @@ export const Private = 'Private';
|
|||||||
export const ProjectGuid = 'ProjectGuid';
|
export const ProjectGuid = 'ProjectGuid';
|
||||||
export const Type = 'Type';
|
export const Type = 'Type';
|
||||||
export const ExternalStreamingJob: string = 'ExternalStreamingJob';
|
export const ExternalStreamingJob: string = 'ExternalStreamingJob';
|
||||||
|
export const Sdk: string = 'Sdk';
|
||||||
|
|
||||||
/** Name of the property item in the project file that defines default database collation. */
|
/** Name of the property item in the project file that defines default database collation. */
|
||||||
export const DefaultCollationProperty = 'DefaultCollation';
|
export const DefaultCollationProperty = 'DefaultCollation';
|
||||||
|
|||||||
@@ -1057,25 +1057,6 @@ export class ProjectsController {
|
|||||||
return new AddDatabaseReferenceDialog(project);
|
return new AddDatabaseReferenceDialog(project);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async updateProjectForRoundTrip(project: Project) {
|
|
||||||
if (project.importedTargets.includes(constants.NetCoreTargets) && !project.containsSSDTOnlySystemDatabaseReferences()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!project.importedTargets.includes(constants.NetCoreTargets)) {
|
|
||||||
const result = await vscode.window.showWarningMessage(constants.updateProjectForRoundTrip, constants.yesString, constants.noString);
|
|
||||||
if (result === constants.yesString) {
|
|
||||||
await project.updateProjectForRoundTrip();
|
|
||||||
await project.updateSystemDatabaseReferencesInProjFile();
|
|
||||||
}
|
|
||||||
} else if (project.containsSSDTOnlySystemDatabaseReferences()) {
|
|
||||||
const result = await vscode.window.showWarningMessage(constants.updateProjectDatabaseReferencesForRoundTrip, constants.yesString, constants.noString);
|
|
||||||
if (result === constants.yesString) {
|
|
||||||
await project.updateSystemDatabaseReferencesInProjFile();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private async addTemplateFiles(newProjFilePath: string, projectTypeId: string): Promise<void> {
|
private async addTemplateFiles(newProjFilePath: string, projectTypeId: string): Promise<void> {
|
||||||
if (projectTypeId === constants.emptySqlDatabaseProjectTypeId || newProjFilePath === '') {
|
if (projectTypeId === constants.emptySqlDatabaseProjectTypeId || newProjFilePath === '') {
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ export class Project implements ISqlProject {
|
|||||||
private _preDeployScripts: FileProjectEntry[] = [];
|
private _preDeployScripts: FileProjectEntry[] = [];
|
||||||
private _postDeployScripts: FileProjectEntry[] = [];
|
private _postDeployScripts: FileProjectEntry[] = [];
|
||||||
private _noneDeployScripts: FileProjectEntry[] = [];
|
private _noneDeployScripts: FileProjectEntry[] = [];
|
||||||
|
private _isMsbuildSdkStyleProject: boolean = false;
|
||||||
|
|
||||||
public get dacpacOutputPath(): string {
|
public get dacpacOutputPath(): string {
|
||||||
return path.join(this.projectFolderPath, 'bin', 'Debug', `${this._projectFileName}.dacpac`);
|
return path.join(this.projectFolderPath, 'bin', 'Debug', `${this._projectFileName}.dacpac`);
|
||||||
@@ -86,6 +87,10 @@ export class Project implements ISqlProject {
|
|||||||
return this._noneDeployScripts;
|
return this._noneDeployScripts;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public get isMsbuildSdkStyleProject(): boolean {
|
||||||
|
return this._isMsbuildSdkStyleProject;
|
||||||
|
}
|
||||||
|
|
||||||
private projFileXmlDoc: any = undefined;
|
private projFileXmlDoc: any = undefined;
|
||||||
|
|
||||||
constructor(projectFilePath: string) {
|
constructor(projectFilePath: string) {
|
||||||
@@ -113,6 +118,8 @@ export class Project implements ISqlProject {
|
|||||||
const projFileText = await fs.readFile(this._projectFilePath);
|
const projFileText = await fs.readFile(this._projectFilePath);
|
||||||
this.projFileXmlDoc = new xmldom.DOMParser().parseFromString(projFileText.toString());
|
this.projFileXmlDoc = new xmldom.DOMParser().parseFromString(projFileText.toString());
|
||||||
|
|
||||||
|
// check if this is a new msbuild sdk style project
|
||||||
|
this._isMsbuildSdkStyleProject = this.CheckForMsbuildSdkStyleProject();
|
||||||
// get projectGUID
|
// get projectGUID
|
||||||
this._projectGuid = this.projFileXmlDoc.documentElement.getElementsByTagName(constants.ProjectGuid)[0].childNodes[0].nodeValue;
|
this._projectGuid = this.projFileXmlDoc.documentElement.getElementsByTagName(constants.ProjectGuid)[0].childNodes[0].nodeValue;
|
||||||
|
|
||||||
@@ -236,8 +243,38 @@ export class Project implements ISqlProject {
|
|||||||
this.projFileXmlDoc = undefined;
|
this.projFileXmlDoc = undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks for the 3 possible ways a project can reference the sql msbuild sdk
|
||||||
|
* https://docs.microsoft.com/en-us/visualstudio/msbuild/how-to-use-project-sdk?view=vs-2019
|
||||||
|
* @returns true if the project is an msbuild sdk style project, false if it isn't
|
||||||
|
*/
|
||||||
|
public CheckForMsbuildSdkStyleProject(): boolean {
|
||||||
|
// type 1: Sdk node like <Sdk Name="Microsoft.Build.Sql" Version="1.0.0" />
|
||||||
|
const sdkNodes = this.projFileXmlDoc.documentElement.getElementsByTagName(constants.Sdk);
|
||||||
|
if (sdkNodes.length > 0) {
|
||||||
|
return sdkNodes[0].getAttribute(constants.Name) === constants.sqlMsbuildSdk;
|
||||||
|
}
|
||||||
|
|
||||||
|
// type 2: Project node has Sdk attribute like <Project Sdk="Microsoft.Build.Sql/1.0.0">
|
||||||
|
const sdkAttribute: string = this.projFileXmlDoc.documentElement.getAttribute(constants.Sdk);
|
||||||
|
if (sdkAttribute) {
|
||||||
|
return sdkAttribute.includes(constants.sqlMsbuildSdk);
|
||||||
|
}
|
||||||
|
|
||||||
|
// type 3: Import node with Sdk attribute like <Import Project="Sdk.targets" Sdk="Microsoft.Build.Sql" Version="1.0.0" />
|
||||||
|
const importNodes = this.projFileXmlDoc.documentElement.getElementsByTagName(constants.Import);
|
||||||
|
for (let i = 0; i < importNodes.length; i++) {
|
||||||
|
if (importNodes[i].getAttribute(constants.Sdk) === constants.sqlMsbuildSdk) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public async updateProjectForRoundTrip(): Promise<void> {
|
public async updateProjectForRoundTrip(): Promise<void> {
|
||||||
if (this._importedTargets.includes(constants.NetCoreTargets) && !this.containsSSDTOnlySystemDatabaseReferences()) {
|
if (this._importedTargets.includes(constants.NetCoreTargets) && !this.containsSSDTOnlySystemDatabaseReferences() // old style project check
|
||||||
|
|| this.isMsbuildSdkStyleProject) { // new style project check
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -26,6 +26,9 @@ export let sqlProjectMissingVersionBaseline: string;
|
|||||||
export let sqlProjectInvalidVersionBaseline: string;
|
export let sqlProjectInvalidVersionBaseline: string;
|
||||||
export let sqlProjectCustomCollationBaseline: string;
|
export let sqlProjectCustomCollationBaseline: string;
|
||||||
export let sqlProjectInvalidCollationBaseline: string;
|
export let sqlProjectInvalidCollationBaseline: string;
|
||||||
|
export let newStyleProjectSdkNodeBaseline: string;
|
||||||
|
export let newStyleProjectSdkProjectAttributeBaseline: string;
|
||||||
|
export let newStyleProjectSdkImportAttributeBaseline: string;
|
||||||
|
|
||||||
const baselineFolderPath = __dirname;
|
const baselineFolderPath = __dirname;
|
||||||
|
|
||||||
@@ -49,6 +52,9 @@ export async function loadBaselines() {
|
|||||||
sqlProjectInvalidVersionBaseline = await loadBaseline(baselineFolderPath, 'sqlProjectInvalidVersionBaseline.xml');
|
sqlProjectInvalidVersionBaseline = await loadBaseline(baselineFolderPath, 'sqlProjectInvalidVersionBaseline.xml');
|
||||||
sqlProjectCustomCollationBaseline = await loadBaseline(baselineFolderPath, 'sqlProjectCustomCollationBaseline.xml');
|
sqlProjectCustomCollationBaseline = await loadBaseline(baselineFolderPath, 'sqlProjectCustomCollationBaseline.xml');
|
||||||
sqlProjectInvalidCollationBaseline = await loadBaseline(baselineFolderPath, 'sqlProjectInvalidCollationBaseline.xml');
|
sqlProjectInvalidCollationBaseline = await loadBaseline(baselineFolderPath, 'sqlProjectInvalidCollationBaseline.xml');
|
||||||
|
newStyleProjectSdkNodeBaseline = await loadBaseline(baselineFolderPath, 'newStyleSqlProjectSdkNodeBaseline.xml');
|
||||||
|
newStyleProjectSdkProjectAttributeBaseline = await loadBaseline(baselineFolderPath, 'newStyleSqlProjectSdkProjectAttributeBaseline.xml');
|
||||||
|
newStyleProjectSdkImportAttributeBaseline = await loadBaseline(baselineFolderPath, 'newStyleSqlProjectSdkImportAttributeBaseline.xml');
|
||||||
}
|
}
|
||||||
|
|
||||||
async function loadBaseline(baselineFolderPath: string, fileName: string): Promise<string> {
|
async function loadBaseline(baselineFolderPath: string, fileName: string): Promise<string> {
|
||||||
|
|||||||
@@ -0,0 +1,14 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project DefaultTargets="Build">
|
||||||
|
<PropertyGroup>
|
||||||
|
<Name>TestProjectName</Name>
|
||||||
|
<ProjectGuid>{2C283C5D-9E4A-4313-8FF9-4E0CEE20B063}</ProjectGuid>
|
||||||
|
<DSP>Microsoft.Data.Tools.Schema.Sql.Sql150DatabaseSchemaProvider</DSP>
|
||||||
|
<ModelCollation>1033, CI</ModelCollation>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Target Name="BeforeBuild">
|
||||||
|
<Delete Files="$(BaseIntermediateOutputPath)\project.assets.json" />
|
||||||
|
</Target>
|
||||||
|
<Import Project="Sdk.props" Sdk="Microsoft.Build.Sql" Version="1.0.0" />
|
||||||
|
<Import Project="Sdk.targets" Sdk="Microsoft.Build.Sql" Version="1.0.0" />
|
||||||
|
</Project>
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project DefaultTargets="Build">
|
||||||
|
<Sdk Name="Microsoft.Build.Sql" Version="1.0.0" />
|
||||||
|
<PropertyGroup>
|
||||||
|
<Name>TestProjectName</Name>
|
||||||
|
<ProjectGuid>{2C283C5D-9E4A-4313-8FF9-4E0CEE20B063}</ProjectGuid>
|
||||||
|
<DSP>Microsoft.Data.Tools.Schema.Sql.Sql150DatabaseSchemaProvider</DSP>
|
||||||
|
<ModelCollation>1033, CI</ModelCollation>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Target Name="BeforeBuild">
|
||||||
|
<Delete Files="$(BaseIntermediateOutputPath)\project.assets.json" />
|
||||||
|
</Target>
|
||||||
|
</Project>
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project DefaultTargets="Build" Sdk="Microsoft.Build.Sql/1.0.0">
|
||||||
|
<PropertyGroup>
|
||||||
|
<Name>TestProjectName</Name>
|
||||||
|
<ProjectGuid>{2C283C5D-9E4A-4313-8FF9-4E0CEE20B063}</ProjectGuid>
|
||||||
|
<DSP>Microsoft.Data.Tools.Schema.Sql.Sql150DatabaseSchemaProvider</DSP>
|
||||||
|
<ModelCollation>1033, CI</ModelCollation>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Target Name="BeforeBuild">
|
||||||
|
<Delete Files="$(BaseIntermediateOutputPath)\project.assets.json" />
|
||||||
|
</Target>
|
||||||
|
</Project>
|
||||||
@@ -906,6 +906,10 @@ describe('Project: round trip updates', function (): void {
|
|||||||
await baselines.loadBaselines();
|
await baselines.loadBaselines();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
beforeEach(function (): void {
|
||||||
|
sinon.restore();
|
||||||
|
});
|
||||||
|
|
||||||
it('Should update SSDT project to work in ADS', async function (): Promise<void> {
|
it('Should update SSDT project to work in ADS', async function (): Promise<void> {
|
||||||
await testUpdateInRoundTrip(baselines.SSDTProjectFileBaseline, baselines.SSDTProjectAfterUpdateBaseline);
|
await testUpdateInRoundTrip(baselines.SSDTProjectFileBaseline, baselines.SSDTProjectAfterUpdateBaseline);
|
||||||
});
|
});
|
||||||
@@ -943,6 +947,29 @@ describe('Project: round trip updates', function (): void {
|
|||||||
|
|
||||||
should(project.importedTargets.length).equal(3); // additional target should exist by default
|
should(project.importedTargets.length).equal(3); // additional target should exist by default
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('Should not show update project warning message when opening msbuild sdk style project using Sdk node', async function (): Promise<void> {
|
||||||
|
await shouldNotShowUpdateWarning(baselines.newStyleProjectSdkNodeBaseline);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Should not show update project warning message when opening msbuild sdk style project using Project node with Sdk attribute', async function (): Promise<void> {
|
||||||
|
await shouldNotShowUpdateWarning(baselines.newStyleProjectSdkProjectAttributeBaseline);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Should not show update project warning message when opening msbuild sdk style project using Import node with Sdk attribute', async function (): Promise<void> {
|
||||||
|
await shouldNotShowUpdateWarning(baselines.newStyleProjectSdkImportAttributeBaseline);
|
||||||
|
});
|
||||||
|
|
||||||
|
async function shouldNotShowUpdateWarning(baselineFile: string): Promise<void> {
|
||||||
|
// setup test files
|
||||||
|
const folderPath = await testUtils.generateTestFolderPath();
|
||||||
|
const sqlProjPath = await testUtils.createTestSqlProjFile(baselineFile, folderPath);
|
||||||
|
const spy = sinon.spy(window, 'showWarningMessage');
|
||||||
|
|
||||||
|
const project = await Project.openProject(Uri.file(sqlProjPath).fsPath);
|
||||||
|
should(spy.notCalled).be.true();
|
||||||
|
should(project.isMsbuildSdkStyleProject).be.true();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
async function testUpdateInRoundTrip(fileBeforeupdate: string, fileAfterUpdate: string): Promise<void> {
|
async function testUpdateInRoundTrip(fileBeforeupdate: string, fileAfterUpdate: string): Promise<void> {
|
||||||
@@ -960,5 +987,3 @@ async function testUpdateInRoundTrip(fileBeforeupdate: string, fileAfterUpdate:
|
|||||||
should(stub.calledOnce).be.true('showWarningMessage should have been called exactly once');
|
should(stub.calledOnce).be.true('showWarningMessage should have been called exactly once');
|
||||||
sinon.restore();
|
sinon.restore();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user