Swap rename to use DacFx move api (#22051)

* swap rename to use DacFx project apis

* add support for rename pre/post deploy scripts and add tests

* update the enum names too

* check instanceof instead of getting and iterating through all the collections
This commit is contained in:
Kim Santiago
2023-02-28 11:59:09 -08:00
committed by GitHub
parent 8550faaa73
commit 0413b95343
5 changed files with 88 additions and 18 deletions

View File

@@ -565,10 +565,10 @@ export enum DatabaseProjectItemType {
dataSourceRoot = 'databaseProject.itemType.dataSourceRoot',
sqlcmdVariablesRoot = 'databaseProject.itemType.sqlcmdVariablesRoot',
sqlcmdVariable = 'databaseProject.itemType.sqlcmdVariable',
preDeploy = 'databaseProject.itemType.file.preDeploymentScript',
postDeploy = 'databaseProject.itemType.file.postDeployScript',
none = 'databaseProject.itemType.file.noneFile',
sqlObjectFile = 'databaseProject.itemType.file.sqlObjectScript',
preDeploymentScript = 'databaseProject.itemType.file.preDeploymentScript',
postDeploymentScript = 'databaseProject.itemType.file.postDeployScript',
noneFile = 'databaseProject.itemType.file.noneFile',
sqlObjectScript = 'databaseProject.itemType.file.sqlObjectScript',
publishProfile = 'databaseProject.itemType.file.publishProfile'
}

View File

@@ -20,7 +20,7 @@ import { promises as fs } from 'fs';
import { PublishDatabaseDialog } from '../dialogs/publishDatabaseDialog';
import { Project, reservedProjectFolders } from '../models/project';
import { SqlDatabaseProjectTreeViewProvider } from './databaseProjectTreeViewProvider';
import { FolderNode, FileNode } from '../models/tree/fileFolderTreeItem';
import { FolderNode, FileNode, SqlObjectFileNode, PreDeployNode, PostDeployNode } from '../models/tree/fileFolderTreeItem';
import { BaseProjectTreeItem } from '../models/tree/baseTreeItem';
import { ImportDataModel } from '../models/api/import';
import { NetCoreTool, DotNetError } from '../tools/netcoreTool';
@@ -856,12 +856,18 @@ export class ProjectsController {
return;
}
// TODO: swap this out and hookup to "Move" file/folder api
// rename the file
const newFilePath = path.join(path.dirname(file?.fsUri.fsPath!), `${newFileName}.sql`);
await fs.rename(file?.fsUri.fsPath!, newFilePath);
await project.exclude(file!);
await project.addExistingItem(newFilePath);
const newFilePath = path.join(path.dirname(utils.getPlatformSafeFileEntryPath(file?.relativePath!)), `${newFileName}.sql`);
const sqlProjectsService = await utils.getSqlProjectsService();
if (node instanceof SqlObjectFileNode) {
await sqlProjectsService.moveSqlObjectScript(project.projectFilePath, newFilePath, file!.relativePath)
} else if (node instanceof PreDeployNode) {
await sqlProjectsService.movePreDeploymentScript(project.projectFilePath, newFilePath, file!.relativePath)
} else if (node instanceof PostDeployNode) {
await sqlProjectsService.movePostDeploymentScript(project.projectFilePath, newFilePath, file!.relativePath)
}
// TODO add support for renaming none scripts after those are added in STS
// TODO add support for renaming publish profiles when support is added in DacFx
this.refreshProjectsTree(context);
}

View File

@@ -68,7 +68,7 @@ export abstract class FileNode extends BaseProjectTreeItem {
export class SqlObjectFileNode extends FileNode {
public override get treeItem(): vscode.TreeItem {
const treeItem = super.treeItem;
treeItem.contextValue = DatabaseProjectItemType.sqlObjectFile;
treeItem.contextValue = DatabaseProjectItemType.sqlObjectScript;
return treeItem;
}
@@ -95,7 +95,7 @@ export class TableFileNode extends SqlObjectFileNode {
export class PreDeployNode extends FileNode {
public override get treeItem(): vscode.TreeItem {
const treeItem = super.treeItem;
treeItem.contextValue = DatabaseProjectItemType.preDeploy;
treeItem.contextValue = DatabaseProjectItemType.preDeploymentScript;
return treeItem;
}
@@ -104,7 +104,7 @@ export class PreDeployNode extends FileNode {
export class PostDeployNode extends FileNode {
public override get treeItem(): vscode.TreeItem {
const treeItem = super.treeItem;
treeItem.contextValue = DatabaseProjectItemType.postDeploy;
treeItem.contextValue = DatabaseProjectItemType.postDeploymentScript;
return treeItem;
}
@@ -113,7 +113,7 @@ export class PostDeployNode extends FileNode {
export class NoneNode extends FileNode {
public override get treeItem(): vscode.TreeItem {
const treeItem = super.treeItem;
treeItem.contextValue = DatabaseProjectItemType.none;
treeItem.contextValue = DatabaseProjectItemType.noneFile;
return treeItem;
}

View File

@@ -923,6 +923,70 @@ describe('ProjectsController', function (): void {
});
});
describe('Rename file', function (): void {
it('Should not do anything if no new name is provided', async function (): Promise<void> {
sinon.stub(vscode.window, 'showInputBox').resolves('');
let proj = await testUtils.createTestProject(baselines.openSdkStyleSqlProjectBaseline);
const projTreeRoot = await setupMoveTest(proj);
const projController = new ProjectsController(testContext.outputChannel);
// try to rename a file from the root folder
const sqlFileNode = projTreeRoot.children.find(x => x.friendlyName === 'script1.sql');
await projController.rename(createWorkspaceTreeItem(sqlFileNode!));
// reload project and verify file was not renamed
proj = await Project.openProject(proj.projectFilePath);
should(proj.files.find(f => f.relativePath === 'script1.sql') !== undefined).be.true('The file path should not have been updated');
should(await utils.exists(path.join(proj.projectFolderPath, 'script1.sql'))).be.true('The moved file should exist');
});
it('Should rename a sql object file', async function (): Promise<void> {
sinon.stub(vscode.window, 'showInputBox').resolves('newName');
let proj = await testUtils.createTestProject(baselines.openSdkStyleSqlProjectBaseline);
const projTreeRoot = await setupMoveTest(proj);
const projController = new ProjectsController(testContext.outputChannel);
// try to rename a file from the root folder
const sqlFileNode = projTreeRoot.children.find(x => x.friendlyName === 'script1.sql');
await projController.rename(createWorkspaceTreeItem(sqlFileNode!));
// reload project and verify file was renamed
proj = await Project.openProject(proj.projectFilePath);
should(proj.files.find(f => f.relativePath === 'newName.sql') !== undefined).be.true('The file path should have been updated');
should(await utils.exists(path.join(proj.projectFolderPath, 'newName.sql'))).be.true('The moved file should exist');
});
it('Should rename a pre and post deploy script', async function (): Promise<void> {
let proj = await testUtils.createTestProject(baselines.newSdkStyleProjectSdkNodeBaseline);
await proj.addScriptItem('Script.PreDeployment1.sql', 'pre-deployment stuff', ItemType.preDeployScript);
await proj.addScriptItem('Script.PostDeployment1.sql', 'post-deployment stuff', ItemType.postDeployScript);
const projController = new ProjectsController(testContext.outputChannel);
const projTreeRoot = new ProjectRootTreeItem(proj);
// try to rename a file from the root folder
sinon.stub(vscode.window, 'showInputBox').resolves('predeployNewName');
const preDeployScriptNode = projTreeRoot.children.find(x => x.friendlyName === 'Script.PreDeployment1.sql');
await projController.rename(createWorkspaceTreeItem(preDeployScriptNode!));
sinon.restore();
sinon.stub(vscode.window, 'showInputBox').resolves('postdeployNewName');
const postDeployScriptNode = projTreeRoot.children.find(x => x.friendlyName === 'Script.PostDeployment1.sql');
await projController.rename(createWorkspaceTreeItem(postDeployScriptNode!));
// reload project and verify files were renamed
proj = await Project.openProject(proj.projectFilePath);
should(proj.preDeployScripts.find(f => f.relativePath === 'predeployNewName.sql') !== undefined).be.true('The pre deploy script file path should have been updated');
should(await utils.exists(path.join(proj.projectFolderPath, 'predeployNewName.sql'))).be.true('The moved pre deploy script file should exist');
should(proj.postDeployScripts.find(f => f.relativePath === 'postdeployNewName.sql') !== undefined).be.true('The post deploy script file path should have been updated');
should(await utils.exists(path.join(proj.projectFolderPath, 'postdeployNewName.sql'))).be.true('The moved post deploy script file should exist');
});
// TODO: add test for renaming a file in a folder after fix from DacFx for slashes is brought over
});
describe('SqlCmd Variables', function (): void {
it('Should delete sqlcmd variable', async function (): Promise<void> {
let project = await testUtils.createTestProject(baselines.openSdkStyleSqlProjectBaseline);

View File

@@ -86,13 +86,13 @@ describe('Project Tree tests', function (): void {
DatabaseProjectItemType.sqlcmdVariablesRoot,
DatabaseProjectItemType.folder,
DatabaseProjectItemType.folder,
DatabaseProjectItemType.sqlObjectFile]);
DatabaseProjectItemType.sqlObjectScript]);
should(tree.children.find(x => x.relativeProjectUri.path === '/TestProj/someFolder')?.children.map(y => y.treeItem.contextValue)).deepEqual([
DatabaseProjectItemType.folder,
DatabaseProjectItemType.folder,
DatabaseProjectItemType.sqlObjectFile,
DatabaseProjectItemType.sqlObjectFile]);
DatabaseProjectItemType.sqlObjectScript,
DatabaseProjectItemType.sqlObjectScript]);
});
it('Should be able to parse windows relative path as platform safe path', function (): void {