mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-01-13 17:22:15 -05:00
fix excluding pre/post/none deploy scripts in sdk style projects (#18117)
This commit is contained in:
@@ -238,6 +238,10 @@ export class Project implements ISqlProject {
|
||||
this.preDeployScripts.forEach(f => filesSet.delete(f.relativePath));
|
||||
this.postDeployScripts.forEach(f => filesSet.delete(f.relativePath));
|
||||
this.noneDeployScripts.forEach(f => filesSet.delete(f.relativePath));
|
||||
|
||||
// remove any none remove scripts (these would be pre/post/none deploy scripts that were excluded)
|
||||
const noneRemoveScripts = this.readNoneRemoveScripts();
|
||||
noneRemoveScripts.forEach(f => filesSet.delete(f.relativePath));
|
||||
}
|
||||
|
||||
// create a FileProjectEntry for each file
|
||||
@@ -379,7 +383,10 @@ export class Project implements ISqlProject {
|
||||
try {
|
||||
const noneItems = itemGroup.getElementsByTagName(constants.None);
|
||||
for (let n = 0; n < noneItems.length; n++) {
|
||||
noneDeployScripts.push(this.createFileProjectEntry(noneItems[n].getAttribute(constants.Include)!, EntryType.File));
|
||||
const includeAttribute = noneItems[n].getAttribute(constants.Include);
|
||||
if (includeAttribute) {
|
||||
noneDeployScripts.push(this.createFileProjectEntry(includeAttribute, EntryType.File));
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
void window.showErrorMessage(constants.errorReadingProject(constants.NoneElements, this.projectFilePath));
|
||||
@@ -390,6 +397,30 @@ export class Project implements ISqlProject {
|
||||
return noneDeployScripts;
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns all the files specified as <None Remove="file.sql" /> in the sqlproj
|
||||
*/
|
||||
private readNoneRemoveScripts(): FileProjectEntry[] {
|
||||
const noneRemoveScripts: FileProjectEntry[] = [];
|
||||
|
||||
for (let ig = 0; ig < this.projFileXmlDoc!.documentElement.getElementsByTagName(constants.ItemGroup).length; ig++) {
|
||||
const itemGroup = this.projFileXmlDoc!.documentElement.getElementsByTagName(constants.ItemGroup)[ig];
|
||||
|
||||
// find all none remove scripts to specified in the sqlproj
|
||||
try {
|
||||
const noneItems = itemGroup.getElementsByTagName(constants.None);
|
||||
for (let n = 0; n < noneItems.length; n++) {
|
||||
noneRemoveScripts.push(this.createFileProjectEntry(noneItems[n].getAttribute(constants.Remove)!, EntryType.File));
|
||||
}
|
||||
} catch (e) {
|
||||
void window.showErrorMessage(constants.errorReadingProject(constants.NoneElements, this.projectFilePath));
|
||||
console.error(utils.getErrorMessage(e));
|
||||
}
|
||||
}
|
||||
|
||||
return noneRemoveScripts;
|
||||
}
|
||||
|
||||
private readDatabaseReferences(): IDatabaseReferenceProjectEntry[] {
|
||||
const databaseReferenceEntries: IDatabaseReferenceProjectEntry[] = [];
|
||||
|
||||
@@ -969,6 +1000,8 @@ export class Project implements ISqlProject {
|
||||
const noneNodes = this.projFileXmlDoc!.documentElement.getElementsByTagName(constants.None);
|
||||
const nodes = [fileNodes, preDeployNodes, postDeployNodes, noneNodes];
|
||||
|
||||
const isBuildElement = this.files.find(f => f.relativePath === path);
|
||||
|
||||
let deleted = false;
|
||||
|
||||
// remove the <Build Include="..."> entry if there is one
|
||||
@@ -992,13 +1025,17 @@ export class Project implements ISqlProject {
|
||||
if (deleted) {
|
||||
await this.serializeToProjFile(this.projFileXmlDoc!);
|
||||
}
|
||||
this._preDeployScripts = this.readPreDeployScripts();
|
||||
this._postDeployScripts = this.readPostDeployScripts();
|
||||
this._noneDeployScripts = this.readNoneDeployScripts();
|
||||
const currentFiles = await this.readFilesInProject();
|
||||
|
||||
// only add a node to exclude the file if it's still included by a glob
|
||||
// only add a Remove node to exclude the file if it's still included by a glob
|
||||
if (currentFiles.find(f => f.relativePath === utils.convertSlashesForSqlProj(path))) {
|
||||
const removeFileNode = this.projFileXmlDoc!.createElement(constants.Build);
|
||||
const removeFileNode = isBuildElement ? this.projFileXmlDoc!.createElement(constants.Build) : this.projFileXmlDoc!.createElement(constants.None);
|
||||
removeFileNode.setAttribute(constants.Remove, utils.convertSlashesForSqlProj(path));
|
||||
this.findOrCreateItemGroup(constants.Build).appendChild(removeFileNode);
|
||||
return;
|
||||
}
|
||||
|
||||
return;
|
||||
@@ -1503,6 +1540,10 @@ export class Project implements ISqlProject {
|
||||
* @returns Project entry for the last folder in the path, if path is under the project folder; otherwise `undefined`.
|
||||
*/
|
||||
private async ensureFolderItems(relativeFolderPath: string): Promise<FileProjectEntry | undefined> {
|
||||
if (!relativeFolderPath) {
|
||||
return;
|
||||
}
|
||||
|
||||
const absoluteFolderPath = path.join(this.projectFolderPath, relativeFolderPath);
|
||||
const normalizedProjectFolderPath = path.normalize(this.projectFolderPath);
|
||||
|
||||
|
||||
@@ -988,6 +988,45 @@ describe('Project: sdk style project content operations', function (): void {
|
||||
should(project.files.filter(f => f.relativePath === 'file1.sql').length).equal(0);
|
||||
});
|
||||
|
||||
it('Should exclude pre/post/none deploy scripts correctly', async function (): Promise<void> {
|
||||
const folderPath = await testUtils.generateTestFolderPath();
|
||||
projFilePath = await testUtils.createTestSqlProjFile(baselines.newSdkStyleProjectSdkNodeBaseline, folderPath);
|
||||
|
||||
const project: Project = await Project.openProject(projFilePath);
|
||||
await project.addScriptItem('Script.PreDeployment1.sql', 'fake contents', templates.preDeployScript);
|
||||
await project.addScriptItem('Script.PreDeployment2.sql', 'fake contents', templates.preDeployScript);
|
||||
await project.addScriptItem('Script.PostDeployment1.sql', 'fake contents', templates.postDeployScript);
|
||||
|
||||
// verify they were added to the sqlproj
|
||||
let projFileText = (await fs.readFile(projFilePath)).toString();
|
||||
should(projFileText.includes('<PreDeploy Include="Script.PreDeployment1.sql" />')).equal(true);
|
||||
should(projFileText.includes('<None Include="Script.PreDeployment2.sql" />')).equal(true);
|
||||
should(projFileText.includes('<PostDeploy Include="Script.PostDeployment1.sql" />')).equal(true);
|
||||
should(project.preDeployScripts.length).equal(1, 'Script.PreDeployment1.sql should have been added');
|
||||
should(project.noneDeployScripts.length).equal(1, 'Script.PreDeployment2.sql should have been added');
|
||||
should(project.preDeployScripts.length).equal(1, 'Script.PostDeployment1.sql should have been added');
|
||||
should(project.files.length).equal(0, 'There should not be any files');
|
||||
|
||||
// exclude the pre/post/none deploy script
|
||||
await project.exclude(project.preDeployScripts.find(f => f.relativePath === 'Script.PreDeployment1.sql')!);
|
||||
await project.exclude(project.noneDeployScripts.find(f => f.relativePath === 'Script.PreDeployment2.sql')!);
|
||||
await project.exclude(project.postDeployScripts.find(f => f.relativePath === 'Script.PostDeployment1.sql')!);
|
||||
|
||||
// verify they are excluded in the sqlproj
|
||||
projFileText = (await fs.readFile(projFilePath)).toString();
|
||||
should(projFileText.includes('<PreDeploy Include="Script.PreDeployment1.sql" />')).equal(false);
|
||||
should(projFileText.includes('<None Include="Script.PreDeployment2.sql" />')).equal(false);
|
||||
should(projFileText.includes('<PostDeploy Include="Script.PostDeployment1.sql" />')).equal(false);
|
||||
should(projFileText.includes('<None Remove="Script.PreDeployment1.sql" />')).equal(true);
|
||||
should(projFileText.includes('<None Remove="Script.PreDeployment2.sql" />')).equal(true);
|
||||
should(projFileText.includes('<None Remove="Script.PostDeployment1.sql" />')).equal(true);
|
||||
|
||||
should(project.preDeployScripts.length).equal(0, 'Script.PreDeployment1.sql should have been removed');
|
||||
should(project.noneDeployScripts.length).equal(0, 'Script.PreDeployment2.sql should have been removed');
|
||||
should(project.postDeployScripts.length).equal(0, 'Script.PostDeployment1.sql should have been removed');
|
||||
should(project.files.length).equal(0, 'There should not be any files after the excludes');
|
||||
});
|
||||
|
||||
it('Should handle excluding files included by glob patterns', async function (): Promise<void> {
|
||||
const testFolderPath = await testUtils.generateTestFolderPath();
|
||||
const mainProjectPath = path.join(testFolderPath, 'project');
|
||||
|
||||
Reference in New Issue
Block a user