mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-17 02:51:36 -05:00
Changes to add pre/post deploy script to sqlproj (#11864)
* Initial changes for adding pre/post deploy script in project * Right click > Add pre/post deploy script * Print script files in tree * Add new pre-post deploy items with their own tags and additional ones with None * Add tests * Fix error due to merge conflicts * Addressed comments and fixed tests. * Fix code scan error * Addressed comments
This commit is contained in:
@@ -69,6 +69,16 @@
|
|||||||
"title": "%sqlDatabaseProjects.newScript%",
|
"title": "%sqlDatabaseProjects.newScript%",
|
||||||
"category": "%sqlDatabaseProjects.displayName%"
|
"category": "%sqlDatabaseProjects.displayName%"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"command": "sqlDatabaseProjects.newPreDeploymentScript",
|
||||||
|
"title": "%sqlDatabaseProjects.newPreDeploymentScript%",
|
||||||
|
"category": "%sqlDatabaseProjects.displayName%"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "sqlDatabaseProjects.newPostDeploymentScript",
|
||||||
|
"title": "%sqlDatabaseProjects.newPostDeploymentScript%",
|
||||||
|
"category": "%sqlDatabaseProjects.displayName%"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"command": "sqlDatabaseProjects.newTable",
|
"command": "sqlDatabaseProjects.newTable",
|
||||||
"title": "%sqlDatabaseProjects.newTable%",
|
"title": "%sqlDatabaseProjects.newTable%",
|
||||||
@@ -157,6 +167,14 @@
|
|||||||
"command": "sqlDatabaseProjects.newScript",
|
"command": "sqlDatabaseProjects.newScript",
|
||||||
"when": "false"
|
"when": "false"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"command": "sqlDatabaseProjects.newPreDeploymentScript",
|
||||||
|
"when": "false"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "sqlDatabaseProjects.newPostDeploymentScript",
|
||||||
|
"when": "false"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"command": "sqlDatabaseProjects.newTable",
|
"command": "sqlDatabaseProjects.newTable",
|
||||||
"when": "false"
|
"when": "false"
|
||||||
@@ -253,6 +271,16 @@
|
|||||||
{
|
{
|
||||||
"command": "sqlDatabaseProjects.newScript",
|
"command": "sqlDatabaseProjects.newScript",
|
||||||
"when": "view == sqlDatabaseProjectsView && viewItem == databaseProject.itemType.project || viewItem == databaseProject.itemType.folder",
|
"when": "view == sqlDatabaseProjectsView && viewItem == databaseProject.itemType.project || viewItem == databaseProject.itemType.folder",
|
||||||
|
"group": "3_dbProjects_newItem@7"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "sqlDatabaseProjects.newPreDeploymentScript",
|
||||||
|
"when": "view == sqlDatabaseProjectsView && viewItem == databaseProject.itemType.project || viewItem == databaseProject.itemType.folder",
|
||||||
|
"group": "3_dbProjects_newItem@8"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"command": "sqlDatabaseProjects.newPostDeploymentScript",
|
||||||
|
"when": "view == sqlDatabaseProjectsView && viewItem == databaseProject.itemType.project || viewItem == databaseProject.itemType.folder",
|
||||||
"group": "3_dbProjects_newItem@9"
|
"group": "3_dbProjects_newItem@9"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -15,6 +15,8 @@
|
|||||||
"sqlDatabaseProjects.exclude": "Exclude from project",
|
"sqlDatabaseProjects.exclude": "Exclude from project",
|
||||||
|
|
||||||
"sqlDatabaseProjects.newScript": "Add Script",
|
"sqlDatabaseProjects.newScript": "Add Script",
|
||||||
|
"sqlDatabaseProjects.newPreDeploymentScript": "Add Pre-Deployment Script",
|
||||||
|
"sqlDatabaseProjects.newPostDeploymentScript": "Add Post-Deployment Script",
|
||||||
"sqlDatabaseProjects.newTable": "Add Table",
|
"sqlDatabaseProjects.newTable": "Add Table",
|
||||||
"sqlDatabaseProjects.newView": "Add View",
|
"sqlDatabaseProjects.newView": "Add View",
|
||||||
"sqlDatabaseProjects.newStoredProcedure": "Add Stored Procedure",
|
"sqlDatabaseProjects.newStoredProcedure": "Add Stored Procedure",
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
-- This file contains SQL statements that will be executed after the build script.
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
-- This file contains SQL statements that will be executed before the build script.
|
||||||
@@ -127,12 +127,12 @@ export function folderAlreadyExists(filename: string) { return localize('folderA
|
|||||||
export function invalidInput(input: string) { return localize('invalidInput', "Invalid input: {0}", input); }
|
export function invalidInput(input: string) { return localize('invalidInput', "Invalid input: {0}", input); }
|
||||||
export function unableToCreatePublishConnection(input: string) { return localize('unableToCreatePublishConnection', "Unable to construct connection: {0}", input); }
|
export function unableToCreatePublishConnection(input: string) { return localize('unableToCreatePublishConnection', "Unable to construct connection: {0}", input); }
|
||||||
export function circularProjectReference(project1: string, project2: string) { return localize('cicularProjectReference', "Circular reference from project {0} to project {1}", project1, project2); }
|
export function circularProjectReference(project1: string, project2: string) { return localize('cicularProjectReference', "Circular reference from project {0} to project {1}", project1, project2); }
|
||||||
|
|
||||||
export function mssqlNotFound(mssqlConfigDir: string) { return localize('mssqlNotFound', "Could not get mssql extension's install location at {0}", mssqlConfigDir); }
|
export function mssqlNotFound(mssqlConfigDir: string) { return localize('mssqlNotFound', "Could not get mssql extension's install location at {0}", mssqlConfigDir); }
|
||||||
export function projBuildFailed(errorMessage: string) { return localize('projBuildFailed', "Build failed. Check output pane for more details. {0}", errorMessage); }
|
export function projBuildFailed(errorMessage: string) { return localize('projBuildFailed', "Build failed. Check output pane for more details. {0}", errorMessage); }
|
||||||
export function unexpectedProjectContext(uri: string) { return localize('unexpectedProjectContext', "Unable to establish project context. Command invoked from unexpected location: {0}", uri); }
|
export function unexpectedProjectContext(uri: string) { return localize('unexpectedProjectContext', "Unable to establish project context. Command invoked from unexpected location: {0}", uri); }
|
||||||
export function unableToPerformAction(action: string, uri: string) { return localize('unableToPerformAction', "Unable to locate '{0}' target: '{1}'", action, uri); }
|
export function unableToPerformAction(action: string, uri: string) { return localize('unableToPerformAction', "Unable to locate '{0}' target: '{1}'", action, uri); }
|
||||||
export function unableToFindObject(path: string, objType: string) { return localize('unableToFindFile', "Unable to find {1} with path '{0}'", path, objType); }
|
export function unableToFindObject(path: string, objType: string) { return localize('unableToFindFile', "Unable to find {1} with path '{0}'", path, objType); }
|
||||||
|
export function deployScriptExists(scriptType: string) { return localize('deployScriptExists', "A {0} script already exists. The new script will not be included in build.", scriptType); }
|
||||||
|
|
||||||
// Action types
|
// Action types
|
||||||
export const deleteAction = localize('deleteAction', 'Delete');
|
export const deleteAction = localize('deleteAction', 'Delete');
|
||||||
@@ -149,6 +149,8 @@ export const scriptFriendlyName = localize('scriptFriendlyName', "Script");
|
|||||||
export const tableFriendlyName = localize('tableFriendlyName', "Table");
|
export const tableFriendlyName = localize('tableFriendlyName', "Table");
|
||||||
export const viewFriendlyName = localize('viewFriendlyName', "View");
|
export const viewFriendlyName = localize('viewFriendlyName', "View");
|
||||||
export const storedProcedureFriendlyName = localize('storedProcedureFriendlyName', "Stored Procedure");
|
export const storedProcedureFriendlyName = localize('storedProcedureFriendlyName', "Stored Procedure");
|
||||||
|
export const preDeployScriptFriendlyName = localize('preDeployScriptFriendlyName', "Script.PreDeployment");
|
||||||
|
export const postDeployScriptFriendlyName = localize('postDeployScriptFriendlyName', "Script.PostDeployment");
|
||||||
|
|
||||||
// SqlProj file XML names
|
// SqlProj file XML names
|
||||||
export const ItemGroup = 'ItemGroup';
|
export const ItemGroup = 'ItemGroup';
|
||||||
|
|||||||
@@ -63,6 +63,8 @@ export default class MainController implements vscode.Disposable {
|
|||||||
vscode.commands.registerCommand('sqlDatabaseProjects.importDatabase', async (profile: azdata.IConnectionProfile) => { await this.projectsController.importNewDatabaseProject(profile); });
|
vscode.commands.registerCommand('sqlDatabaseProjects.importDatabase', async (profile: azdata.IConnectionProfile) => { await this.projectsController.importNewDatabaseProject(profile); });
|
||||||
|
|
||||||
vscode.commands.registerCommand('sqlDatabaseProjects.newScript', async (node: BaseProjectTreeItem) => { await this.projectsController.addItemPromptFromNode(node, templates.script); });
|
vscode.commands.registerCommand('sqlDatabaseProjects.newScript', async (node: BaseProjectTreeItem) => { await this.projectsController.addItemPromptFromNode(node, templates.script); });
|
||||||
|
vscode.commands.registerCommand('sqlDatabaseProjects.newPreDeploymentScript', async (node: BaseProjectTreeItem) => { await this.projectsController.addItemPromptFromNode(node, templates.preDeployScript); });
|
||||||
|
vscode.commands.registerCommand('sqlDatabaseProjects.newPostDeploymentScript', async (node: BaseProjectTreeItem) => { await this.projectsController.addItemPromptFromNode(node, templates.postDeployScript); });
|
||||||
vscode.commands.registerCommand('sqlDatabaseProjects.newTable', async (node: BaseProjectTreeItem) => { await this.projectsController.addItemPromptFromNode(node, templates.table); });
|
vscode.commands.registerCommand('sqlDatabaseProjects.newTable', async (node: BaseProjectTreeItem) => { await this.projectsController.addItemPromptFromNode(node, templates.table); });
|
||||||
vscode.commands.registerCommand('sqlDatabaseProjects.newView', async (node: BaseProjectTreeItem) => { await this.projectsController.addItemPromptFromNode(node, templates.view); });
|
vscode.commands.registerCommand('sqlDatabaseProjects.newView', async (node: BaseProjectTreeItem) => { await this.projectsController.addItemPromptFromNode(node, templates.view); });
|
||||||
vscode.commands.registerCommand('sqlDatabaseProjects.newStoredProcedure', async (node: BaseProjectTreeItem) => { await this.projectsController.addItemPromptFromNode(node, templates.storedProcedure); });
|
vscode.commands.registerCommand('sqlDatabaseProjects.newStoredProcedure', async (node: BaseProjectTreeItem) => { await this.projectsController.addItemPromptFromNode(node, templates.storedProcedure); });
|
||||||
|
|||||||
@@ -353,7 +353,7 @@ export class ProjectsController {
|
|||||||
throw new Error(constants.fileAlreadyExists(path.parse(absoluteFilePath).name));
|
throw new Error(constants.fileAlreadyExists(path.parse(absoluteFilePath).name));
|
||||||
}
|
}
|
||||||
|
|
||||||
const newEntry = await project.addScriptItem(relativeFilePath, newFileText);
|
const newEntry = await project.addScriptItem(relativeFilePath, newFileText, itemType.type);
|
||||||
|
|
||||||
await vscode.commands.executeCommand(constants.vscodeOpenCommand, newEntry.fsUri);
|
await vscode.commands.executeCommand(constants.vscodeOpenCommand, newEntry.fsUri);
|
||||||
|
|
||||||
@@ -630,7 +630,7 @@ export class ProjectsController {
|
|||||||
|
|
||||||
private async promptForNewObjectName(itemType: templates.ProjectScriptType, _project: Project): Promise<string | undefined> {
|
private async promptForNewObjectName(itemType: templates.ProjectScriptType, _project: Project): Promise<string | undefined> {
|
||||||
// TODO: ask project for suggested name that doesn't conflict
|
// TODO: ask project for suggested name that doesn't conflict
|
||||||
const suggestedName = itemType.friendlyName.replace(new RegExp('\s', 'g'), '') + '1';
|
const suggestedName = itemType.friendlyName.replace(/\s+/g, '') + '1';
|
||||||
|
|
||||||
const itemObjectName = await vscode.window.showInputBox({
|
const itemObjectName = await vscode.window.showInputBox({
|
||||||
prompt: constants.newObjectNamePrompt(itemType.friendlyName),
|
prompt: constants.newObjectNamePrompt(itemType.friendlyName),
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import * as constants from '../common/constants';
|
|||||||
import * as utils from '../common/utils';
|
import * as utils from '../common/utils';
|
||||||
import * as xmlFormat from 'xml-formatter';
|
import * as xmlFormat from 'xml-formatter';
|
||||||
import * as os from 'os';
|
import * as os from 'os';
|
||||||
|
import * as templates from '../templates/templates';
|
||||||
|
|
||||||
import { Uri, window } from 'vscode';
|
import { Uri, window } from 'vscode';
|
||||||
import { promises as fs } from 'fs';
|
import { promises as fs } from 'fs';
|
||||||
@@ -215,7 +216,7 @@ export class Project {
|
|||||||
* @param relativeFilePath Relative path of the file
|
* @param relativeFilePath Relative path of the file
|
||||||
* @param contents Contents to be written to the new file
|
* @param contents Contents to be written to the new file
|
||||||
*/
|
*/
|
||||||
public async addScriptItem(relativeFilePath: string, contents?: string): Promise<ProjectEntry> {
|
public async addScriptItem(relativeFilePath: string, contents?: string, itemType?: string): Promise<ProjectEntry> {
|
||||||
const absoluteFilePath = path.join(this.projectFolderPath, relativeFilePath);
|
const absoluteFilePath = path.join(this.projectFolderPath, relativeFilePath);
|
||||||
|
|
||||||
if (contents) {
|
if (contents) {
|
||||||
@@ -230,9 +231,23 @@ export class Project {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const fileEntry = this.createProjectEntry(relativeFilePath, EntryType.File);
|
const fileEntry = this.createProjectEntry(relativeFilePath, EntryType.File);
|
||||||
this.files.push(fileEntry);
|
|
||||||
|
|
||||||
await this.addToProjFile(fileEntry);
|
let xmlTag;
|
||||||
|
switch (itemType) {
|
||||||
|
case templates.preDeployScript:
|
||||||
|
xmlTag = constants.PreDeploy;
|
||||||
|
this.preDeployScripts.push(fileEntry);
|
||||||
|
break;
|
||||||
|
case templates.postDeployScript:
|
||||||
|
xmlTag = constants.PostDeploy;
|
||||||
|
this.postDeployScripts.push(fileEntry);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
xmlTag = constants.Build;
|
||||||
|
this.files.push(fileEntry);
|
||||||
|
}
|
||||||
|
|
||||||
|
await this.addToProjFile(fileEntry, xmlTag);
|
||||||
|
|
||||||
return fileEntry;
|
return fileEntry;
|
||||||
}
|
}
|
||||||
@@ -335,7 +350,7 @@ export class Project {
|
|||||||
return new ProjectEntry(Uri.file(path.join(this.projectFolderPath, platformSafeRelativePath)), relativePath, entryType);
|
return new ProjectEntry(Uri.file(path.join(this.projectFolderPath, platformSafeRelativePath)), relativePath, entryType);
|
||||||
}
|
}
|
||||||
|
|
||||||
private findOrCreateItemGroup(containedTag?: string): any {
|
private findOrCreateItemGroup(containedTag?: string, prePostScriptExist?: { scriptExist: boolean; }): any {
|
||||||
let outputItemGroup = undefined;
|
let outputItemGroup = undefined;
|
||||||
|
|
||||||
// search for a particular item goup if a child type is provided
|
// search for a particular item goup if a child type is provided
|
||||||
@@ -356,16 +371,32 @@ export class Project {
|
|||||||
if (!outputItemGroup) {
|
if (!outputItemGroup) {
|
||||||
outputItemGroup = this.projFileXmlDoc.createElement(constants.ItemGroup);
|
outputItemGroup = this.projFileXmlDoc.createElement(constants.ItemGroup);
|
||||||
this.projFileXmlDoc.documentElement.appendChild(outputItemGroup);
|
this.projFileXmlDoc.documentElement.appendChild(outputItemGroup);
|
||||||
|
if (prePostScriptExist) {
|
||||||
|
prePostScriptExist.scriptExist = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return outputItemGroup;
|
return outputItemGroup;
|
||||||
}
|
}
|
||||||
|
|
||||||
private addFileToProjFile(path: string) {
|
private addFileToProjFile(path: string, xmlTag: string) {
|
||||||
const newFileNode = this.projFileXmlDoc.createElement(constants.Build);
|
let itemGroup;
|
||||||
newFileNode.setAttribute(constants.Include, utils.convertSlashesForSqlProj(path));
|
|
||||||
|
|
||||||
this.findOrCreateItemGroup(constants.Build).appendChild(newFileNode);
|
if (xmlTag === constants.PreDeploy || xmlTag === constants.PostDeploy) {
|
||||||
|
let prePostScriptExist = { scriptExist: true };
|
||||||
|
itemGroup = this.findOrCreateItemGroup(xmlTag, prePostScriptExist);
|
||||||
|
if (prePostScriptExist.scriptExist === true) {
|
||||||
|
window.showInformationMessage(constants.deployScriptExists(xmlTag));
|
||||||
|
xmlTag = constants.None; // Add only one pre-deploy and post-deploy script. All additional ones get added in the same item group with None tag
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
itemGroup = this.findOrCreateItemGroup(xmlTag);
|
||||||
|
}
|
||||||
|
|
||||||
|
const newFileNode = this.projFileXmlDoc.createElement(xmlTag);
|
||||||
|
newFileNode.setAttribute(constants.Include, utils.convertSlashesForSqlProj(path));
|
||||||
|
itemGroup.appendChild(newFileNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
private removeFileFromProjFile(path: string) {
|
private removeFileFromProjFile(path: string) {
|
||||||
@@ -512,10 +543,10 @@ export class Project {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async addToProjFile(entry: ProjectEntry) {
|
private async addToProjFile(entry: ProjectEntry, xmlTag?: string) {
|
||||||
switch (entry.type) {
|
switch (entry.type) {
|
||||||
case EntryType.File:
|
case EntryType.File:
|
||||||
this.addFileToProjFile(entry.relativePath);
|
this.addFileToProjFile(entry.relativePath, xmlTag ? xmlTag : constants.Build);
|
||||||
break;
|
break;
|
||||||
case EntryType.Folder:
|
case EntryType.Folder:
|
||||||
this.addFolderToProjFile(entry.relativePath);
|
this.addFolderToProjFile(entry.relativePath);
|
||||||
|
|||||||
@@ -16,6 +16,8 @@ export const table: string = 'table';
|
|||||||
export const view: string = 'view';
|
export const view: string = 'view';
|
||||||
export const storedProcedure: string = 'storedProcedure';
|
export const storedProcedure: string = 'storedProcedure';
|
||||||
export const folder: string = 'folder';
|
export const folder: string = 'folder';
|
||||||
|
export const preDeployScript: string = 'preDeployScript';
|
||||||
|
export const postDeployScript: string = 'postDeployScript';
|
||||||
|
|
||||||
// Object maps
|
// Object maps
|
||||||
|
|
||||||
@@ -45,7 +47,9 @@ export async function loadTemplates(templateFolderPath: string) {
|
|||||||
loadObjectTypeInfo(script, constants.scriptFriendlyName, templateFolderPath, 'newTsqlScriptTemplate.sql'),
|
loadObjectTypeInfo(script, constants.scriptFriendlyName, templateFolderPath, 'newTsqlScriptTemplate.sql'),
|
||||||
loadObjectTypeInfo(table, constants.tableFriendlyName, templateFolderPath, 'newTsqlTableTemplate.sql'),
|
loadObjectTypeInfo(table, constants.tableFriendlyName, templateFolderPath, 'newTsqlTableTemplate.sql'),
|
||||||
loadObjectTypeInfo(view, constants.viewFriendlyName, templateFolderPath, 'newTsqlViewTemplate.sql'),
|
loadObjectTypeInfo(view, constants.viewFriendlyName, templateFolderPath, 'newTsqlViewTemplate.sql'),
|
||||||
loadObjectTypeInfo(storedProcedure, constants.storedProcedureFriendlyName, templateFolderPath, 'newTsqlStoredProcedureTemplate.sql')
|
loadObjectTypeInfo(storedProcedure, constants.storedProcedureFriendlyName, templateFolderPath, 'newTsqlStoredProcedureTemplate.sql'),
|
||||||
|
loadObjectTypeInfo(preDeployScript, constants.preDeployScriptFriendlyName, templateFolderPath, 'newTsqlPreDeployScriptTemplate.sql'),
|
||||||
|
loadObjectTypeInfo(postDeployScript, constants.postDeployScriptFriendlyName, templateFolderPath, 'newTsqlPostDeployScriptTemplate.sql')
|
||||||
]);
|
]);
|
||||||
|
|
||||||
for (const scriptType of scriptTypes) {
|
for (const scriptType of scriptTypes) {
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import * as should from 'should';
|
|||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
import * as sinon from 'sinon';
|
import * as sinon from 'sinon';
|
||||||
import * as baselines from './baselines/baselines';
|
import * as baselines from './baselines/baselines';
|
||||||
|
import * as templates from '../templates/templates';
|
||||||
import * as testUtils from './testUtils';
|
import * as testUtils from './testUtils';
|
||||||
import * as constants from '../common/constants';
|
import * as constants from '../common/constants';
|
||||||
|
|
||||||
@@ -231,6 +232,58 @@ describe('Project: sqlproj content operations', function (): void {
|
|||||||
await testUtils.shouldThrowSpecificError(async () => await project.addDatabaseReference(Uri.parse('test.dacpac'), DatabaseReferenceLocation.sameDatabase), constants.databaseReferenceAlreadyExists);
|
await testUtils.shouldThrowSpecificError(async () => await project.addDatabaseReference(Uri.parse('test.dacpac'), DatabaseReferenceLocation.sameDatabase), constants.databaseReferenceAlreadyExists);
|
||||||
should(project.databaseReferences.length).equal(2, 'There should be two database references after trying to add a reference to test.dacpac again');
|
should(project.databaseReferences.length).equal(2, 'There should be two database references after trying to add a reference to test.dacpac again');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('Should add pre and post deployment scripts as entries to sqlproj', async function (): Promise<void> {
|
||||||
|
projFilePath = await testUtils.createTestSqlProjFile(baselines.newProjectFileBaseline);
|
||||||
|
const project: Project = await Project.openProject(projFilePath);
|
||||||
|
|
||||||
|
const folderPath = 'Pre-Post Deployment Scripts';
|
||||||
|
const preDeploymentScriptFilePath = path.join(folderPath, 'Script.PreDeployment1.sql');
|
||||||
|
const postDeploymentScriptFilePath = path.join(folderPath, 'Script.PostDeployment1.sql');
|
||||||
|
const fileContents = ' ';
|
||||||
|
|
||||||
|
await project.addFolderItem(folderPath);
|
||||||
|
await project.addScriptItem(preDeploymentScriptFilePath, fileContents, templates.preDeployScript);
|
||||||
|
await project.addScriptItem(postDeploymentScriptFilePath, fileContents, templates.postDeployScript);
|
||||||
|
|
||||||
|
const newProject = await Project.openProject(projFilePath);
|
||||||
|
|
||||||
|
should(newProject.preDeployScripts.find(f => f.type === EntryType.File && f.relativePath === convertSlashesForSqlProj(preDeploymentScriptFilePath))).not.equal(undefined, 'File Script.PreDeployment1.sql not read');
|
||||||
|
should(newProject.postDeployScripts.find(f => f.type === EntryType.File && f.relativePath === convertSlashesForSqlProj(postDeploymentScriptFilePath))).not.equal(undefined, 'File Script.PostDeployment1.sql not read');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Should show information messages when adding more than one pre/post deployment scripts to sqlproj', async function (): Promise<void> {
|
||||||
|
const stub = sinon.stub(window, 'showInformationMessage').returns(<any>Promise.resolve());
|
||||||
|
|
||||||
|
projFilePath = await testUtils.createTestSqlProjFile(baselines.newProjectFileBaseline);
|
||||||
|
const project: Project = await Project.openProject(projFilePath);
|
||||||
|
|
||||||
|
const folderPath = 'Pre-Post Deployment Scripts';
|
||||||
|
const preDeploymentScriptFilePath = path.join(folderPath, 'Script.PreDeployment1.sql');
|
||||||
|
const postDeploymentScriptFilePath = path.join(folderPath, 'Script.PostDeployment1.sql');
|
||||||
|
const preDeploymentScriptFilePath2 = path.join(folderPath, 'Script.PreDeployment2.sql');
|
||||||
|
const postDeploymentScriptFilePath2 = path.join(folderPath, 'Script.PostDeployment2.sql');
|
||||||
|
const fileContents = ' ';
|
||||||
|
|
||||||
|
await project.addFolderItem(folderPath);
|
||||||
|
await project.addScriptItem(preDeploymentScriptFilePath, fileContents, templates.preDeployScript);
|
||||||
|
await project.addScriptItem(postDeploymentScriptFilePath, fileContents, templates.postDeployScript);
|
||||||
|
|
||||||
|
await project.addScriptItem(preDeploymentScriptFilePath2, fileContents, templates.preDeployScript);
|
||||||
|
should(stub.calledWith(constants.deployScriptExists(constants.PreDeploy))).be.true(`showInformationMessage not called with expected message '${constants.deployScriptExists(constants.PreDeploy)}' Actual '${stub.getCall(0).args[0]}'`);
|
||||||
|
|
||||||
|
await project.addScriptItem(postDeploymentScriptFilePath2, fileContents, templates.postDeployScript);
|
||||||
|
should(stub.calledWith(constants.deployScriptExists(constants.PostDeploy))).be.true(`showInformationMessage not called with expected message '${constants.deployScriptExists(constants.PostDeploy)}' Actual '${stub.getCall(0).args[0]}'`);
|
||||||
|
|
||||||
|
const newProject = await Project.openProject(projFilePath);
|
||||||
|
|
||||||
|
should(newProject.preDeployScripts.find(f => f.type === EntryType.File && f.relativePath === convertSlashesForSqlProj(preDeploymentScriptFilePath))).not.equal(undefined, 'File Script.PreDeployment1.sql not read');
|
||||||
|
should(newProject.postDeployScripts.find(f => f.type === EntryType.File && f.relativePath === convertSlashesForSqlProj(postDeploymentScriptFilePath))).not.equal(undefined, 'File Script.PostDeployment1.sql not read');
|
||||||
|
should(newProject.noneDeployScripts.length).equal(2);
|
||||||
|
should(newProject.noneDeployScripts.find(f => f.type === EntryType.File && f.relativePath === convertSlashesForSqlProj(preDeploymentScriptFilePath2))).not.equal(undefined, 'File Script.PreDeployment2.sql not read');
|
||||||
|
should(newProject.noneDeployScripts.find(f => f.type === EntryType.File && f.relativePath === convertSlashesForSqlProj(postDeploymentScriptFilePath2))).not.equal(undefined, 'File Script.PostDeployment2.sql not read');
|
||||||
|
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Project: round trip updates', function (): void {
|
describe('Project: round trip updates', function (): void {
|
||||||
|
|||||||
@@ -243,6 +243,25 @@ describe('ProjectsController', function (): void {
|
|||||||
|
|
||||||
should(await exists(scriptEntry.fsUri.fsPath)).equal(true, 'script is supposed to still exist on disk');
|
should(await exists(scriptEntry.fsUri.fsPath)).equal(true, 'script is supposed to still exist on disk');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('Should be able to add pre deploy and post deploy script', async function (): Promise<void> {
|
||||||
|
const preDeployScriptName = 'PreDeployScript1.sql';
|
||||||
|
const postDeployScriptName = 'PostDeployScript1.sql';
|
||||||
|
|
||||||
|
const projController = new ProjectsController(new SqlDatabaseProjectTreeViewProvider());
|
||||||
|
const project = await testUtils.createTestProject(baselines.newProjectFileBaseline);
|
||||||
|
|
||||||
|
sinon.stub(vscode.window, 'showInputBox').resolves(preDeployScriptName);
|
||||||
|
should(project.preDeployScripts.length).equal(0, 'There should be no pre deploy scripts');
|
||||||
|
await projController.addItemPrompt(project, '', templates.preDeployScript);
|
||||||
|
should(project.preDeployScripts.length).equal(1, `Pre deploy script should be successfully added. ${project.preDeployScripts.length}, ${project.files.length}`);
|
||||||
|
|
||||||
|
sinon.restore();
|
||||||
|
sinon.stub(vscode.window, 'showInputBox').resolves(postDeployScriptName);
|
||||||
|
should(project.postDeployScripts.length).equal(0, 'There should be no post deploy scripts');
|
||||||
|
await projController.addItemPrompt(project, '', templates.postDeployScript);
|
||||||
|
should(project.postDeployScripts.length).equal(1, 'Post deploy script should be successfully added');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Publishing and script generation', function (): void {
|
describe('Publishing and script generation', function (): void {
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ describe('Templates: loading templates from disk', function (): void {
|
|||||||
|
|
||||||
// check expected counts
|
// check expected counts
|
||||||
|
|
||||||
const numScriptObjectTypes = 4;
|
const numScriptObjectTypes = 6;
|
||||||
|
|
||||||
should(templates.projectScriptTypes().length).equal(numScriptObjectTypes);
|
should(templates.projectScriptTypes().length).equal(numScriptObjectTypes);
|
||||||
should(Object.keys(templates.projectScriptTypes()).length).equal(numScriptObjectTypes);
|
should(Object.keys(templates.projectScriptTypes()).length).equal(numScriptObjectTypes);
|
||||||
|
|||||||
Reference in New Issue
Block a user