feat: show SSH:project name in status bar
This commit is contained in:
@@ -69,7 +69,7 @@ export default class DSHome {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'firstOpenRemoteFolder':
|
case 'firstOpenRemoteFolder':
|
||||||
await this.remoteContainer.firstOpenProject(data.host, data.port, data.username, data.path, this.context)
|
await this.remoteContainer.firstOpenProject(data.host, data.hostname, data.port, data.username, data.path, this.context)
|
||||||
break;
|
break;
|
||||||
case 'openRemoteFolder':
|
case 'openRemoteFolder':
|
||||||
this.remoteContainer.openRemoteFolder(data.host, data.port, data.username, data.path);
|
this.remoteContainer.openRemoteFolder(data.host, data.port, data.username, data.path);
|
||||||
|
10
src/main.ts
10
src/main.ts
@@ -26,14 +26,16 @@ export class DevStarExtension {
|
|||||||
if (uri.path === '/openProject') {
|
if (uri.path === '/openProject') {
|
||||||
const params = new URLSearchParams(uri.query);
|
const params = new URLSearchParams(uri.query);
|
||||||
const host = params.get('host');
|
const host = params.get('host');
|
||||||
|
const hostname = params.get('hostname');
|
||||||
const port = params.get('port');
|
const port = params.get('port');
|
||||||
const username = params.get('username');
|
const username = params.get('username');
|
||||||
const path = params.get('path');
|
const path = params.get('path');
|
||||||
const access_token = params.get('access_token');
|
const access_token = params.get('access_token');
|
||||||
const devstar_username = params.get('devstar_username');
|
const devstar_username = params.get('devstar_username');
|
||||||
|
|
||||||
if (host && port && username && path) {
|
if (host && hostname && port && username && path) {
|
||||||
const container_host = host;
|
const container_host = host;
|
||||||
|
const container_hostname = hostname
|
||||||
const container_port = parseInt(port, 10);
|
const container_port = parseInt(port, 10);
|
||||||
const container_username = username;
|
const container_username = username;
|
||||||
const project_path = decodeURIComponent(path);
|
const project_path = decodeURIComponent(path);
|
||||||
@@ -43,12 +45,12 @@ export class DevStarExtension {
|
|||||||
// 如果没有用户登录,则直接登录;
|
// 如果没有用户登录,则直接登录;
|
||||||
const res = await this.user.login(access_token, devstar_username)
|
const res = await this.user.login(access_token, devstar_username)
|
||||||
if (res === 'ok') {
|
if (res === 'ok') {
|
||||||
await this.remoteContainer.firstOpenProject(container_host, container_port, container_username, project_path, this.context)
|
await this.remoteContainer.firstOpenProject(container_host, container_hostname, container_port, container_username, project_path, this.context)
|
||||||
}
|
}
|
||||||
} else if (devstar_username === this.user.getUsernameFromLocal()) {
|
} else if (devstar_username === this.user.getUsernameFromLocal()) {
|
||||||
// 如果同用户已经登录,则忽略;
|
// 如果同用户已经登录,则忽略;
|
||||||
// 直接打开项目
|
// 直接打开项目
|
||||||
await this.remoteContainer.firstOpenProject(container_host, container_port, container_username, project_path, this.context)
|
await this.remoteContainer.firstOpenProject(container_host, container_hostname,container_port, container_username, project_path, this.context)
|
||||||
} else {
|
} else {
|
||||||
// 如果不是同用户,可以选择切换用户,或者不切换登录用户,直接打开容器
|
// 如果不是同用户,可以选择切换用户,或者不切换登录用户,直接打开容器
|
||||||
const selection = await vscode.window.showWarningMessage(`已登录用户:${this.user.getUsernameFromLocal()},是否切换用户?`,
|
const selection = await vscode.window.showWarningMessage(`已登录用户:${this.user.getUsernameFromLocal()},是否切换用户?`,
|
||||||
@@ -57,7 +59,7 @@ export class DevStarExtension {
|
|||||||
// 如果没有用户登录,则直接登录;
|
// 如果没有用户登录,则直接登录;
|
||||||
const res = await this.user.login(access_token, devstar_username)
|
const res = await this.user.login(access_token, devstar_username)
|
||||||
if (res === 'ok') {
|
if (res === 'ok') {
|
||||||
await this.remoteContainer.firstOpenProject(container_host, container_port, container_username, project_path, this.context)
|
await this.remoteContainer.firstOpenProject(container_host, container_hostname, container_port, container_username, project_path, this.context)
|
||||||
}
|
}
|
||||||
} else if (selection === 'No') {
|
} else if (selection === 'No') {
|
||||||
await openProjectWithoutLogging(container_host, container_port, container_username, project_path);
|
await openProjectWithoutLogging(container_host, container_port, container_username, project_path);
|
||||||
|
@@ -16,18 +16,36 @@ export default class RemoteContainer {
|
|||||||
this.user = user
|
this.user = user
|
||||||
}
|
}
|
||||||
|
|
||||||
async firstOpenProject(hostname: string, port: number, username: string, path: string, context: vscode.ExtensionContext) {
|
/**
|
||||||
await this.firstConnect(hostname, username, port, context)
|
* 第一次打开远程项目
|
||||||
|
* @param host 项目名称
|
||||||
|
* @param hostname ip
|
||||||
|
* @param port
|
||||||
|
* @param username
|
||||||
|
* @param path
|
||||||
|
* @param context 用于支持远程项目环境
|
||||||
|
*/
|
||||||
|
async firstOpenProject(host: string, hostname: string, port: number, username: string, path: string, context: vscode.ExtensionContext) {
|
||||||
|
await this.firstConnect(host, hostname, username, port, context)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
if (res === 'success') {
|
if (res === 'success') {
|
||||||
// only success then open folder
|
// only success then open folder
|
||||||
this.openRemoteFolder(hostname, port, username, path);
|
this.openRemoteFolder(host, port, username, path);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 本地/远程项目环境下,第一次连接其他项目
|
||||||
|
* @param host 项目名称
|
||||||
|
* @param hostname ip
|
||||||
|
* @param username
|
||||||
|
* @param port
|
||||||
|
* @param context 用于支持远程项目环境
|
||||||
|
* @returns 成功返回success
|
||||||
|
*/
|
||||||
// connect with key
|
// connect with key
|
||||||
async firstConnect(hostname: string, username: string, port: number, context: vscode.ExtensionContext): Promise<string> {
|
async firstConnect(host: string, hostname: string, username: string, port: number, context: vscode.ExtensionContext): Promise<string> {
|
||||||
return new Promise(async (resolve) => {
|
return new Promise(async (resolve) => {
|
||||||
const ssh = new NodeSSH();
|
const ssh = new NodeSSH();
|
||||||
vscode.window.withProgress({
|
vscode.window.withProgress({
|
||||||
@@ -87,11 +105,10 @@ export default class RemoteContainer {
|
|||||||
await ssh.dispose();
|
await ssh.dispose();
|
||||||
|
|
||||||
// ssh信息存储到ssh config file中
|
// ssh信息存储到ssh config file中
|
||||||
// 远程环境,利用global state中记录的localSystemName来决定执行的命令
|
// 远程项目环境,利用global state中记录的localSystemName来决定执行的命令
|
||||||
const localSystemName = utils.getLocalSystemName(context)
|
const localSystemName = utils.getLocalSystemName(context)
|
||||||
const localSSHConfigPath = utils.getLocalSSHConfigPath(context);
|
const localSSHConfigPath = utils.getLocalSSHConfigPath(context);
|
||||||
const privateKeyPath = this.user.getLocalUserPrivateKeyPath();
|
const privateKeyPath = this.user.getLocalUserPrivateKeyPath();
|
||||||
const host = `${hostname}-${port}` // host: hostname-port
|
|
||||||
const newSShConfigContent =
|
const newSShConfigContent =
|
||||||
`\nHost ${host}\n HostName ${hostname}\n Port ${port}\n User ${username}\n PreferredAuthentications publickey\n IdentityFile ${privateKeyPath}\n `;
|
`\nHost ${host}\n HostName ${hostname}\n Port ${port}\n User ${username}\n PreferredAuthentications publickey\n IdentityFile ${privateKeyPath}\n `;
|
||||||
let commandToAppend: string;
|
let commandToAppend: string;
|
||||||
@@ -164,7 +181,7 @@ export default class RemoteContainer {
|
|||||||
await ssh.dispose();
|
await ssh.dispose();
|
||||||
|
|
||||||
// only connect successfully then save the host info
|
// only connect successfully then save the host info
|
||||||
await this.storeHostInfo(hostname, port, username)
|
await this.storeProjectSSHInfo(host, hostname, port, username)
|
||||||
|
|
||||||
resolve('success')
|
resolve('success')
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@@ -176,7 +193,14 @@ export default class RemoteContainer {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async storeHostInfo(hostname: string, port: number, username: string): Promise<void> {
|
/**
|
||||||
|
* 本地环境,保存项目的ssh连接信息
|
||||||
|
* @param host
|
||||||
|
* @param hostname
|
||||||
|
* @param port
|
||||||
|
* @param username
|
||||||
|
*/
|
||||||
|
async storeProjectSSHInfo(host: string, hostname: string, port: number, username: string): Promise<void> {
|
||||||
const sshConfigPath = path.join(os.homedir(), '.ssh', 'config');
|
const sshConfigPath = path.join(os.homedir(), '.ssh', 'config');
|
||||||
// check if the host and related info exist in local ssh config file before saving
|
// check if the host and related info exist in local ssh config file before saving
|
||||||
var canAppendSSHConfig = true
|
var canAppendSSHConfig = true
|
||||||
@@ -184,8 +208,7 @@ export default class RemoteContainer {
|
|||||||
var reader = rd.createInterface(fs.createReadStream(sshConfigPath))
|
var reader = rd.createInterface(fs.createReadStream(sshConfigPath))
|
||||||
|
|
||||||
for await (const line of reader) {
|
for await (const line of reader) {
|
||||||
// host format: hostname-port
|
if (line.includes(`Host ${host}`)) {
|
||||||
if (line.includes(`Host ${hostname}-${port}`)) {
|
|
||||||
// the container ssh info exists
|
// the container ssh info exists
|
||||||
canAppendSSHConfig = false
|
canAppendSSHConfig = false
|
||||||
break;
|
break;
|
||||||
@@ -195,7 +218,6 @@ export default class RemoteContainer {
|
|||||||
|
|
||||||
if (canAppendSSHConfig) {
|
if (canAppendSSHConfig) {
|
||||||
// save the host to the local ssh config file
|
// save the host to the local ssh config file
|
||||||
const host = `${hostname}-${port}` // host: hostname-port
|
|
||||||
const privateKeyPath = this.user.getUserPrivateKeyPath();
|
const privateKeyPath = this.user.getUserPrivateKeyPath();
|
||||||
const newSShConfigContent =
|
const newSShConfigContent =
|
||||||
`\nHost ${host}\n HostName ${hostname}\n Port ${port}\n User ${username}\n PreferredAuthentications publickey\n IdentityFile ${privateKeyPath}\n `;
|
`\nHost ${host}\n HostName ${hostname}\n Port ${port}\n User ${username}\n PreferredAuthentications publickey\n IdentityFile ${privateKeyPath}\n `;
|
||||||
@@ -205,21 +227,24 @@ export default class RemoteContainer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
openRemoteFolder(hostname: string, port: number, username: string, path: string): void {
|
/**
|
||||||
|
* 仅支持已经成功连接,并在ssh config file中存储ssh信息的项目连接。
|
||||||
|
*
|
||||||
|
* @host 表示project name
|
||||||
|
*/
|
||||||
|
openRemoteFolder(host: string, port: number, username: string, path: string): void {
|
||||||
if (vscode.env.remoteName) {
|
if (vscode.env.remoteName) {
|
||||||
// 远程环境,打开local terminal
|
// 远程环境,打开local terminal
|
||||||
vscode.commands.executeCommand('workbench.action.terminal.newLocal').then(() => {
|
vscode.commands.executeCommand('workbench.action.terminal.newLocal').then(() => {
|
||||||
// 获取最后一个打开的终端实例
|
// 获取最后一个打开的终端实例
|
||||||
const terminal = vscode.window.terminals[vscode.window.terminals.length - 1];
|
const terminal = vscode.window.terminals[vscode.window.terminals.length - 1];
|
||||||
if (terminal) {
|
if (terminal) {
|
||||||
var host = `${hostname}-${port}`
|
|
||||||
// 在新窗口打开
|
// 在新窗口打开
|
||||||
terminal.sendText(`code --remote ssh-remote+${username}@${host}:${port} ${path} --new-window`)
|
terminal.sendText(`code --remote ssh-remote+${username}@${host}:${port} ${path} --new-window`)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
// 本地环境
|
// 本地环境
|
||||||
var host = `${hostname}-${port}`
|
|
||||||
let terminal = vscode.window.activeTerminal || vscode.window.createTerminal(`Ext Terminal`);
|
let terminal = vscode.window.activeTerminal || vscode.window.createTerminal(`Ext Terminal`);
|
||||||
terminal.show(true);
|
terminal.show(true);
|
||||||
// 在原窗口打开
|
// 在原窗口打开
|
||||||
@@ -229,8 +254,15 @@ export default class RemoteContainer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export async function openProjectWithoutLogging(host: string, port: number, username: string, path: string): Promise<void> {
|
/**
|
||||||
const command = `code --remote ssh-remote+${username}@${host}:${port} ${path} --reuse-window`
|
* 打开项目(无须插件登录)
|
||||||
|
* @param hostname 表示ip
|
||||||
|
* @param port
|
||||||
|
* @param username
|
||||||
|
* @param path
|
||||||
|
*/
|
||||||
|
export async function openProjectWithoutLogging(hostname: string, port: number, username: string, path: string): Promise<void> {
|
||||||
|
const command = `code --remote ssh-remote+${username}@${hostname}:${port} ${path} --reuse-window`
|
||||||
let terminal = vscode.window.activeTerminal || vscode.window.createTerminal(`Ext Terminal`);
|
let terminal = vscode.window.activeTerminal || vscode.window.createTerminal(`Ext Terminal`);
|
||||||
terminal.show(true);
|
terminal.show(true);
|
||||||
terminal.sendText(command);
|
terminal.sendText(command);
|
||||||
|
Reference in New Issue
Block a user