diff --git a/package.json b/package.json index d3849a4..7689925 100644 --- a/package.json +++ b/package.json @@ -66,39 +66,65 @@ }, "viewsWelcome": [ { - "view": "components", - "contents": "Loading components..." - }, + "view": "components", + "contents": "Loading components...", + "when": "!githubLocalActions:noComponents && workspaceFolderCount > 0" + }, { - "view": "workflows", - "contents": "Loading components...", - "when": "!githubLocalActions:noWorkflows" - }, + "view": "components", + "contents": "No workspace folder opened", + "when": "workspaceFolderCount == 0" + }, { - "view": "workflows", - "contents": "No workflows found.", - "when": "githubLocalActions:noWorkflows" - }, + "view": "components", + "contents": "No components found.", + "when": "githubLocalActions:noComponents && workspaceFolderCount > 0" + }, { - "view": "history", - "contents": "Loading history...", - "when": "!githubLocalActions:noHistory" - }, + "view": "workflows", + "contents": "Loading components...", + "when": "!githubLocalActions:noWorkflows && workspaceFolderCount > 0" + }, { - "view": "history", - "contents": "No history found.", - "when": "githubLocalActions:noHistory" - }, + "view": "workflows", + "contents": "No workspace folder opened", + "when": "workspaceFolderCount == 0" + }, { - "view": "settings", - "contents": "Loading settings...", - "when": "!githubLocalActions:noSettings" - }, + "view": "workflows", + "contents": "No workflows found.", + "when": "githubLocalActions:noWorkflows && workspaceFolderCount > 0" + }, { - "view": "settings", - "contents": "No workflows found.", - "when": "githubLocalActions:noSettings" - } + "view": "history", + "contents": "Loading history...", + "when": "!githubLocalActions:noHistory && workspaceFolderCount > 0" + }, + { + "view": "history", + "contents": "No workspace folder opened", + "when": "workspaceFolderCount == 0" + }, + { + "view": "history", + "contents": "No history found.", + "when": "githubLocalActions:noHistory && workspaceFolderCount > 0" + }, + { + "view": "settings", + "contents": "Loading settings...", + "when": "!githubLocalActions:noSettings && workspaceFolderCount > 0" + }, + { + "view": "settings", + "contents": "No workspace folder opened", + "when": "workspaceFolderCount == 0" + }, + { + "view": "settings", + "contents": "No workflows found.", + "when": "githubLocalActions:noSettings && workspaceFolderCount > 0" + } ], "commands": [ { @@ -129,12 +155,14 @@ "category": "GitHub Local Actions", "command": "githubLocalActions.runAllWorkflows", "title": "Run All Workflows", + "enablement": "!githubLocalActions:noWorkflows && workspaceFolderCount > 0", "icon": "$(run-all)" }, { "category": "GitHub Local Actions", "command": "githubLocalActions.runEvent", "title": "Run Event", + "enablement": "!githubLocalActions:noWorkflows && workspaceFolderCount > 0", "icon": "$(symbol-event)" }, { @@ -161,12 +189,40 @@ "title": "Run Job", "icon": "$(debug-start)" }, + { + "category": "GitHub Local Actions", + "command": "githubLocalActions.clearAll", + "title": "Clear All", + "enablement": "!githubLocalActions:isRunning && !githubLocalActions:noWorkflows && workspaceFolderCount > 0", + "icon": "$(clear-all)" + }, { "category": "GitHub Local Actions", "command": "githubLocalActions.refreshHistory", "title": "Refresh", "icon": "$(refresh)" }, + { + "category": "GitHub Local Actions", + "command": "githubLocalActions.restart", + "title": "Restart", + "enablement": "viewItem =~ /^githubLocalActions.history_(Success|Failed|Cancelled).*/", + "icon": "$(debug-restart)" + }, + { + "category": "GitHub Local Actions", + "command": "githubLocalActions.stop", + "title": "Stop", + "enablement": "viewItem =~ /^githubLocalActions.history_(Running).*/", + "icon": "$(debug-stop)" + }, + { + "category": "GitHub Local Actions", + "command": "githubLocalActions.remove", + "title": "Remove", + "enablement": "viewItem =~ /^githubLocalActions.history_(Success|Failed|Cancelled).*/", + "icon": "$(close)" + }, { "category": "GitHub Local Actions", "command": "githubLocalActions.refreshSettings", @@ -216,10 +272,26 @@ "command": "githubLocalActions.runJob", "when": "never" }, + { + "command": "githubLocalActions.clearAll", + "when": "never" + }, { "command": "githubLocalActions.refreshHistory", "when": "never" }, + { + "command": "githubLocalActions.restart", + "when": "never" + }, + { + "command": "githubLocalActions.stop", + "when": "never" + }, + { + "command": "githubLocalActions.remove", + "when": "never" + }, { "command": "githubLocalActions.refreshSettings", "when": "never" @@ -247,10 +319,15 @@ "group": "navigation@2" }, { - "command": "githubLocalActions.refreshHistory", + "command": "githubLocalActions.clearAll", "when": "view == history", "group": "navigation@0" }, + { + "command": "githubLocalActions.refreshHistory", + "when": "view == history", + "group": "navigation@1" + }, { "command": "githubLocalActions.refreshSettings", "when": "view == settings", @@ -287,6 +364,21 @@ "command": "githubLocalActions.runJob", "when": "view == workflows && viewItem =~ /^githubLocalActions.job.*/", "group": "inline@0" + }, + { + "command": "githubLocalActions.restart", + "when": "view == history && viewItem =~ /^githubLocalActions.history.*/", + "group": "inline@0" + }, + { + "command": "githubLocalActions.stop", + "when": "view == history && viewItem =~ /^githubLocalActions.history.*/", + "group": "inline@1" + }, + { + "command": "githubLocalActions.remove", + "when": "view == history && viewItem =~ /^githubLocalActions.history.*/", + "group": "inline@2" } ] }, @@ -346,4 +438,4 @@ "webpack": "^5.94.0", "webpack-cli": "^5.1.4" } -} +} \ No newline at end of file diff --git a/src/act.ts b/src/act.ts index 04df970..a15b2f5 100644 --- a/src/act.ts +++ b/src/act.ts @@ -1,6 +1,6 @@ import * as child_process from 'child_process'; import * as path from "path"; -import { commands, CustomExecution, env, EventEmitter, Pseudoterminal, ShellExecution, TaskDefinition, TaskGroup, TaskPanelKind, TaskRevealKind, tasks, TaskScope, TerminalDimensions, window, workspace, WorkspaceFolder } from "vscode"; +import { commands, CustomExecution, env, EventEmitter, Pseudoterminal, ShellExecution, TaskDefinition, TaskExecution, TaskGroup, TaskPanelKind, TaskRevealKind, tasks, TaskScope, TerminalDimensions, window, workspace, WorkspaceFolder } from "vscode"; import { ComponentsManager } from "./componentsManager"; import { historyTreeDataProvider } from './extension'; import { SettingsManager } from './settingsManager'; @@ -68,12 +68,22 @@ export interface RawLog { jobResult?: string, //TODO: Could be an enum? } +export interface CommandArgs { + workspaceFolder: WorkspaceFolder, + options: string, + name: string, + typeText: string[] +} + export interface History { + index: number, name: string, status: HistoryStatus, start?: string, end?: string, - output?: string + output?: string, + taskExecution?: TaskExecution, + commandArgs: CommandArgs } export enum HistoryStatus { @@ -157,7 +167,14 @@ export class Act { async runWorkflow(workflow: Workflow) { const workspaceFolder = workspace.getWorkspaceFolder(workflow.uri); if (workspaceFolder) { - return await this.runCommand(workspaceFolder, `${Option.Workflows} ".github/workflows/${path.parse(workflow.uri.fsPath).base}"`, workflow.name, [`Workflow: ${workflow.name}`]); + return await this.runCommand({ + workspaceFolder: workspaceFolder, + options: `${Option.Workflows} ".github/workflows/${path.parse(workflow.uri.fsPath).base}"`, + name: workflow.name, + typeText: [ + `Workflow: ${workflow.name}` + ] + }); } else { window.showErrorMessage(`Failed to locate workspace folder for ${workflow.uri.fsPath}`); } @@ -173,8 +190,8 @@ export class Act { // return await this.runCommand(workspaceFolder, `${Option.Workflows} ${event}`, event, [`Event: ${event}`]); // } - async runCommand(workspaceFolder: WorkspaceFolder, options: string, name: string, typeText: string[]) { - const command = `${Act.base} ${Option.Json} ${options}`; + async runCommand(commandArgs: CommandArgs) { + const command = `${Act.base} ${Option.Json} ${commandArgs.options}`; const unreadyComponents = await this.componentsManager.getUnreadyComponents(); if (unreadyComponents.length > 0) { @@ -186,24 +203,26 @@ export class Act { return; } - if (!this.workspaceHistory[workspaceFolder.uri.fsPath]) { - this.workspaceHistory[workspaceFolder.uri.fsPath] = []; + if (!this.workspaceHistory[commandArgs.workspaceFolder.uri.fsPath]) { + this.workspaceHistory[commandArgs.workspaceFolder.uri.fsPath] = []; } - const historyIndex = this.workspaceHistory[workspaceFolder.uri.fsPath].length; - this.workspaceHistory[workspaceFolder.uri.fsPath].push({ - name: `${name} #${this.workspaceHistory[workspaceFolder.uri.fsPath].length + 1}`, + const historyIndex = this.workspaceHistory[commandArgs.workspaceFolder.uri.fsPath].length; + this.workspaceHistory[commandArgs.workspaceFolder.uri.fsPath].push({ + index: historyIndex, + name: `${commandArgs.name} #${this.workspaceHistory[commandArgs.workspaceFolder.uri.fsPath].length + 1}`, status: HistoryStatus.Running, - start: new Date().toISOString() + start: new Date().toISOString(), + commandArgs: commandArgs }); historyTreeDataProvider.refresh(); - await tasks.executeTask({ - name: name, + this.workspaceHistory[commandArgs.workspaceFolder.uri.fsPath][historyIndex].taskExecution = await tasks.executeTask({ + name: commandArgs.name, detail: 'Run workflow', definition: { type: 'GitHub Local Actions' }, source: 'GitHub Local Actions', - scope: workspaceFolder || TaskScope.Workspace, + scope: commandArgs.workspaceFolder || TaskScope.Workspace, isBackground: true, presentationOptions: { reveal: TaskRevealKind.Always, @@ -221,25 +240,25 @@ export class Act { const writeEmitter = new EventEmitter(); const closeEmitter = new EventEmitter(); - const exec = child_process.spawn(command, { cwd: workspaceFolder.uri.fsPath, shell: env.shell }); + const exec = child_process.spawn(command, { cwd: commandArgs.workspaceFolder.uri.fsPath, shell: env.shell }); const handleIO = (data: any) => { const lines: string[] = data.toString().split('\n').filter((line: string) => line != ''); for (const line of lines) { const jsonLine = JSON.parse(line); - if (!this.workspaceHistory[workspaceFolder.uri.fsPath][historyIndex].start) { - this.workspaceHistory[workspaceFolder.uri.fsPath][historyIndex].start = jsonLine.time; + if (!this.workspaceHistory[commandArgs.workspaceFolder.uri.fsPath][historyIndex].start) { + this.workspaceHistory[commandArgs.workspaceFolder.uri.fsPath][historyIndex].start = jsonLine.time; } if (jsonLine.jobResult) { - this.workspaceHistory[workspaceFolder.uri.fsPath][historyIndex].end = jsonLine.time; + this.workspaceHistory[commandArgs.workspaceFolder.uri.fsPath][historyIndex].end = jsonLine.time; switch (jsonLine.jobResult) { case 'success': - this.workspaceHistory[workspaceFolder.uri.fsPath][historyIndex].status = HistoryStatus.Success; + this.workspaceHistory[commandArgs.workspaceFolder.uri.fsPath][historyIndex].status = HistoryStatus.Success; break; case 'failure': - this.workspaceHistory[workspaceFolder.uri.fsPath][historyIndex].status = HistoryStatus.Failed; + this.workspaceHistory[commandArgs.workspaceFolder.uri.fsPath][historyIndex].status = HistoryStatus.Failed; break; // TODO: Handle cancelled } @@ -252,12 +271,12 @@ export class Act { exec.stdout.on('data', handleIO); exec.stderr.on('data', handleIO); exec.on('close', (code) => { - if (!this.workspaceHistory[workspaceFolder.uri.fsPath][historyIndex].end) { - this.workspaceHistory[workspaceFolder.uri.fsPath][historyIndex].end = new Date().toISOString(); + if (!this.workspaceHistory[commandArgs.workspaceFolder.uri.fsPath][historyIndex].end) { + this.workspaceHistory[commandArgs.workspaceFolder.uri.fsPath][historyIndex].end = new Date().toISOString(); } - if (this.workspaceHistory[workspaceFolder.uri.fsPath][historyIndex].status === HistoryStatus.Running) { - this.workspaceHistory[workspaceFolder.uri.fsPath][historyIndex].status = HistoryStatus.Failed; + if (this.workspaceHistory[commandArgs.workspaceFolder.uri.fsPath][historyIndex].status === HistoryStatus.Running) { + this.workspaceHistory[commandArgs.workspaceFolder.uri.fsPath][historyIndex].status = HistoryStatus.Failed; } historyTreeDataProvider.refresh(); @@ -268,9 +287,9 @@ export class Act { onDidWrite: writeEmitter.event, onDidClose: closeEmitter.event, open: async (initialDimensions: TerminalDimensions | undefined): Promise => { - writeEmitter.fire(`Name: ${name}\r\n`); - writeEmitter.fire(`Path: ${workspaceFolder.uri.fsPath}\r\n`); - for (const text of typeText) { + writeEmitter.fire(`Name: ${commandArgs.name}\r\n`); + writeEmitter.fire(`Path: ${commandArgs.workspaceFolder.uri.fsPath}\r\n`); + for (const text of commandArgs.typeText) { writeEmitter.fire(`${text}\r\n`); } writeEmitter.fire(`Environments: OSSBUILD\r\n`); @@ -282,8 +301,8 @@ export class Act { }, close: () => { - if (this.workspaceHistory[workspaceFolder.uri.fsPath][historyIndex].status === HistoryStatus.Running) { - this.workspaceHistory[workspaceFolder.uri.fsPath][historyIndex].status = HistoryStatus.Cancelled; + if (this.workspaceHistory[commandArgs.workspaceFolder.uri.fsPath][historyIndex].status === HistoryStatus.Running) { + this.workspaceHistory[commandArgs.workspaceFolder.uri.fsPath][historyIndex].status = HistoryStatus.Cancelled; } historyTreeDataProvider.refresh(); @@ -323,4 +342,26 @@ export class Act { }); } } + + async clearAll() { + //TODO: Fix for multi workspace support + const workspaceFolders = workspace.workspaceFolders; + if (workspaceFolders && workspaceFolders.length > 0) { + for (const workspaceFolder of workspaceFolders) { + this.workspaceHistory[workspaceFolder.uri.fsPath] = []; + historyTreeDataProvider.refresh(); + } + } + } + + async stop(history: History) { + history.taskExecution?.terminate(); + historyTreeDataProvider.refresh(); + } + + async remove(history: History) { + const historyIndex = this.workspaceHistory[history.commandArgs.workspaceFolder.uri.fsPath].findIndex(workspaceHistory => workspaceHistory.index === history.index) + this.workspaceHistory[history.commandArgs.workspaceFolder.uri.fsPath].splice(historyIndex, 1); + historyTreeDataProvider.refresh(); + } } \ No newline at end of file diff --git a/src/views/components/componentsTreeDataProvider.ts b/src/views/components/componentsTreeDataProvider.ts index 39a9b5c..c30e0ea 100644 --- a/src/views/components/componentsTreeDataProvider.ts +++ b/src/views/components/componentsTreeDataProvider.ts @@ -55,8 +55,15 @@ export default class ComponentsTreeDataProvider implements TreeDataProvider new ComponentTreeItem(component)); + for (const component of components) { + items.push(new ComponentTreeItem(component)); + } + + await commands.executeCommand('setContext', 'githubLocalActions:noComponents', items.length == 0); + return items; } } } \ No newline at end of file diff --git a/src/views/history/historyTreeDataProvider.ts b/src/views/history/historyTreeDataProvider.ts index 49d92b6..280d55b 100644 --- a/src/views/history/historyTreeDataProvider.ts +++ b/src/views/history/historyTreeDataProvider.ts @@ -1,4 +1,5 @@ import { CancellationToken, commands, EventEmitter, ExtensionContext, extensions, TreeDataProvider, TreeItem, workspace } from "vscode"; +import { HistoryStatus } from "../../act"; import { act } from "../../extension"; import { GithubLocalActionsTreeItem } from "../githubLocalActionsTreeItem"; import HistoryTreeItem from "./history"; @@ -14,8 +15,20 @@ export default class HistoryTreeDataProvider implements TreeDataProvider { + await act.clearAll(); + }), commands.registerCommand('githubLocalActions.refreshHistory', async () => { this.refresh(); + }), + commands.registerCommand('githubLocalActions.restart', async (historyTreeItem: HistoryTreeItem) => { + await act.runCommand(historyTreeItem.history.commandArgs); + }), + commands.registerCommand('githubLocalActions.stop', async (historyTreeItem: HistoryTreeItem) => { + await act.stop(historyTreeItem.history); + }), + commands.registerCommand('githubLocalActions.remove', async (historyTreeItem: HistoryTreeItem) => { + await act.remove(historyTreeItem.history); }) ); } @@ -43,15 +56,22 @@ export default class HistoryTreeDataProvider implements TreeDataProvider 0) { - const workspaceHistory = act.workspaceHistory[workspaceFolders[0].uri.fsPath]; //TODO: Fix for multi workspace support + //TODO: Fix for multi workspace support + const workspaceHistory = act.workspaceHistory[workspaceFolders[0].uri.fsPath]; if (workspaceHistory) { for (const history of workspaceHistory) { items.push(new HistoryTreeItem(history)); + + if (history.status === HistoryStatus.Running) { + isRunning = true; + } } } } + await commands.executeCommand('setContext', 'githubLocalActions:isRunning', isRunning); await commands.executeCommand('setContext', 'githubLocalActions:noHistory', items.length == 0); return items; }