From 676f419ddded0625abc9e9db2ba78f9bd6e3b2b0 Mon Sep 17 00:00:00 2001 From: Benjin Dubishar Date: Mon, 22 May 2023 17:51:23 -0700 Subject: [PATCH] Adding option to open referenced project from SQL Project reference item (#23178) * Adding hook to open a referenced SQL project * cleanup * adding docstring --- .../src/services/workspaceService.ts | 2 +- extensions/sql-database-projects/package.json | 16 +++++++++++++++- .../sql-database-projects/package.nls.json | 1 + .../src/common/constants.ts | 1 + .../src/controllers/mainController.ts | 1 + .../src/controllers/projectController.ts | 18 +++++++++++++++++- .../models/tree/databaseReferencesTreeItem.ts | 13 +++++++++++-- 7 files changed, 47 insertions(+), 5 deletions(-) diff --git a/extensions/data-workspace/src/services/workspaceService.ts b/extensions/data-workspace/src/services/workspaceService.ts index 18d138a140..31014522d3 100644 --- a/extensions/data-workspace/src/services/workspaceService.ts +++ b/extensions/data-workspace/src/services/workspaceService.ts @@ -81,7 +81,7 @@ export class WorkspaceService implements IWorkspaceService { vscode.workspace.updateWorkspaceFolders(vscode.workspace.workspaceFolders?.length || 0, undefined, ...(newWorkspaceFolders.map(folder => ({ uri: vscode.Uri.file(folder) })))); } - // 2. Compare projcets being added against prior (cached) list of projects in the workspace + // 2. Compare projects being added against prior (cached) list of projects in the workspace const previousProjects: string[] = (await this.getProjectsInWorkspace(undefined, false)).map(p => p.path); let newProjectAdded: boolean = false; diff --git a/extensions/sql-database-projects/package.json b/extensions/sql-database-projects/package.json index a7d979b526..1577874231 100644 --- a/extensions/sql-database-projects/package.json +++ b/extensions/sql-database-projects/package.json @@ -163,6 +163,11 @@ "title": "%sqlDatabaseProjects.addDatabaseReference%", "category": "%sqlDatabaseProjects.displayName%" }, + { + "command": "sqlDatabaseProjects.openReferencedSqlProject", + "title": "%sqlDatabaseProjects.openReferencedSqlProject%", + "category": "%sqlDatabaseProjects.displayName%" + }, { "command": "sqlDatabaseProjects.validateExternalStreamingJob", "title": "%sqlDatabaseProjects.validateExternalStreamingJob%", @@ -300,6 +305,10 @@ "command": "sqlDatabaseProjects.addDatabaseReference", "when": "false" }, + { + "command": "sqlDatabaseProjects.openReferencedSqlProject", + "when": "false" + }, { "command": "sqlDatabaseProjects.validateExternalStreamingJob", "when": "false" @@ -431,6 +440,11 @@ "when": "azdataAvailable && view == dataworkspace.views.main && viewItem == databaseProject.itemType.file.table", "group": "6_dbProjects_openInDesigner" }, + { + "command": "sqlDatabaseProjects.openReferencedSqlProject", + "when": "view == dataworkspace.views.main && viewItem == databaseProject.itemType.reference.sqlProject", + "group": "8_dbProjects_openReferencedSqlProject" + }, { "command": "sqlDatabaseProjects.exclude", "when": "view == dataworkspace.views.main && viewItem == databaseProject.itemType.folder || viewItem =~ /^databaseProject.itemType.file/", @@ -438,7 +452,7 @@ }, { "command": "sqlDatabaseProjects.delete", - "when": "view == dataworkspace.views.main && viewItem == databaseProject.itemType.folder || viewItem =~ /^databaseProject.itemType.file/ || viewItem == databaseProject.itemType.reference || viewItem == databaseProject.itemType.sqlcmdVariable", + "when": "view == dataworkspace.views.main && viewItem == databaseProject.itemType.folder || viewItem =~ /^databaseProject.itemType.file/ || viewItem =~ /^databaseProject.itemType.reference/ || viewItem == databaseProject.itemType.sqlcmdVariable", "group": "9_dbProjectsLast@2" }, { diff --git a/extensions/sql-database-projects/package.nls.json b/extensions/sql-database-projects/package.nls.json index 60973d5242..78faa513a0 100644 --- a/extensions/sql-database-projects/package.nls.json +++ b/extensions/sql-database-projects/package.nls.json @@ -38,6 +38,7 @@ "sqlDatabaseProjects.generateProjectFromOpenApiSpec": "Generate SQL Project from OpenAPI/Swagger spec (Preview)", "sqlDatabaseProjects.convertToSdkStyleProject": "Convert to SDK-style project", "sqlDatabaseProjects.openInDesigner": "Open in Designer", + "sqlDatabaseProjects.openReferencedSqlProject": "Open project", "sqlDatabaseProjects.Settings": "Database Projects", "sqlDatabaseProjects.dotnetInstallLocation": "Full path to .NET SDK on the machine. For example, if dotnet.exe is located at C:\\folder1\\dotnet\\dotnet.exe, set the path for this setting to C:\\folder1\\dotnet", diff --git a/extensions/sql-database-projects/src/common/constants.ts b/extensions/sql-database-projects/src/common/constants.ts index 969e6bde7d..5920ad3f77 100644 --- a/extensions/sql-database-projects/src/common/constants.ts +++ b/extensions/sql-database-projects/src/common/constants.ts @@ -572,6 +572,7 @@ export enum DatabaseProjectItemType { table = 'databaseProject.itemType.file.table', referencesRoot = 'databaseProject.itemType.referencesRoot', reference = 'databaseProject.itemType.reference', + sqlProjectReference = 'databaseProject.itemType.reference.sqlProject', dataSourceRoot = 'databaseProject.itemType.dataSourceRoot', sqlcmdVariablesRoot = 'databaseProject.itemType.sqlcmdVariablesRoot', sqlcmdVariable = 'databaseProject.itemType.sqlcmdVariable', diff --git a/extensions/sql-database-projects/src/controllers/mainController.ts b/extensions/sql-database-projects/src/controllers/mainController.ts index 6180254789..614eebdc76 100644 --- a/extensions/sql-database-projects/src/controllers/mainController.ts +++ b/extensions/sql-database-projects/src/controllers/mainController.ts @@ -81,6 +81,7 @@ export default class MainController implements vscode.Disposable { this.context.subscriptions.push(vscode.commands.registerCommand('sqlDatabaseProjects.newPublishProfile', async (node: WorkspaceTreeItem) => { return this.projectsController.addItemPromptFromNode(node, ItemType.publishProfile); })); this.context.subscriptions.push(vscode.commands.registerCommand('sqlDatabaseProjects.addDatabaseReference', async (node: WorkspaceTreeItem) => { return this.projectsController.addDatabaseReference(node); })); + this.context.subscriptions.push(vscode.commands.registerCommand('sqlDatabaseProjects.openReferencedSqlProject', async (node: WorkspaceTreeItem) => { return this.projectsController.openReferencedSqlProject(node); })); this.context.subscriptions.push(vscode.commands.registerCommand('sqlDatabaseProjects.openContainingFolder', async (node: WorkspaceTreeItem) => { return this.projectsController.openContainingFolder(node); })); this.context.subscriptions.push(vscode.commands.registerCommand('sqlDatabaseProjects.editProjectFile', async (node: WorkspaceTreeItem) => { return this.projectsController.editProjectFile(node); })); this.context.subscriptions.push(vscode.commands.registerCommand('sqlDatabaseProjects.delete', async (node: WorkspaceTreeItem) => { return this.projectsController.delete(node); })); diff --git a/extensions/sql-database-projects/src/controllers/projectController.ts b/extensions/sql-database-projects/src/controllers/projectController.ts index 43b0a257b6..167c005ca2 100644 --- a/extensions/sql-database-projects/src/controllers/projectController.ts +++ b/extensions/sql-database-projects/src/controllers/projectController.ts @@ -28,7 +28,7 @@ import { BuildHelper } from '../tools/buildHelper'; import { readPublishProfile, promptForSavingProfile, savePublishProfile } from '../models/publishProfile/publishProfile'; import { AddDatabaseReferenceDialog } from '../dialogs/addDatabaseReferenceDialog'; import { ISystemDatabaseReferenceSettings, IDacpacReferenceSettings, IProjectReferenceSettings, INugetPackageReferenceSettings } from '../models/IDatabaseReferenceSettings'; -import { DatabaseReferenceTreeItem } from '../models/tree/databaseReferencesTreeItem'; +import { DatabaseReferenceTreeItem, SqlProjectReferenceTreeItem } from '../models/tree/databaseReferencesTreeItem'; import { CreateProjectFromDatabaseDialog } from '../dialogs/createProjectFromDatabaseDialog'; import { UpdateProjectFromDatabaseDialog } from '../dialogs/updateProjectFromDatabaseDialog'; import { TelemetryActions, TelemetryReporter, TelemetryViews } from '../common/telemetry'; @@ -1028,6 +1028,22 @@ export class ProjectsController { await vscode.commands.executeCommand(constants.revealFileInOsCommand, vscode.Uri.file(project.projectFilePath)); } + /** + * Open the project indicated by `context` in the workspace + * @param context a SqlProjectReferenceTreeItem in the project's tree + */ + public async openReferencedSqlProject(context: dataworkspace.WorkspaceTreeItem): Promise { + const node = context.element as BaseProjectTreeItem; + const project = await this.getProjectFromContext(node); + + if (!(node instanceof SqlProjectReferenceTreeItem)) { + return; + } + + const absolutePath = path.normalize(path.join(project.projectFolderPath, node.reference.fsUri.fsPath)); + await this.openProjectInWorkspace(absolutePath); + } + /** * Opens the .sqlproj file for the given project. Upon update of file, prompts user to * reload their project. diff --git a/extensions/sql-database-projects/src/models/tree/databaseReferencesTreeItem.ts b/extensions/sql-database-projects/src/models/tree/databaseReferencesTreeItem.ts index 9cccd70f10..a7a1ee2247 100644 --- a/extensions/sql-database-projects/src/models/tree/databaseReferencesTreeItem.ts +++ b/extensions/sql-database-projects/src/models/tree/databaseReferencesTreeItem.ts @@ -10,6 +10,7 @@ import * as constants from '../../common/constants'; import { BaseProjectTreeItem } from './baseTreeItem'; import { IconPathHelper } from '../../common/iconHelper'; import { IDatabaseReferenceProjectEntry } from 'sqldbproj'; +import { SqlProjectReferenceProjectEntry } from '../projectEntry'; /** * Folder for containing references nodes in the tree @@ -35,7 +36,9 @@ export class DatabaseReferencesTreeItem extends BaseProjectTreeItem { } for (const reference of databaseReferences) { - this.references.push(new DatabaseReferenceTreeItem(reference, this.relativeProjectUri, this.projectFileUri)); + this.references.push(reference instanceof SqlProjectReferenceProjectEntry + ? new SqlProjectReferenceTreeItem(reference, this.relativeProjectUri, this.projectFileUri) + : new DatabaseReferenceTreeItem(reference, this.relativeProjectUri, this.projectFileUri)); } } @@ -57,7 +60,7 @@ export class DatabaseReferencesTreeItem extends BaseProjectTreeItem { } export class DatabaseReferenceTreeItem extends BaseProjectTreeItem { - constructor(private reference: IDatabaseReferenceProjectEntry, referencesNodeRelativeProjectUri: vscode.Uri, sqlprojUri: vscode.Uri) { + constructor(public readonly reference: IDatabaseReferenceProjectEntry, referencesNodeRelativeProjectUri: vscode.Uri, sqlprojUri: vscode.Uri) { super(vscode.Uri.file(path.join(referencesNodeRelativeProjectUri.fsPath, reference.referenceName)), sqlprojUri); this.entryKey = this.friendlyName; } @@ -79,3 +82,9 @@ export class DatabaseReferenceTreeItem extends BaseProjectTreeItem { return refItem; } } + +export class SqlProjectReferenceTreeItem extends DatabaseReferenceTreeItem { + public override get type(): constants.DatabaseProjectItemType { + return constants.DatabaseProjectItemType.sqlProjectReference; + } +}