mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-01-15 09:35:37 -05:00
Round trip with SSDT (#10563)
* Initial changes * Round trip feature implementation * Addressed PR comments * Addressed comments
This commit is contained in:
@@ -8,7 +8,7 @@ import * as xmldom from 'xmldom';
|
||||
import * as constants from '../common/constants';
|
||||
import * as utils from '../common/utils';
|
||||
|
||||
import { Uri } from 'vscode';
|
||||
import { Uri, window } from 'vscode';
|
||||
import { promises as fs } from 'fs';
|
||||
import { DataSource } from './dataSources/dataSources';
|
||||
|
||||
@@ -20,6 +20,7 @@ export class Project {
|
||||
public projectFileName: string;
|
||||
public files: ProjectEntry[] = [];
|
||||
public dataSources: DataSource[] = [];
|
||||
public importedTargets: string[] = [];
|
||||
public sqlCmdVariables: Record<string, string> = {};
|
||||
|
||||
public get projectFolderPath() {
|
||||
@@ -41,7 +42,6 @@ export class Project {
|
||||
this.projFileXmlDoc = new xmldom.DOMParser().parseFromString(projFileText.toString());
|
||||
|
||||
// find all folders and files to include
|
||||
|
||||
for (let ig = 0; ig < this.projFileXmlDoc.documentElement.getElementsByTagName(constants.ItemGroup).length; ig++) {
|
||||
const itemGroup = this.projFileXmlDoc.documentElement.getElementsByTagName(constants.ItemGroup)[ig];
|
||||
|
||||
@@ -53,6 +53,45 @@ export class Project {
|
||||
this.files.push(this.createProjectEntry(itemGroup.getElementsByTagName(constants.Folder)[f].getAttribute(constants.Include), EntryType.Folder));
|
||||
}
|
||||
}
|
||||
|
||||
// find all import statements to include
|
||||
for (let i = 0; i < this.projFileXmlDoc.documentElement.getElementsByTagName(constants.Import).length; i++) {
|
||||
const importTarget = this.projFileXmlDoc.documentElement.getElementsByTagName(constants.Import)[i];
|
||||
this.importedTargets.push(importTarget.getAttribute(constants.Project));
|
||||
}
|
||||
}
|
||||
|
||||
public async updateProjectForRoundTrip() {
|
||||
if (this.importedTargets.includes(constants.NetCoreTargets)) {
|
||||
return;
|
||||
}
|
||||
|
||||
window.showWarningMessage(constants.updateProjectForRoundTrip, constants.yesString, constants.noString).then(async (result) => {
|
||||
if (result === constants.yesString) {
|
||||
await fs.copyFile(this.projectFilePath, this.projectFilePath + '_backup');
|
||||
await this.updateImportToSupportRoundTrip();
|
||||
await this.updatePackageReferenceInProjFile();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private async updateImportToSupportRoundTrip(): Promise<void> {
|
||||
// update an SSDT project to include Net core target information
|
||||
for (let i = 0; i < this.projFileXmlDoc.documentElement.getElementsByTagName(constants.Import).length; i++) {
|
||||
const importTarget = this.projFileXmlDoc.documentElement.getElementsByTagName(constants.Import)[i];
|
||||
|
||||
let condition = importTarget.getAttribute(constants.Condition);
|
||||
let project = importTarget.getAttribute(constants.Project);
|
||||
|
||||
if (condition === constants.SqlDbPresentCondition && project === constants.SqlDbTargets) {
|
||||
await this.updateImportedTargetsToProjFile(constants.RoundTripSqlDbPresentCondition, project, importTarget);
|
||||
}
|
||||
if (condition === constants.SqlDbNotPresentCondition && project === constants.MsBuildtargets) {
|
||||
await this.updateImportedTargetsToProjFile(constants.RoundTripSqlDbNotPresentCondition, project, importTarget);
|
||||
}
|
||||
}
|
||||
|
||||
await this.updateImportedTargetsToProjFile(constants.NetCoreCondition, constants.NetCoreTargets, undefined);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -109,14 +148,17 @@ export class Project {
|
||||
private findOrCreateItemGroup(containedTag?: string): any {
|
||||
let outputItemGroup = undefined;
|
||||
|
||||
// find any ItemGroup node that contains files; that's where we'll add
|
||||
for (let i = 0; i < this.projFileXmlDoc.documentElement.getElementsByTagName(constants.ItemGroup).length; i++) {
|
||||
const currentItemGroup = this.projFileXmlDoc.documentElement.getElementsByTagName(constants.ItemGroup)[i];
|
||||
// search for a particular item goup if a child type is provided
|
||||
if (containedTag) {
|
||||
// find any ItemGroup node that contains files; that's where we'll add
|
||||
for (let ig = 0; ig < this.projFileXmlDoc.documentElement.getElementsByTagName(constants.ItemGroup).length; ig++) {
|
||||
const currentItemGroup = this.projFileXmlDoc.documentElement.getElementsByTagName(constants.ItemGroup)[ig];
|
||||
|
||||
// if we're not hunting for a particular child type, or if we are and we find it, use the ItemGroup
|
||||
if (!containedTag || currentItemGroup.getElementsByTagName(containedTag).length > 0) {
|
||||
outputItemGroup = currentItemGroup;
|
||||
break;
|
||||
// if we find the tag, use the ItemGroup
|
||||
if (currentItemGroup.getElementsByTagName(containedTag).length > 0) {
|
||||
outputItemGroup = currentItemGroup;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -143,6 +185,34 @@ export class Project {
|
||||
this.findOrCreateItemGroup(constants.Folder).appendChild(newFolderNode);
|
||||
}
|
||||
|
||||
private async updateImportedTargetsToProjFile(condition: string, project: string, oldImportNode?: any): Promise<any> {
|
||||
const importNode = this.projFileXmlDoc.createElement(constants.Import);
|
||||
importNode.setAttribute(constants.Condition, condition);
|
||||
importNode.setAttribute(constants.Project, project);
|
||||
|
||||
if (oldImportNode) {
|
||||
this.projFileXmlDoc.documentElement.replaceChild(importNode, oldImportNode);
|
||||
}
|
||||
else {
|
||||
this.projFileXmlDoc.documentElement.appendChild(importNode, oldImportNode);
|
||||
}
|
||||
|
||||
await this.serializeToProjFile(this.projFileXmlDoc);
|
||||
return importNode;
|
||||
}
|
||||
|
||||
private async updatePackageReferenceInProjFile(): Promise<void> {
|
||||
const packageRefNode = this.projFileXmlDoc.createElement(constants.PackageReference);
|
||||
packageRefNode.setAttribute(constants.Condition, constants.NetCoreCondition);
|
||||
packageRefNode.setAttribute(constants.Include, constants.NETFrameworkAssembly);
|
||||
packageRefNode.setAttribute(constants.Version, constants.VersionNumber);
|
||||
packageRefNode.setAttribute(constants.PrivateAssets, constants.All);
|
||||
|
||||
this.findOrCreateItemGroup(constants.PackageReference).appendChild(packageRefNode);
|
||||
|
||||
await this.serializeToProjFile(this.projFileXmlDoc);
|
||||
}
|
||||
|
||||
private async addToProjFile(entry: ProjectEntry) {
|
||||
switch (entry.type) {
|
||||
case EntryType.File:
|
||||
|
||||
Reference in New Issue
Block a user