From 93d2caa6ca9c4520f43e89866428814700cab621 Mon Sep 17 00:00:00 2001 From: Sebastian Malton Date: Fri, 19 Nov 2021 15:43:06 -0500 Subject: [PATCH] Improve local shell CWD setting Signed-off-by: Sebastian Malton --- src/common/utils/paths.ts | 2 +- src/main/shell-session/shell-session.ts | 22 ++++-- .../components/cluster-home-dir-setting.tsx | 79 ++++++++++++++++++- .../components/path-picker/path-picker.tsx | 2 + 4 files changed, 97 insertions(+), 8 deletions(-) diff --git a/src/common/utils/paths.ts b/src/common/utils/paths.ts index 68d8f61ffa..86ada911e6 100644 --- a/src/common/utils/paths.ts +++ b/src/common/utils/paths.ts @@ -22,7 +22,7 @@ import path from "path"; import os from "os"; -function resolveTilde(filePath: string) { +export function resolveTilde(filePath: string) { if (filePath[0] === "~" && (filePath[1] === "/" || filePath.length === 1)) { return filePath.replace("~", os.homedir()); } diff --git a/src/main/shell-session/shell-session.ts b/src/main/shell-session/shell-session.ts index 0fb9b3ef11..523ab6176f 100644 --- a/src/main/shell-session/shell-session.ts +++ b/src/main/shell-session/shell-session.ts @@ -19,7 +19,6 @@ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -import fse from "fs-extra"; import type { Cluster } from "../cluster"; import { Kubectl } from "../kubectl"; import type WebSocket from "ws"; @@ -34,6 +33,7 @@ import { appEventBus } from "../../common/event-bus"; import logger from "../logger"; import { TerminalChannels, TerminalMessage } from "../../renderer/api/terminal-api"; import { deserialize, serialize } from "v8"; +import { stat } from "fs/promises"; export class ShellOpenError extends Error { constructor(message: string, public cause: Error) { @@ -178,10 +178,22 @@ export abstract class ShellSession { this.websocket.send(serialize(message)); } - protected async openShellProcess(shell: string, args: string[], env: Record) { - const cwd = (this.cwd && await fse.pathExists(this.cwd)) - ? this.cwd - : env.HOME; + protected async getCwd(env: Record): Promise { + if (this.cwd) { + try { + const stats = await stat(this.cwd); + + if (stats.isDirectory()) { + return this.cwd; + } + } catch {} + } + + return env.HOME; + } + + protected async openShellProcess(shell: string, args: string[], env: Record) { + const cwd = await this.getCwd(env); const { shellProcess, resume } = this.ensureShellProcess(shell, args, env, cwd); if (resume) { diff --git a/src/renderer/components/cluster-settings/components/cluster-home-dir-setting.tsx b/src/renderer/components/cluster-settings/components/cluster-home-dir-setting.tsx index 0af3238792..001793f662 100644 --- a/src/renderer/components/cluster-settings/components/cluster-home-dir-setting.tsx +++ b/src/renderer/components/cluster-settings/components/cluster-home-dir-setting.tsx @@ -25,6 +25,11 @@ import { observer, disposeOnUnmount } from "mobx-react"; import type { Cluster } from "../../../../main/cluster"; import { Input } from "../../input"; import { SubTitle } from "../../layout/sub-title"; +import { stat } from "fs/promises"; +import { Notifications } from "../../notifications"; +import { resolveTilde } from "../../../utils"; +import { Icon } from "../../icon"; +import { PathPicker } from "../../path-picker"; interface Props { cluster: Cluster; @@ -53,8 +58,45 @@ export class ClusterHomeDirSetting extends React.Component { ); } - saveCWD = () => { - this.props.cluster.preferences.terminalCWD = this.directory; + saveCWD = async () => { + if (!this.directory) { + this.props.cluster.preferences.terminalCWD = undefined; + + return; + } + + try { + const dir = resolveTilde(this.directory); + const stats = await stat(dir); + + if (stats.isDirectory()) { + this.props.cluster.preferences.terminalCWD = dir; + } else { + Notifications.error( + <> + Shell Working Directory +

Provided path is not a directory, your changes were not saved.

+ , + ); + } + } catch (error) { + if (error.code === "ENOENT") { + Notifications.error( + <> + Shell Working Directory +

Provided path does not exist, your changes were not saved.

+ , + ); + } else { + Notifications.error( + <> + Shell Working Directory +

Your changes were not saved due to the error bellow

+

{String(error)}

+ , + ); + } + } }; onChangeTerminalCWD = (value: string) => { @@ -73,6 +115,21 @@ export class ClusterHomeDirSetting extends React.Component { this.defaultNamespace = value; }; + openFilePicker = () => { + PathPicker.pick({ + label: "Choose Working Directory", + buttonLabel: "Pick", + properties: ["openDirectory", "showHiddenFiles"], + onPick: ([directory]) => { + this.props.cluster.preferences.terminalCWD = directory; + }, + }); + }; + + onClearCWD = () => { + this.props.cluster.preferences.terminalCWD = undefined; + }; + render() { return ( <> @@ -84,6 +141,24 @@ export class ClusterHomeDirSetting extends React.Component { onChange={this.onChangeTerminalCWD} onBlur={this.saveCWD} placeholder="$HOME" + iconRight={ + <> + { + this.directory && ( + + ) + } + + + } /> An explicit start path where the terminal will be launched,{" "} diff --git a/src/renderer/components/path-picker/path-picker.tsx b/src/renderer/components/path-picker/path-picker.tsx index 782b0e67d5..ba90306efb 100644 --- a/src/renderer/components/path-picker/path-picker.tsx +++ b/src/renderer/components/path-picker/path-picker.tsx @@ -51,6 +51,8 @@ export class PathPicker extends React.Component { ...dialogOptions, }); + console.log(filePaths); + if (canceled) { await onCancel?.(); } else {