From c2e800a2024d046a8ae265e616c351bafcc40a88 Mon Sep 17 00:00:00 2001 From: Tatsat Mishra Date: Wed, 4 Dec 2024 20:39:53 +1300 Subject: [PATCH 1/8] Initial commit to demo command hook only. --- package.json | 12 ++++++++++++ src/extension.ts | 2 +- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index c3fc2a820..b4a5878ec 100644 --- a/package.json +++ b/package.json @@ -319,6 +319,10 @@ { "command": "aks.aksKaito", "title": "Install KAITO" + }, + { + "command": "aks.runDraftValidateYamlCommand", + "title": "Run Draft Validate for YAML" } ], "menus": { @@ -348,6 +352,14 @@ { "command": "aks.draftDeployment", "when": "explorerResourceIsFolder" + }, + { + "command": "aks.runDraftValidateYamlCommand", + "when": "resourceExtname == .yaml || resourceExtname == .yml" + }, + { + "command": "aks.runDraftValidateYamlCommand", + "when": "explorerResourceIsFolder" } ], "view/item/context": [ diff --git a/src/extension.ts b/src/extension.ts index ea55e7d43..0b4e107fc 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -70,7 +70,6 @@ export async function activate(context: vscode.ExtensionContext) { outputChannel: createAzExtOutputChannel("Azure Identity", ""), prefix: "", }; - context.subscriptions.push(uiExtensionVariables.outputChannel); registerUIExtensionVariables(uiExtensionVariables); @@ -114,6 +113,7 @@ export async function activate(context: vscode.ExtensionContext) { registerCommandWithTelemetry("aks.aksDeployManifest", aksDeployManifest); registerCommandWithTelemetry("aks.aksOpenKubectlPanel", aksOpenKubectlPanel); registerCommandWithTelemetry("aks.getAzureKubernetesServicePlugins", getPlugins); + registerCommandWithTelemetry("aks.runDraftValidateYamlCommand", aksCreateCluster); await registerAzureServiceNodes(context); From 13048d544ae4114d1f8ffa069d7fd20e2442d88b Mon Sep 17 00:00:00 2001 From: Tatsat Mishra Date: Thu, 5 Dec 2024 09:08:58 +1300 Subject: [PATCH 2/8] Draft pannel connection with the Draft validate command. --- src/commands/draft/draftCommands.ts | 18 +++ src/extension.ts | 4 +- src/panels/draft/DraftDockerfilePanel.ts | 18 +++ src/panels/draft/DraftValidatePanel.ts | 151 +++++++++++++++++++++++ 4 files changed, 189 insertions(+), 2 deletions(-) create mode 100644 src/panels/draft/DraftValidatePanel.ts diff --git a/src/commands/draft/draftCommands.ts b/src/commands/draft/draftCommands.ts index 4a29d49ab..3046d601c 100644 --- a/src/commands/draft/draftCommands.ts +++ b/src/commands/draft/draftCommands.ts @@ -10,6 +10,7 @@ import { FileType, } from "vscode"; import { DraftDockerfileDataProvider, DraftDockerfilePanel } from "../../panels/draft/DraftDockerfilePanel"; +import { DraftDockerfileDataProvider1, DraftDockerfilePanel1 } from "../../panels/draft/DraftValidatePanel"; import { getExtension } from "../utils/host"; import { Errorable, failed, getErrorMessage, succeeded } from "../utils/errorable"; import { getDraftBinaryPath } from "../utils/helper/draftBinaryDownload"; @@ -169,6 +170,23 @@ export async function draftWorkflow(_context: IActionContext, target: unknown): panel.show(dataProvider); } +export async function aksDraftValidate(_context: IActionContext, target: unknown): Promise { + const params = getDraftDockerfileParams(target); + const commonDependencies = await getCommonDraftDependencies(params?.workspaceFolder); + if (commonDependencies === null) { + return; + } + + const { workspaceFolder, extension, draftBinaryPath } = commonDependencies; + const panel = new DraftDockerfilePanel1(extension.extensionUri); + const dataProvider = new DraftDockerfileDataProvider1( + workspaceFolder, + draftBinaryPath, + params?.initialLocation || "", + ); + panel.show(dataProvider); +} + async function getCommonDraftDependencies( suppliedWorkspaceFolder?: WorkspaceFolder, ): Promise { diff --git a/src/extension.ts b/src/extension.ts index 0b4e107fc..e153708aa 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -38,7 +38,7 @@ import { aksNodeHealth, aksStorageDiagnostics, } from "./commands/detectors/detectors"; -import { draftDeployment, draftDockerfile, draftWorkflow } from "./commands/draft/draftCommands"; +import { aksDraftValidate, draftDeployment, draftDockerfile, draftWorkflow } from "./commands/draft/draftCommands"; import periscope from "./commands/periscope/periscope"; import refreshSubscription from "./commands/refreshSubscriptions"; import { getKubeconfigYaml, getManagedCluster } from "./commands/utils/clusters"; @@ -113,7 +113,7 @@ export async function activate(context: vscode.ExtensionContext) { registerCommandWithTelemetry("aks.aksDeployManifest", aksDeployManifest); registerCommandWithTelemetry("aks.aksOpenKubectlPanel", aksOpenKubectlPanel); registerCommandWithTelemetry("aks.getAzureKubernetesServicePlugins", getPlugins); - registerCommandWithTelemetry("aks.runDraftValidateYamlCommand", aksCreateCluster); + registerCommandWithTelemetry("aks.runDraftValidateYamlCommand", aksDraftValidate); await registerAzureServiceNodes(context); diff --git a/src/panels/draft/DraftDockerfilePanel.ts b/src/panels/draft/DraftDockerfilePanel.ts index e7c8177a5..d55f13608 100644 --- a/src/panels/draft/DraftDockerfilePanel.ts +++ b/src/panels/draft/DraftDockerfilePanel.ts @@ -158,6 +158,24 @@ export class DraftDockerfileDataProvider implements PanelDataProvider<"draftDock webview.postCreateDockerfileResponse(existingFiles); } + async handleDraftValidateRequest(location: string, webview: MessageSink) { + const command = `draft validate --manifest .${path.sep}${location}`; + + const execOptions: ShellOptions = { + workingDir: this.workspaceFolder.uri.fsPath, + envPaths: [this.draftDirectory], + }; + + const draftResult = await exec(command, execOptions); + if (failed(draftResult)) { + window.showErrorMessage(draftResult.error); + return; + } + + const existingFiles = getExistingFiles(this.workspaceFolder, location); + webview.postCreateDockerfileResponse(existingFiles); + } + private handleOpenFileRequest(relativeFilePath: string) { const filePath = path.join(this.workspaceFolder.uri.fsPath, relativeFilePath); window.showTextDocument(Uri.file(filePath)); diff --git a/src/panels/draft/DraftValidatePanel.ts b/src/panels/draft/DraftValidatePanel.ts new file mode 100644 index 000000000..695654348 --- /dev/null +++ b/src/panels/draft/DraftValidatePanel.ts @@ -0,0 +1,151 @@ +import { Uri, WorkspaceFolder, window } from "vscode"; +import path from "path"; +import * as fs from "fs"; +import { BasePanel, PanelDataProvider } from "../BasePanel"; +import { + ExistingFiles, + InitialState, + ToVsCodeMsgDef, + ToWebViewMsgDef, +} from "../../webview-contract/webviewDefinitions/draft/draftDockerfile"; +import { TelemetryDefinition } from "../../webview-contract/webviewTypes"; +import { MessageHandler, MessageSink } from "../../webview-contract/messaging"; +import { ShellOptions, exec } from "../../commands/utils/shell"; +import { failed } from "../../commands/utils/errorable"; +import { OpenFileOptions } from "../../webview-contract/webviewDefinitions/shared/fileSystemTypes"; +import { launchDraftCommand } from "./commandUtils"; +import { getLanguageVersionInfo, getSupportedLanguages } from "../../commands/draft/languages"; + +export class DraftDockerfilePanel1 extends BasePanel<"draftDockerfile"> { + constructor(extensionUri: Uri) { + super(extensionUri, "draftDockerfile", { + pickLocationResponse: null, + getLanguageVersionInfoResponse: null, + createDockerfileResponse: null, + }); + } +} + +export class DraftDockerfileDataProvider1 implements PanelDataProvider<"draftDockerfile"> { + readonly draftDirectory: string; + constructor( + readonly workspaceFolder: WorkspaceFolder, + readonly draftBinaryPath: string, + readonly initialLocation: string, + ) { + this.draftDirectory = path.dirname(draftBinaryPath); + } + + getTitle(): string { + return `Draft Dockerfile in ${this.workspaceFolder.name}`; + } + + getInitialState(): InitialState { + return { + workspaceConfig: { + name: this.workspaceFolder.name, + fullPath: this.workspaceFolder.uri.fsPath, + pathSeparator: path.sep, + }, + location: this.initialLocation, + supportedLanguages: getSupportedLanguages(), + existingFiles: getExistingFiles(this.workspaceFolder, this.initialLocation), + }; + } + + getTelemetryDefinition(): TelemetryDefinition<"draftDockerfile"> { + return { + createDockerfileRequest: true, + getLanguageVersionInfoRequest: false, + openFileRequest: false, + pickLocationRequest: false, + launchDraftDeployment: false, + launchDraftWorkflow: false, + }; + } + + getMessageHandler(webview: MessageSink): MessageHandler { + return { + pickLocationRequest: (openFileOptions) => this.handlePickLocationRequest(openFileOptions, webview), + getLanguageVersionInfoRequest: (args) => + this.handleGetLanguageVersionInfoRequest(args.language, args.version, webview), + createDockerfileRequest: (args) => this.handleDraftValidateRequest(args.location, webview), + openFileRequest: (filePath) => this.handleOpenFileRequest(filePath), + launchDraftDeployment: (args) => + launchDraftCommand("aks.draftDeployment", { + workspaceFolder: this.workspaceFolder, + initialLocation: args.initialLocation, + initialSelection: { + targetPort: args.initialTargetPort || undefined, + }, + }), + launchDraftWorkflow: (args) => + launchDraftCommand("aks.draftWorkflow", { + workspaceFolder: this.workspaceFolder, + initialSelection: { + dockerfilePath: path.join(args.initialDockerfileLocation, "Dockerfile"), + dockerfileBuildContextPath: args.initialDockerfileLocation, + }, + }), + }; + } + + private async handlePickLocationRequest(openFileOptions: OpenFileOptions, webview: MessageSink) { + const result = await window.showOpenDialog({ + canSelectFiles: openFileOptions.type === "file", + canSelectFolders: openFileOptions.type === "directory", + canSelectMany: false, + defaultUri: openFileOptions.defaultPath ? Uri.file(openFileOptions.defaultPath) : undefined, + }); + + if (!result || result.length === 0) return; + + const location = path.relative(this.workspaceFolder.uri.fsPath, result[0].fsPath); + webview.postPickLocationResponse({ + location, + existingFiles: getExistingFiles(this.workspaceFolder, location), + }); + } + + private handleGetLanguageVersionInfoRequest( + language: string, + version: string, + webview: MessageSink, + ) { + const versionInfo = getLanguageVersionInfo(language, version); + webview.postGetLanguageVersionInfoResponse({ language, versionInfo }); + } + + private async handleDraftValidateRequest(location: string, webview: MessageSink) { + const command = `draft validate --manifest .${path.sep}${location}`; + + const execOptions: ShellOptions = { + workingDir: this.workspaceFolder.uri.fsPath, + envPaths: [this.draftDirectory], + }; + + const draftResult = await exec(command, execOptions); + if (failed(draftResult)) { + window.showErrorMessage(draftResult.error); + return; + } + + const existingFiles = getExistingFiles(this.workspaceFolder, location); + webview.postCreateDockerfileResponse(existingFiles); + } + + private handleOpenFileRequest(relativeFilePath: string) { + const filePath = path.join(this.workspaceFolder.uri.fsPath, relativeFilePath); + window.showTextDocument(Uri.file(filePath)); + } +} + +function getExistingFiles(workspaceFolder: WorkspaceFolder, location: string): ExistingFiles { + const locationFullPath = path.join(workspaceFolder.uri.fsPath, location); + const dockerfilePath = path.join(locationFullPath, "Dockerfile"); + const dockerignorePath = path.join(locationFullPath, ".dockerignore"); + const existingFiles = [dockerfilePath, dockerignorePath] + .filter((p) => fs.existsSync(p)) + .map((p) => path.relative(workspaceFolder.uri.fsPath, p)); + return existingFiles; +} From 749075877b91013fe3a0b425e9420ac2046cb5d7 Mon Sep 17 00:00:00 2001 From: Reinier Cruz Date: Wed, 11 Dec 2024 15:29:02 -0500 Subject: [PATCH 3/8] Inital working version --- package.json | 6 +- src/commands/draft/draftCommands.ts | 12 +- src/commands/draft/types.ts | 4 + src/extension.ts | 4 +- src/panels/draft/DraftDockerfilePanel.ts | 18 --- src/panels/draft/DraftValidatePanel.ts | 108 +++--------------- .../webviewDefinitions/draft/draftValidate.ts | 19 +++ src/webview-contract/webviewTypes.ts | 2 + .../src/Draft/DraftValidate/DraftValidate.tsx | 20 ++++ webview-ui/src/Draft/DraftValidate/state.ts | 37 ++++++ webview-ui/src/Draft/index.ts | 3 +- webview-ui/src/main.tsx | 3 +- webview-ui/src/manualTest/main.tsx | 1 + 13 files changed, 111 insertions(+), 126 deletions(-) create mode 100644 src/webview-contract/webviewDefinitions/draft/draftValidate.ts create mode 100644 webview-ui/src/Draft/DraftValidate/DraftValidate.tsx create mode 100644 webview-ui/src/Draft/DraftValidate/state.ts diff --git a/package.json b/package.json index b4a5878ec..32735d30f 100644 --- a/package.json +++ b/package.json @@ -321,7 +321,7 @@ "title": "Install KAITO" }, { - "command": "aks.runDraftValidateYamlCommand", + "command": "aks.aksDraftValidate", "title": "Run Draft Validate for YAML" } ], @@ -354,11 +354,11 @@ "when": "explorerResourceIsFolder" }, { - "command": "aks.runDraftValidateYamlCommand", + "command": "aks.aksDraftValidate", "when": "resourceExtname == .yaml || resourceExtname == .yml" }, { - "command": "aks.runDraftValidateYamlCommand", + "command": "aks.aksDraftValidate", "when": "explorerResourceIsFolder" } ], diff --git a/src/commands/draft/draftCommands.ts b/src/commands/draft/draftCommands.ts index 3046d601c..c56d56e68 100644 --- a/src/commands/draft/draftCommands.ts +++ b/src/commands/draft/draftCommands.ts @@ -10,7 +10,7 @@ import { FileType, } from "vscode"; import { DraftDockerfileDataProvider, DraftDockerfilePanel } from "../../panels/draft/DraftDockerfilePanel"; -import { DraftDockerfileDataProvider1, DraftDockerfilePanel1 } from "../../panels/draft/DraftValidatePanel"; +import { DraftValidateDataProvider, DraftValidatePanel } from "../../panels/draft/DraftValidatePanel"; import { getExtension } from "../utils/host"; import { Errorable, failed, getErrorMessage, succeeded } from "../utils/errorable"; import { getDraftBinaryPath } from "../utils/helper/draftBinaryDownload"; @@ -170,7 +170,7 @@ export async function draftWorkflow(_context: IActionContext, target: unknown): panel.show(dataProvider); } -export async function aksDraftValidate(_context: IActionContext, target: unknown): Promise { +export async function draftValidate(_context: IActionContext, target: unknown): Promise { const params = getDraftDockerfileParams(target); const commonDependencies = await getCommonDraftDependencies(params?.workspaceFolder); if (commonDependencies === null) { @@ -178,12 +178,8 @@ export async function aksDraftValidate(_context: IActionContext, target: unknown } const { workspaceFolder, extension, draftBinaryPath } = commonDependencies; - const panel = new DraftDockerfilePanel1(extension.extensionUri); - const dataProvider = new DraftDockerfileDataProvider1( - workspaceFolder, - draftBinaryPath, - params?.initialLocation || "", - ); + const panel = new DraftValidatePanel(extension.extensionUri); + const dataProvider = new DraftValidateDataProvider(workspaceFolder, draftBinaryPath, params?.initialLocation || ""); panel.show(dataProvider); } diff --git a/src/commands/draft/types.ts b/src/commands/draft/types.ts index 4c1e54787..10ec25f5b 100644 --- a/src/commands/draft/types.ts +++ b/src/commands/draft/types.ts @@ -16,6 +16,10 @@ export type DraftCommandParamsTypes = { workspaceFolder?: WorkspaceFolder; initialSelection?: WorkflowInitialSelection; }; + "aks.draftValidate": { + workspaceFolder?: WorkspaceFolder; + initialLocation?: string; + }; }; export type DraftCommandName = keyof DraftCommandParamsTypes; diff --git a/src/extension.ts b/src/extension.ts index e153708aa..c4e77edc2 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -38,7 +38,7 @@ import { aksNodeHealth, aksStorageDiagnostics, } from "./commands/detectors/detectors"; -import { aksDraftValidate, draftDeployment, draftDockerfile, draftWorkflow } from "./commands/draft/draftCommands"; +import { draftValidate, draftDeployment, draftDockerfile, draftWorkflow } from "./commands/draft/draftCommands"; import periscope from "./commands/periscope/periscope"; import refreshSubscription from "./commands/refreshSubscriptions"; import { getKubeconfigYaml, getManagedCluster } from "./commands/utils/clusters"; @@ -113,7 +113,7 @@ export async function activate(context: vscode.ExtensionContext) { registerCommandWithTelemetry("aks.aksDeployManifest", aksDeployManifest); registerCommandWithTelemetry("aks.aksOpenKubectlPanel", aksOpenKubectlPanel); registerCommandWithTelemetry("aks.getAzureKubernetesServicePlugins", getPlugins); - registerCommandWithTelemetry("aks.runDraftValidateYamlCommand", aksDraftValidate); + registerCommandWithTelemetry("aks.aksDraftValidate", draftValidate); await registerAzureServiceNodes(context); diff --git a/src/panels/draft/DraftDockerfilePanel.ts b/src/panels/draft/DraftDockerfilePanel.ts index d55f13608..e7c8177a5 100644 --- a/src/panels/draft/DraftDockerfilePanel.ts +++ b/src/panels/draft/DraftDockerfilePanel.ts @@ -158,24 +158,6 @@ export class DraftDockerfileDataProvider implements PanelDataProvider<"draftDock webview.postCreateDockerfileResponse(existingFiles); } - async handleDraftValidateRequest(location: string, webview: MessageSink) { - const command = `draft validate --manifest .${path.sep}${location}`; - - const execOptions: ShellOptions = { - workingDir: this.workspaceFolder.uri.fsPath, - envPaths: [this.draftDirectory], - }; - - const draftResult = await exec(command, execOptions); - if (failed(draftResult)) { - window.showErrorMessage(draftResult.error); - return; - } - - const existingFiles = getExistingFiles(this.workspaceFolder, location); - webview.postCreateDockerfileResponse(existingFiles); - } - private handleOpenFileRequest(relativeFilePath: string) { const filePath = path.join(this.workspaceFolder.uri.fsPath, relativeFilePath); window.showTextDocument(Uri.file(filePath)); diff --git a/src/panels/draft/DraftValidatePanel.ts b/src/panels/draft/DraftValidatePanel.ts index 695654348..ddfb0562d 100644 --- a/src/panels/draft/DraftValidatePanel.ts +++ b/src/panels/draft/DraftValidatePanel.ts @@ -1,32 +1,25 @@ import { Uri, WorkspaceFolder, window } from "vscode"; import path from "path"; -import * as fs from "fs"; import { BasePanel, PanelDataProvider } from "../BasePanel"; import { - ExistingFiles, InitialState, ToVsCodeMsgDef, ToWebViewMsgDef, -} from "../../webview-contract/webviewDefinitions/draft/draftDockerfile"; +} from "../../webview-contract/webviewDefinitions/draft/draftValidate"; import { TelemetryDefinition } from "../../webview-contract/webviewTypes"; import { MessageHandler, MessageSink } from "../../webview-contract/messaging"; import { ShellOptions, exec } from "../../commands/utils/shell"; import { failed } from "../../commands/utils/errorable"; -import { OpenFileOptions } from "../../webview-contract/webviewDefinitions/shared/fileSystemTypes"; -import { launchDraftCommand } from "./commandUtils"; -import { getLanguageVersionInfo, getSupportedLanguages } from "../../commands/draft/languages"; -export class DraftDockerfilePanel1 extends BasePanel<"draftDockerfile"> { +export class DraftValidatePanel extends BasePanel<"draftValidate"> { constructor(extensionUri: Uri) { - super(extensionUri, "draftDockerfile", { - pickLocationResponse: null, - getLanguageVersionInfoResponse: null, - createDockerfileResponse: null, + super(extensionUri, "draftValidate", { + validationResult: undefined, }); } } -export class DraftDockerfileDataProvider1 implements PanelDataProvider<"draftDockerfile"> { +export class DraftValidateDataProvider implements PanelDataProvider<"draftValidate"> { readonly draftDirectory: string; constructor( readonly workspaceFolder: WorkspaceFolder, @@ -37,87 +30,30 @@ export class DraftDockerfileDataProvider1 implements PanelDataProvider<"draftDoc } getTitle(): string { - return `Draft Dockerfile in ${this.workspaceFolder.name}`; + return `Draft Validate`; } getInitialState(): InitialState { return { - workspaceConfig: { - name: this.workspaceFolder.name, - fullPath: this.workspaceFolder.uri.fsPath, - pathSeparator: path.sep, - }, - location: this.initialLocation, - supportedLanguages: getSupportedLanguages(), - existingFiles: getExistingFiles(this.workspaceFolder, this.initialLocation), + validationResults: "Initializing validation...", }; } - getTelemetryDefinition(): TelemetryDefinition<"draftDockerfile"> { + getTelemetryDefinition(): TelemetryDefinition<"draftValidate"> { return { - createDockerfileRequest: true, - getLanguageVersionInfoRequest: false, - openFileRequest: false, - pickLocationRequest: false, - launchDraftDeployment: false, - launchDraftWorkflow: false, + createDraftValidateRequest: false, }; } + //Messages from Webview to Vscode getMessageHandler(webview: MessageSink): MessageHandler { return { - pickLocationRequest: (openFileOptions) => this.handlePickLocationRequest(openFileOptions, webview), - getLanguageVersionInfoRequest: (args) => - this.handleGetLanguageVersionInfoRequest(args.language, args.version, webview), - createDockerfileRequest: (args) => this.handleDraftValidateRequest(args.location, webview), - openFileRequest: (filePath) => this.handleOpenFileRequest(filePath), - launchDraftDeployment: (args) => - launchDraftCommand("aks.draftDeployment", { - workspaceFolder: this.workspaceFolder, - initialLocation: args.initialLocation, - initialSelection: { - targetPort: args.initialTargetPort || undefined, - }, - }), - launchDraftWorkflow: (args) => - launchDraftCommand("aks.draftWorkflow", { - workspaceFolder: this.workspaceFolder, - initialSelection: { - dockerfilePath: path.join(args.initialDockerfileLocation, "Dockerfile"), - dockerfileBuildContextPath: args.initialDockerfileLocation, - }, - }), + createDraftValidateRequest: () => this.handleDraftValidateRequest(webview), }; } - private async handlePickLocationRequest(openFileOptions: OpenFileOptions, webview: MessageSink) { - const result = await window.showOpenDialog({ - canSelectFiles: openFileOptions.type === "file", - canSelectFolders: openFileOptions.type === "directory", - canSelectMany: false, - defaultUri: openFileOptions.defaultPath ? Uri.file(openFileOptions.defaultPath) : undefined, - }); - - if (!result || result.length === 0) return; - - const location = path.relative(this.workspaceFolder.uri.fsPath, result[0].fsPath); - webview.postPickLocationResponse({ - location, - existingFiles: getExistingFiles(this.workspaceFolder, location), - }); - } - - private handleGetLanguageVersionInfoRequest( - language: string, - version: string, - webview: MessageSink, - ) { - const versionInfo = getLanguageVersionInfo(language, version); - webview.postGetLanguageVersionInfoResponse({ language, versionInfo }); - } - - private async handleDraftValidateRequest(location: string, webview: MessageSink) { - const command = `draft validate --manifest .${path.sep}${location}`; + private async handleDraftValidateRequest(webview: MessageSink) { + const command = `draft validate --manifest .${path.sep}${this.initialLocation}`; const execOptions: ShellOptions = { workingDir: this.workspaceFolder.uri.fsPath, @@ -130,22 +66,8 @@ export class DraftDockerfileDataProvider1 implements PanelDataProvider<"draftDoc return; } - const existingFiles = getExistingFiles(this.workspaceFolder, location); - webview.postCreateDockerfileResponse(existingFiles); - } + const validationResults = draftResult.result.stdout; - private handleOpenFileRequest(relativeFilePath: string) { - const filePath = path.join(this.workspaceFolder.uri.fsPath, relativeFilePath); - window.showTextDocument(Uri.file(filePath)); + webview.postValidationResult({ result: validationResults }); } } - -function getExistingFiles(workspaceFolder: WorkspaceFolder, location: string): ExistingFiles { - const locationFullPath = path.join(workspaceFolder.uri.fsPath, location); - const dockerfilePath = path.join(locationFullPath, "Dockerfile"); - const dockerignorePath = path.join(locationFullPath, ".dockerignore"); - const existingFiles = [dockerfilePath, dockerignorePath] - .filter((p) => fs.existsSync(p)) - .map((p) => path.relative(workspaceFolder.uri.fsPath, p)); - return existingFiles; -} diff --git a/src/webview-contract/webviewDefinitions/draft/draftValidate.ts b/src/webview-contract/webviewDefinitions/draft/draftValidate.ts new file mode 100644 index 000000000..5a0a82848 --- /dev/null +++ b/src/webview-contract/webviewDefinitions/draft/draftValidate.ts @@ -0,0 +1,19 @@ +import { WebviewDefinition } from "../../webviewTypes"; + +export interface InitialState { + validationResults: string; +} + +export type ExistingFiles = string[]; + +export type ToVsCodeMsgDef = { + createDraftValidateRequest: string; +}; + +export type ToWebViewMsgDef = { + validationResult: { result: string }; +}; + +export type DraftValidateDefinition = WebviewDefinition; + +//TODO FINISH REPLACING UNUSED CODE diff --git a/src/webview-contract/webviewTypes.ts b/src/webview-contract/webviewTypes.ts index ca2759d84..9a2973615 100644 --- a/src/webview-contract/webviewTypes.ts +++ b/src/webview-contract/webviewTypes.ts @@ -7,6 +7,7 @@ import { DetectorDefinition } from "./webviewDefinitions/detector"; import { DraftDeploymentDefinition } from "./webviewDefinitions/draft/draftDeployment"; import { DraftDockerfileDefinition } from "./webviewDefinitions/draft/draftDockerfile"; import { DraftWorkflowDefinition } from "./webviewDefinitions/draft/draftWorkflow"; +import { DraftValidateDefinition } from "./webviewDefinitions/draft/draftValidate"; import { InspektorGadgetDefinition } from "./webviewDefinitions/inspektorGadget"; import { KaitoDefinition } from "./webviewDefinitions/kaito"; import { KaitoModelsDefinition } from "./webviewDefinitions/kaitoModels"; @@ -43,6 +44,7 @@ type AllWebviewDefinitions = { draftDeployment: DraftDeploymentDefinition; draftDockerfile: DraftDockerfileDefinition; draftWorkflow: DraftWorkflowDefinition; + draftValidate: DraftValidateDefinition; gadget: InspektorGadgetDefinition; kubectl: KubectlDefinition; aso: ASODefinition; diff --git a/webview-ui/src/Draft/DraftValidate/DraftValidate.tsx b/webview-ui/src/Draft/DraftValidate/DraftValidate.tsx new file mode 100644 index 000000000..5c8f8f391 --- /dev/null +++ b/webview-ui/src/Draft/DraftValidate/DraftValidate.tsx @@ -0,0 +1,20 @@ +import { InitialState } from "../../../../src/webview-contract/webviewDefinitions/draft/draftValidate"; +import { useStateManagement } from "../../utilities/state"; +import { stateUpdater, vscode } from "./state"; +import { useEffect } from "react"; + +export function DraftValidate(initialState: InitialState) { + const { state } = useStateManagement(stateUpdater, initialState, vscode); + + //Request the validation results from the backend once when the component is mounted. + useEffect(() => { + vscode.postCreateDraftValidateRequest(""); + }, []); + + return ( + <> +

Draft Validate

+
{state.validationResults}
+ + ); +} diff --git a/webview-ui/src/Draft/DraftValidate/state.ts b/webview-ui/src/Draft/DraftValidate/state.ts new file mode 100644 index 000000000..e77ab2c78 --- /dev/null +++ b/webview-ui/src/Draft/DraftValidate/state.ts @@ -0,0 +1,37 @@ +import { WebviewStateUpdater } from "../../utilities/state"; +import { getWebviewMessageContext } from "../../utilities/vscode"; + +export type EventDef = { + //Defines the events that can originate from the webview and be sent to the backend (ToVsCodeMsgDef). + draftValidateRequest: string; //TODO Proper value //This represents a message from the webview to request a draft validation. +}; + +export type DraftValidateState = { + //Defines the shape of the state for the draftValidate webview. + validationResults: string; +}; + +export const stateUpdater: WebviewStateUpdater<"draftValidate", EventDef, DraftValidateState> = { + createState: (initialState) => ({ + validationResults: initialState.validationResults, + }), + vscodeMessageHandler: { + // This handler updates the state when a message from the extension + // with the name 'getValidationResult' arrives. + validationResult: (state, response) => ({ + ...state, + validationResults: response.result, + }), + }, + eventHandler: { + //There are no user triggered events and thus don't need to define any event handlers. + //Defines handlers for events triggered within the webview (ToVsCodeMsgDef) + draftValidateRequest: (state) => ({ + ...state, + }), + }, +}; + +export const vscode = getWebviewMessageContext<"draftValidate">({ + createDraftValidateRequest: null, //inside of ToVsCodeMsgDef +}); diff --git a/webview-ui/src/Draft/index.ts b/webview-ui/src/Draft/index.ts index fe22093a4..a45c3e02a 100644 --- a/webview-ui/src/Draft/index.ts +++ b/webview-ui/src/Draft/index.ts @@ -1,5 +1,6 @@ import { DraftDockerfile } from "./DraftDockerfile/DraftDockerfile"; import { DraftDeployment } from "./DraftDeployment/DraftDeployment"; import { DraftWorkflow } from "./DraftWorkflow/DraftWorkflow"; +import { DraftValidate } from "./DraftValidate/DraftValidate"; -export { DraftDockerfile, DraftDeployment, DraftWorkflow }; +export { DraftDockerfile, DraftDeployment, DraftWorkflow, DraftValidate }; diff --git a/webview-ui/src/main.tsx b/webview-ui/src/main.tsx index 84bba3163..3924003bb 100644 --- a/webview-ui/src/main.tsx +++ b/webview-ui/src/main.tsx @@ -8,7 +8,7 @@ import { AzureServiceOperator } from "./AzureServiceOperator/AzureServiceOperato import { ClusterProperties } from "./ClusterProperties/ClusterProperties"; import { CreateCluster } from "./CreateCluster/CreateCluster"; import { Detector } from "./Detector/Detector"; -import { DraftDeployment, DraftDockerfile, DraftWorkflow } from "./Draft"; +import { DraftDeployment, DraftDockerfile, DraftWorkflow, DraftValidate } from "./Draft"; import { InspektorGadget } from "./InspektorGadget/InspektorGadget"; import { Kaito } from "./Kaito/Kaito"; import { KaitoModels } from "./KaitoModels/KaitoModels"; @@ -56,6 +56,7 @@ function getVsCodeContent(): JSX.Element { draftDeployment: () => , draftDockerfile: () => , draftWorkflow: () => , + draftValidate: () => , gadget: () => , kubectl: () => , aso: () => , diff --git a/webview-ui/src/manualTest/main.tsx b/webview-ui/src/manualTest/main.tsx index 367eb57fd..2801b2c4e 100644 --- a/webview-ui/src/manualTest/main.tsx +++ b/webview-ui/src/manualTest/main.tsx @@ -44,6 +44,7 @@ const contentTestScenarios: Record = { draftDeployment: getDraftDeploymentScenarios(), draftDockerfile: getDraftDockerfileScenarios(), draftWorkflow: getDraftWorkflowScenarios(), + draftValidate: [], //TODO ADD TEST FOR DRAFT VALIDATE gadget: getInspektorGadgetScenarios(), kubectl: getKubectlScenarios(), aso: getASOScenarios(), From 056fd935bf0cb5f6dc8435409431e1bbfa394dc8 Mon Sep 17 00:00:00 2001 From: Reinier Cruz Date: Thu, 12 Dec 2024 12:19:07 -0500 Subject: [PATCH 4/8] removing comments --- webview-ui/src/Draft/DraftValidate/state.ts | 8 ++------ webview-ui/src/manualTest/main.tsx | 2 +- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/webview-ui/src/Draft/DraftValidate/state.ts b/webview-ui/src/Draft/DraftValidate/state.ts index e77ab2c78..368fd88d6 100644 --- a/webview-ui/src/Draft/DraftValidate/state.ts +++ b/webview-ui/src/Draft/DraftValidate/state.ts @@ -3,11 +3,10 @@ import { getWebviewMessageContext } from "../../utilities/vscode"; export type EventDef = { //Defines the events that can originate from the webview and be sent to the backend (ToVsCodeMsgDef). - draftValidateRequest: string; //TODO Proper value //This represents a message from the webview to request a draft validation. + draftValidateRequest: string; }; export type DraftValidateState = { - //Defines the shape of the state for the draftValidate webview. validationResults: string; }; @@ -17,15 +16,12 @@ export const stateUpdater: WebviewStateUpdater<"draftValidate", EventDef, DraftV }), vscodeMessageHandler: { // This handler updates the state when a message from the extension - // with the name 'getValidationResult' arrives. validationResult: (state, response) => ({ ...state, validationResults: response.result, }), }, eventHandler: { - //There are no user triggered events and thus don't need to define any event handlers. - //Defines handlers for events triggered within the webview (ToVsCodeMsgDef) draftValidateRequest: (state) => ({ ...state, }), @@ -33,5 +29,5 @@ export const stateUpdater: WebviewStateUpdater<"draftValidate", EventDef, DraftV }; export const vscode = getWebviewMessageContext<"draftValidate">({ - createDraftValidateRequest: null, //inside of ToVsCodeMsgDef + createDraftValidateRequest: null, }); diff --git a/webview-ui/src/manualTest/main.tsx b/webview-ui/src/manualTest/main.tsx index 2801b2c4e..fee4662ab 100644 --- a/webview-ui/src/manualTest/main.tsx +++ b/webview-ui/src/manualTest/main.tsx @@ -44,7 +44,7 @@ const contentTestScenarios: Record = { draftDeployment: getDraftDeploymentScenarios(), draftDockerfile: getDraftDockerfileScenarios(), draftWorkflow: getDraftWorkflowScenarios(), - draftValidate: [], //TODO ADD TEST FOR DRAFT VALIDATE + draftValidate: [], gadget: getInspektorGadgetScenarios(), kubectl: getKubectlScenarios(), aso: getASOScenarios(), From ee83a213cef6564625596389120526d0d9db4626 Mon Sep 17 00:00:00 2001 From: Reinier Cruz Date: Mon, 16 Dec 2024 12:08:05 -0500 Subject: [PATCH 5/8] adding ',' to fix previous merge conflict --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index 5adb8f5f3..b5f59cde1 100644 --- a/package.json +++ b/package.json @@ -328,6 +328,7 @@ "command": "aks.aksDraftValidate", "title": "Run Draft Validate for YAML" }, + { "command": "aks.aksKaitoTest", "title": "Test KAITO models" } From 31598053ed4b0772c7c1b3cf0ed722b40fa51af0 Mon Sep 17 00:00:00 2001 From: Reinier Cruz Date: Tue, 17 Dec 2024 12:04:21 -0500 Subject: [PATCH 6/8] renaming tab to include workspace name --- src/panels/draft/DraftValidatePanel.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/panels/draft/DraftValidatePanel.ts b/src/panels/draft/DraftValidatePanel.ts index ddfb0562d..8e5156772 100644 --- a/src/panels/draft/DraftValidatePanel.ts +++ b/src/panels/draft/DraftValidatePanel.ts @@ -30,7 +30,7 @@ export class DraftValidateDataProvider implements PanelDataProvider<"draftValida } getTitle(): string { - return `Draft Validate`; + return `Draft Validate in ${this.workspaceFolder.name}`; } getInitialState(): InitialState { From 499dba3387e59669f085338b6abcaa62c1d27864 Mon Sep 17 00:00:00 2001 From: Reinier Cruz Date: Tue, 17 Dec 2024 15:00:42 -0500 Subject: [PATCH 7/8] turning on telemtry --- src/panels/draft/DraftValidatePanel.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/panels/draft/DraftValidatePanel.ts b/src/panels/draft/DraftValidatePanel.ts index 8e5156772..c5bcb0fa6 100644 --- a/src/panels/draft/DraftValidatePanel.ts +++ b/src/panels/draft/DraftValidatePanel.ts @@ -41,7 +41,7 @@ export class DraftValidateDataProvider implements PanelDataProvider<"draftValida getTelemetryDefinition(): TelemetryDefinition<"draftValidate"> { return { - createDraftValidateRequest: false, + createDraftValidateRequest: true, }; } From 028ca26c505bb2bf6d3d070484c82d39809c26cf Mon Sep 17 00:00:00 2001 From: Reinier Cruz Date: Tue, 17 Dec 2024 15:01:49 -0500 Subject: [PATCH 8/8] removing old comment --- src/webview-contract/webviewDefinitions/draft/draftValidate.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/webview-contract/webviewDefinitions/draft/draftValidate.ts b/src/webview-contract/webviewDefinitions/draft/draftValidate.ts index 5a0a82848..86e8225c5 100644 --- a/src/webview-contract/webviewDefinitions/draft/draftValidate.ts +++ b/src/webview-contract/webviewDefinitions/draft/draftValidate.ts @@ -15,5 +15,3 @@ export type ToWebViewMsgDef = { }; export type DraftValidateDefinition = WebviewDefinition; - -//TODO FINISH REPLACING UNUSED CODE