From 7ef69d2ef1207f4cd9204b81316dbd35b0e07e5b Mon Sep 17 00:00:00 2001 From: Marwan Zaarab Date: Mon, 19 Feb 2024 14:06:06 -0600 Subject: [PATCH] Add status bar that displays the currently active stack --- zenml-studio/.eslintrc.json => .eslintrc.json | 0 zenml-studio/.gitignore => .gitignore | 8 --- .../.vscode-test.mjs => .vscode-test.mjs | 0 zenml-studio/.vscodeignore => .vscodeignore | 0 zenml-studio/CHANGELOG.md => CHANGELOG.md | 0 zenml-studio/package.json => package.json | 8 ++- src/commands/stackCommands.ts | 8 +++ src/extension.ts | 16 +++++ .../src => src}/test/extension.test.ts | 0 src/utils/shell.ts | 17 +++++ src/views/statusBar.ts | 56 +++++++++++++++ zenml-studio/tsconfig.json => tsconfig.json | 0 ...ickstart.md => vsc-extension-quickstart.md | 0 .../webpack.config.js => webpack.config.js | 0 zenml-studio/README.md | 71 ------------------- zenml-studio/src/extension.ts | 26 ------- 16 files changed, 102 insertions(+), 108 deletions(-) rename zenml-studio/.eslintrc.json => .eslintrc.json (100%) rename zenml-studio/.gitignore => .gitignore (84%) rename zenml-studio/.vscode-test.mjs => .vscode-test.mjs (100%) rename zenml-studio/.vscodeignore => .vscodeignore (100%) rename zenml-studio/CHANGELOG.md => CHANGELOG.md (100%) rename zenml-studio/package.json => package.json (88%) create mode 100644 src/commands/stackCommands.ts create mode 100644 src/extension.ts rename {zenml-studio/src => src}/test/extension.test.ts (100%) create mode 100644 src/utils/shell.ts create mode 100644 src/views/statusBar.ts rename zenml-studio/tsconfig.json => tsconfig.json (100%) rename zenml-studio/vsc-extension-quickstart.md => vsc-extension-quickstart.md (100%) rename zenml-studio/webpack.config.js => webpack.config.js (100%) delete mode 100644 zenml-studio/README.md delete mode 100644 zenml-studio/src/extension.ts diff --git a/zenml-studio/.eslintrc.json b/.eslintrc.json similarity index 100% rename from zenml-studio/.eslintrc.json rename to .eslintrc.json diff --git a/zenml-studio/.gitignore b/.gitignore similarity index 84% rename from zenml-studio/.gitignore rename to .gitignore index 4521ec64..1ba5d5cd 100644 --- a/zenml-studio/.gitignore +++ b/.gitignore @@ -5,16 +5,8 @@ Thumbs.db .sass-cache .eslintcache lib-cov -*.seed *.log -*.csv -*.dat -*.out -*.pid -*.gz pids -logs -results .vscode-test/ diff --git a/zenml-studio/.vscode-test.mjs b/.vscode-test.mjs similarity index 100% rename from zenml-studio/.vscode-test.mjs rename to .vscode-test.mjs diff --git a/zenml-studio/.vscodeignore b/.vscodeignore similarity index 100% rename from zenml-studio/.vscodeignore rename to .vscodeignore diff --git a/zenml-studio/CHANGELOG.md b/CHANGELOG.md similarity index 100% rename from zenml-studio/CHANGELOG.md rename to CHANGELOG.md diff --git a/zenml-studio/package.json b/package.json similarity index 88% rename from zenml-studio/package.json rename to package.json index ae2a431f..b13face7 100644 --- a/zenml-studio/package.json +++ b/package.json @@ -9,13 +9,15 @@ "categories": [ "Other" ], - "activationEvents": [], + "activationEvents": [ + "onStartupFinished" + ], "main": "./dist/extension.js", "contributes": { "commands": [ { - "command": "zenml-studio.helloWorld", - "title": "Hello World" + "command": "zenml.showActiveStack", + "title": "Show Active ZenML Stack" } ] }, diff --git a/src/commands/stackCommands.ts b/src/commands/stackCommands.ts new file mode 100644 index 00000000..4bfb5de9 --- /dev/null +++ b/src/commands/stackCommands.ts @@ -0,0 +1,8 @@ +import { execCLICommand } from '../utils/shell'; + +/** + * Fetches the current active stack using the ZenML CLI. + */ +export function getActiveStack(): Promise { + return execCLICommand('zenml stack get'); +} diff --git a/src/extension.ts b/src/extension.ts new file mode 100644 index 00000000..9887a0dc --- /dev/null +++ b/src/extension.ts @@ -0,0 +1,16 @@ +import * as vscode from 'vscode'; +import { ZenMLStatusBar } from './views/statusBar'; + +export function activate(context: vscode.ExtensionContext) { + console.log('ZenML Studio is now active!'); + + const zenMLStatusBar = ZenMLStatusBar.getInstance(); + + const refreshCommand = vscode.commands.registerCommand('zenml.showActiveStack', () => { + zenMLStatusBar.updateStatusBar(); + }); + + context.subscriptions.push(refreshCommand); +} + +export function deactivate() { } diff --git a/zenml-studio/src/test/extension.test.ts b/src/test/extension.test.ts similarity index 100% rename from zenml-studio/src/test/extension.test.ts rename to src/test/extension.test.ts diff --git a/src/utils/shell.ts b/src/utils/shell.ts new file mode 100644 index 00000000..a040f99e --- /dev/null +++ b/src/utils/shell.ts @@ -0,0 +1,17 @@ +import { exec } from 'child_process'; + +/** + * Executes a CLI command and returns a promise that resolves with the command's stdout. + */ +export function execCLICommand(command: string): Promise { + return new Promise((resolve, reject) => { + + exec(command, (error, stdout, stderr) => { + if (error) { + reject(error); + return; + } + resolve(stdout.trim()); + }); + }); +} diff --git a/src/views/statusBar.ts b/src/views/statusBar.ts new file mode 100644 index 00000000..fbc5e179 --- /dev/null +++ b/src/views/statusBar.ts @@ -0,0 +1,56 @@ +import * as vscode from 'vscode'; +import { getActiveStack } from '../commands/stackCommands'; + +export class ZenMLStatusBar { + private static instance: ZenMLStatusBar; + private statusBar: vscode.StatusBarItem; + private constructor() { + this.statusBar = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Right, 100); + this.statusBar.command = 'zenml.showActiveStack'; + this.updateStatusBar(); + } + + public static getInstance(): ZenMLStatusBar { + if (!ZenMLStatusBar.instance) { + ZenMLStatusBar.instance = new ZenMLStatusBar(); + // ZenMLStatusBar.instance.startAutoRefresh(); + } + return ZenMLStatusBar.instance; + } + + // public startAutoRefresh() { + // const interval = 30000; + // setInterval(() => { + // this.updateStatusBar(); + // }, interval); + // } + + public show() { + this.statusBar.show(); + } + + public hide() { + this.statusBar.hide(); + } + + public updateStatusBar() { + console.log('Updating ZenML active stack...'); + + getActiveStack().then((fullActiveStackText) => { + /** + * The cli command `zenml stack get` outputs the line below: + * The global active stack is: 'default' + * 'default' is the actual string we want to display in the status bar. + */ + const match = fullActiveStackText.match(/'([^']+)'/); // matches text within single quotes + const activeStack = match ? match[1] : 'Error parsing stack name'; + this.statusBar.text = `Active Stack: ${activeStack}`; + this.statusBar.tooltip = 'Click to refresh the active ZenML stack'; + this.show(); + }).catch((error) => { + console.error('Failed to fetch active ZenML stack:', error); + this.statusBar.text = `Active Stack: Error`; + this.show(); + }); + } +} diff --git a/zenml-studio/tsconfig.json b/tsconfig.json similarity index 100% rename from zenml-studio/tsconfig.json rename to tsconfig.json diff --git a/zenml-studio/vsc-extension-quickstart.md b/vsc-extension-quickstart.md similarity index 100% rename from zenml-studio/vsc-extension-quickstart.md rename to vsc-extension-quickstart.md diff --git a/zenml-studio/webpack.config.js b/webpack.config.js similarity index 100% rename from zenml-studio/webpack.config.js rename to webpack.config.js diff --git a/zenml-studio/README.md b/zenml-studio/README.md deleted file mode 100644 index 2a6e90f7..00000000 --- a/zenml-studio/README.md +++ /dev/null @@ -1,71 +0,0 @@ -# zenml-studio README - -This is the README for your extension "zenml-studio". After writing up a brief description, we recommend including the following sections. - -## Features - -Describe specific features of your extension including screenshots of your extension in action. Image paths are relative to this README file. - -For example if there is an image subfolder under your extension project workspace: - -\!\[feature X\]\(images/feature-x.png\) - -> Tip: Many popular extensions utilize animations. This is an excellent way to show off your extension! We recommend short, focused animations that are easy to follow. - -## Requirements - -If you have any requirements or dependencies, add a section describing those and how to install and configure them. - -## Extension Settings - -Include if your extension adds any VS Code settings through the `contributes.configuration` extension point. - -For example: - -This extension contributes the following settings: - -* `myExtension.enable`: Enable/disable this extension. -* `myExtension.thing`: Set to `blah` to do something. - -## Known Issues - -Calling out known issues can help limit users opening duplicate issues against your extension. - -## Release Notes - -Users appreciate release notes as you update your extension. - -### 1.0.0 - -Initial release of ... - -### 1.0.1 - -Fixed issue #. - -### 1.1.0 - -Added features X, Y, and Z. - ---- - -## Following extension guidelines - -Ensure that you've read through the extensions guidelines and follow the best practices for creating your extension. - -* [Extension Guidelines](https://code.visualstudio.com/api/references/extension-guidelines) - -## Working with Markdown - -You can author your README using Visual Studio Code. Here are some useful editor keyboard shortcuts: - -* Split the editor (`Cmd+\` on macOS or `Ctrl+\` on Windows and Linux). -* Toggle preview (`Shift+Cmd+V` on macOS or `Shift+Ctrl+V` on Windows and Linux). -* Press `Ctrl+Space` (Windows, Linux, macOS) to see a list of Markdown snippets. - -## For more information - -* [Visual Studio Code's Markdown Support](http://code.visualstudio.com/docs/languages/markdown) -* [Markdown Syntax Reference](https://help.github.com/articles/markdown-basics/) - -**Enjoy!** diff --git a/zenml-studio/src/extension.ts b/zenml-studio/src/extension.ts deleted file mode 100644 index baf70730..00000000 --- a/zenml-studio/src/extension.ts +++ /dev/null @@ -1,26 +0,0 @@ -// The module 'vscode' contains the VS Code extensibility API -// Import the module and reference it with the alias vscode in your code below -import * as vscode from 'vscode'; - -// This method is called when your extension is activated -// Your extension is activated the very first time the command is executed -export function activate(context: vscode.ExtensionContext) { - - // Use the console to output diagnostic information (console.log) and errors (console.error) - // This line of code will only be executed once when your extension is activated - console.log('Congratulations, your extension "zenml-studio" is now active!'); - - // The command has been defined in the package.json file - // Now provide the implementation of the command with registerCommand - // The commandId parameter must match the command field in package.json - let disposable = vscode.commands.registerCommand('zenml-studio.helloWorld', () => { - // The code you place here will be executed every time your command is executed - // Display a message box to the user - vscode.window.showInformationMessage('Hello World from ZenML Studio!'); - }); - - context.subscriptions.push(disposable); -} - -// This method is called when your extension is deactivated -export function deactivate() {}