mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-01-14 17:22:20 -05:00
Adding Move, Exclude, and Rename support for folders (#22867)
* Adding exclude folder and base for move folder * checkpoint * rename * Fixing up tests * Adding exclude test to projController * Adding tests * fixing order of service.moveX() calls * Updating move() order in sqlproj service * PR feedback * unskipping * reskipping test * Fixing folder move conditional * updating comments
This commit is contained in:
@@ -797,31 +797,27 @@ export class ProjectsController {
|
||||
const node = context.element as BaseProjectTreeItem;
|
||||
const project = await this.getProjectFromContext(node);
|
||||
|
||||
const fileEntry = this.getFileProjectEntry(project, node);
|
||||
|
||||
if (fileEntry) {
|
||||
if (node.entryKey) {
|
||||
TelemetryReporter.sendActionEvent(TelemetryViews.ProjectTree, TelemetryActions.excludeFromProject);
|
||||
|
||||
switch (node.type) {
|
||||
case constants.DatabaseProjectItemType.sqlObjectScript:
|
||||
case constants.DatabaseProjectItemType.table:
|
||||
case constants.DatabaseProjectItemType.externalStreamingJob:
|
||||
await project.excludeSqlObjectScript(fileEntry.relativePath);
|
||||
await project.excludeSqlObjectScript(node.entryKey);
|
||||
break;
|
||||
case constants.DatabaseProjectItemType.folder:
|
||||
// TODO: not yet supported in DacFx
|
||||
//await project.excludeFolder(fileEntry.relativePath);
|
||||
void vscode.window.showErrorMessage(constants.excludeFolderNotSupported);
|
||||
await project.excludeFolder(node.entryKey);
|
||||
break;
|
||||
case constants.DatabaseProjectItemType.preDeploymentScript:
|
||||
await project.excludePreDeploymentScript(fileEntry.relativePath);
|
||||
await project.excludePreDeploymentScript(node.entryKey);
|
||||
break;
|
||||
case constants.DatabaseProjectItemType.postDeploymentScript:
|
||||
await project.excludePostDeploymentScript(fileEntry.relativePath);
|
||||
await project.excludePostDeploymentScript(node.entryKey);
|
||||
break;
|
||||
case constants.DatabaseProjectItemType.noneFile:
|
||||
case constants.DatabaseProjectItemType.publishProfile:
|
||||
await project.excludeNoneItem(fileEntry.relativePath);
|
||||
await project.excludeNoneItem(node.entryKey);
|
||||
break;
|
||||
default:
|
||||
throw new Error(constants.unhandledExcludeType(node.type));
|
||||
@@ -904,25 +900,21 @@ export class ProjectsController {
|
||||
public async rename(context: dataworkspace.WorkspaceTreeItem): Promise<void> {
|
||||
const node = context.element as BaseProjectTreeItem;
|
||||
const project = await this.getProjectFromContext(node);
|
||||
const file = this.getFileProjectEntry(project, node);
|
||||
const baseName = path.basename(node.friendlyName);
|
||||
let fileExtension: string;
|
||||
|
||||
if (utils.isPublishProfile(baseName)) {
|
||||
fileExtension = constants.publishProfileExtension;
|
||||
} else {
|
||||
fileExtension = constants.sqlFileExtension;
|
||||
}
|
||||
const originalAbsolutePath = utils.getPlatformSafeFileEntryPath(node.projectFileUri.fsPath);
|
||||
const originalName = path.basename(node.friendlyName);
|
||||
const originalExt = path.extname(node.friendlyName);
|
||||
|
||||
// need to use quickpick because input box isn't supported in treeviews
|
||||
// https://github.com/microsoft/vscode/issues/117502 and https://github.com/microsoft/vscode/issues/97190
|
||||
const newFileName = await vscode.window.showInputBox(
|
||||
{
|
||||
title: constants.enterNewName,
|
||||
value: path.basename(baseName, fileExtension),
|
||||
value: originalName,
|
||||
valueSelection: [0, path.basename(originalName, originalExt).length],
|
||||
ignoreFocusOut: true,
|
||||
validateInput: async (value) => {
|
||||
return await this.fileAlreadyExists(value, file?.fsUri.fsPath!) ? constants.fileAlreadyExists(value) : undefined;
|
||||
validateInput: async (newName) => {
|
||||
return await this.fileAlreadyExists(newName, originalAbsolutePath) ? constants.fileAlreadyExists(newName) : undefined;
|
||||
}
|
||||
});
|
||||
|
||||
@@ -930,22 +922,21 @@ export class ProjectsController {
|
||||
return;
|
||||
}
|
||||
|
||||
const newFilePath = path.join(path.dirname(utils.getPlatformSafeFileEntryPath(file?.relativePath!)), `${newFileName}${fileExtension}`);
|
||||
const newFilePath = path.join(path.dirname(utils.getPlatformSafeFileEntryPath(node.relativeProjectUri.fsPath!)), newFileName);
|
||||
const result = await project.move(node, newFilePath);
|
||||
|
||||
const renameResult = await project.move(node, newFilePath);
|
||||
|
||||
if (renameResult?.success) {
|
||||
if (result?.success) {
|
||||
TelemetryReporter.sendActionEvent(TelemetryViews.ProjectTree, TelemetryActions.rename);
|
||||
} else {
|
||||
TelemetryReporter.sendErrorEvent2(TelemetryViews.ProjectTree, TelemetryActions.rename);
|
||||
void vscode.window.showErrorMessage(constants.errorRenamingFile(file?.relativePath!, newFilePath, utils.getErrorMessage(renameResult?.errorMessage)));
|
||||
void vscode.window.showErrorMessage(constants.errorRenamingFile(node.entryKey!, newFilePath, result?.errorMessage));
|
||||
}
|
||||
|
||||
this.refreshProjectsTree(context);
|
||||
}
|
||||
|
||||
private fileAlreadyExists(newFileName: string, previousFilePath: string): Promise<boolean> {
|
||||
return utils.exists(path.join(path.dirname(previousFilePath), `${newFileName}.sql`));
|
||||
return utils.exists(path.join(path.dirname(previousFilePath), newFileName));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1488,21 +1479,6 @@ export class ProjectsController {
|
||||
|
||||
//#region Helper methods
|
||||
|
||||
private getFileProjectEntry(project: Project, context: BaseProjectTreeItem): FileProjectEntry | undefined {
|
||||
const fileOrFolder = context as FileNode ? context as FileNode : context as FolderNode;
|
||||
|
||||
if (fileOrFolder) {
|
||||
// use relative path and not tree paths for files and folder
|
||||
const allFileEntries = project.files.concat(project.preDeployScripts).concat(project.postDeployScripts).concat(project.noneDeployScripts).concat(project.publishProfiles);
|
||||
|
||||
// trim trailing slash since folders with and without a trailing slash are allowed in a sqlproj
|
||||
const trimmedUri = utils.trimChars(utils.getPlatformSafeFileEntryPath(utils.trimUri(fileOrFolder.projectFileUri, fileOrFolder.fileSystemUri)), '/');
|
||||
return allFileEntries.find(x => utils.trimChars(utils.getPlatformSafeFileEntryPath(x.relativePath), '/') === trimmedUri);
|
||||
}
|
||||
const projectRelativeUri = vscode.Uri.file(path.basename(context.projectFileUri.fsPath, constants.sqlprojExtension));
|
||||
return project.files.find(x => utils.getPlatformSafeFileEntryPath(x.relativePath) === utils.getPlatformSafeFileEntryPath(utils.trimUri(projectRelativeUri, context.relativeProjectUri)));
|
||||
}
|
||||
|
||||
private async getProjectFromContext(context: Project | BaseProjectTreeItem | dataworkspace.WorkspaceTreeItem): Promise<Project> {
|
||||
if ('element' in context) {
|
||||
context = context.element;
|
||||
@@ -1881,23 +1857,22 @@ export class ProjectsController {
|
||||
//#endregion
|
||||
|
||||
/**
|
||||
* Move a file in the project tree
|
||||
* Move a file or folder in the project tree
|
||||
* @param projectUri URI of the project
|
||||
* @param source
|
||||
* @param target
|
||||
*/
|
||||
public async moveFile(projectUri: vscode.Uri, source: any, target: dataworkspace.WorkspaceTreeItem): Promise<void> {
|
||||
const sourceFileNode = source as FileNode;
|
||||
const sourceFileNode = source as FileNode | FolderNode;
|
||||
const project = await this.getProjectFromContext(sourceFileNode);
|
||||
|
||||
// only moving files is supported
|
||||
if (!sourceFileNode || !(sourceFileNode instanceof FileNode)) {
|
||||
void vscode.window.showErrorMessage(constants.onlyMoveSqlFilesSupported);
|
||||
// only moving files and folders are supported
|
||||
if (!sourceFileNode || !(sourceFileNode instanceof FileNode || sourceFileNode instanceof FolderNode)) {
|
||||
void vscode.window.showErrorMessage(constants.onlyMoveFilesFoldersSupported);
|
||||
return;
|
||||
}
|
||||
|
||||
// Moving files to the SQLCMD variables and Database references folders isn't allowed
|
||||
// TODO: should there be an error displayed if a file attempting to move a file to sqlcmd variables or database references? Or just silently fail and do nothing?
|
||||
// Moving files/folders to the SQLCMD variables and Database references folders isn't allowed
|
||||
if (!target.element.fileSystemUri) {
|
||||
return;
|
||||
}
|
||||
@@ -1930,7 +1905,7 @@ export class ProjectsController {
|
||||
return;
|
||||
}
|
||||
|
||||
// Move the file
|
||||
// Move the file/folder
|
||||
const moveResult = await project.move(sourceFileNode, newPath);
|
||||
|
||||
if (moveResult?.success) {
|
||||
|
||||
Reference in New Issue
Block a user