Switch to singleton act instance

Signed-off-by: Sanjula Ganepola <sanjulagane@gmail.com>
This commit is contained in:
Sanjula Ganepola
2024-09-28 20:09:38 -04:00
parent c4ca083f71
commit f47327dd23
10 changed files with 68 additions and 34 deletions

View File

@@ -1,8 +1,9 @@
import * as child_process from 'child_process'; import * as child_process from 'child_process';
import * as path from "path"; import * as path from "path";
import { commands, CustomExecution, EventEmitter, Pseudoterminal, TaskDefinition, TaskGroup, TaskPanelKind, TaskRevealKind, tasks, TaskScope, TerminalDimensions, window, workspace } from "vscode"; import { commands, CustomExecution, EventEmitter, Pseudoterminal, TaskDefinition, TaskGroup, TaskPanelKind, TaskRevealKind, tasks, TaskScope, TerminalDimensions, window, workspace } from "vscode";
import { ComponentManager } from "./componentManager"; import { ComponentsManager } from "./componentsManager";
import { Workflow } from "./workflowManager"; import { SettingsManager } from './settingsManager';
import { Workflow, WorkflowsManager } from "./workflowsManager";
export enum EventTrigger { export enum EventTrigger {
BranchProtectionRule = 'branch_protection_rule', BranchProtectionRule = 'branch_protection_rule',
@@ -41,26 +42,36 @@ export enum EventTrigger {
} }
export enum Option { export enum Option {
Workflows = '-W' Workflows = '-W',
Variable = '-var'
} }
export class Act { export class Act {
private static base: string = 'act'; private static base: string = 'act';
componentsManager: ComponentsManager;
workflowsManager: WorkflowsManager;
settingsManager: SettingsManager;
static async runAllWorkflows() { constructor() {
this.componentsManager = new ComponentsManager();
this.workflowsManager = new WorkflowsManager();
this.settingsManager = new SettingsManager();
}
async runAllWorkflows() {
// TODO: Implement // TODO: Implement
} }
static async runEvent(eventTrigger: EventTrigger) { async runEvent(eventTrigger: EventTrigger) {
// return await Act.runCommand(`${Act.base} ${eventTrigger}`); // return await this.runCommand(`${Act.base} ${eventTrigger}`);
} }
static async runWorkflow(workflow: Workflow) { async runWorkflow(workflow: Workflow) {
return await Act.runCommand(workflow, `${Act.base} ${Option.Workflows} ".github/workflows/${path.parse(workflow.uri.fsPath).base}"`); return await this.runCommand(workflow, `${Act.base} ${Option.Workflows} ".github/workflows/${path.parse(workflow.uri.fsPath).base}"`);
} }
static async runCommand(workflow: Workflow, command: string) { async runCommand(workflow: Workflow, command: string) {
const unreadyComponents = await ComponentManager.getUnreadyComponents(); const unreadyComponents = await this.componentsManager.getUnreadyComponents();
if (unreadyComponents.length > 0) { if (unreadyComponents.length > 0) {
window.showErrorMessage(`The following required components are not ready: ${unreadyComponents.map(component => component.name).join(', ')}`, 'Fix...').then(async value => { window.showErrorMessage(`The following required components are not ready: ${unreadyComponents.map(component => component.name).join(', ')}`, 'Fix...').then(async value => {
if (value === 'Fix...') { if (value === 'Fix...') {

View File

@@ -21,11 +21,11 @@ export enum ExtensionStatus {
NotActivated = 'Not Activated' NotActivated = 'Not Activated'
} }
export class ComponentManager { export class ComponentsManager {
static async getComponents(): Promise<Component<CliStatus | ExtensionStatus>[]> { async getComponents(): Promise<Component<CliStatus | ExtensionStatus>[]> {
const components: Component<CliStatus | ExtensionStatus>[] = []; const components: Component<CliStatus | ExtensionStatus>[] = [];
const actCliInfo = await ComponentManager.getCliInfo('act', /act version (.+)/); const actCliInfo = await this.getCliInfo('act', /act version (.+)/);
components.push({ components.push({
name: 'nektos/act CLI', name: 'nektos/act CLI',
icon: 'terminal', icon: 'terminal',
@@ -47,7 +47,7 @@ export class ComponentManager {
required: true required: true
}); });
const githubActionsInfo = await ComponentManager.getExtensionInfo('github.vscode-github-actions'); const githubActionsInfo = await this.getExtensionInfo('github.vscode-github-actions');
components.push({ components.push({
name: 'GitHub Actions Extension', name: 'GitHub Actions Extension',
icon: 'extensions', icon: 'extensions',
@@ -58,7 +58,7 @@ export class ComponentManager {
message: 'GitHub Actions extension is not required, but is recommended to take advantage of workflow editor features.' message: 'GitHub Actions extension is not required, but is recommended to take advantage of workflow editor features.'
}); });
const githubCliInfo = await ComponentManager.getCliInfo('gh', /gh version (.+)/); const githubCliInfo = await this.getCliInfo('gh', /gh version (.+)/);
components.push({ components.push({
name: 'GitHub CLI', name: 'GitHub CLI',
icon: 'terminal', icon: 'terminal',
@@ -72,12 +72,12 @@ export class ComponentManager {
return components; return components;
} }
static async getUnreadyComponents(): Promise<Component<CliStatus | ExtensionStatus>[]> { async getUnreadyComponents(): Promise<Component<CliStatus | ExtensionStatus>[]> {
const components = await ComponentManager.getComponents(); const components = await this.getComponents();
return components.filter(component => component.required && (component.status === CliStatus.NotInstalled || component.status === ExtensionStatus.NotActivated)); return components.filter(component => component.required && (component.status === CliStatus.NotInstalled || component.status === ExtensionStatus.NotActivated));
} }
static async getCliInfo(component: string, versionRegex: RegExp): Promise<{ version?: string, status: CliStatus }> { async getCliInfo(component: string, versionRegex: RegExp): Promise<{ version?: string, status: CliStatus }> {
return new Promise<{ version?: string, status: CliStatus }>((resolve, reject) => { return new Promise<{ version?: string, status: CliStatus }>((resolve, reject) => {
child_process.exec(`${component} --version`, (error, stdout, stderr) => { child_process.exec(`${component} --version`, (error, stdout, stderr) => {
if (error) { if (error) {
@@ -96,7 +96,7 @@ export class ComponentManager {
}); });
} }
static async getExtensionInfo(extensionId: string): Promise<{ version?: string, status: ExtensionStatus }> { async getExtensionInfo(extensionId: string): Promise<{ version?: string, status: ExtensionStatus }> {
const allExtensions = extensions.all; const allExtensions = extensions.all;
const extension = allExtensions.find(extension => extension.id === extensionId); const extension = allExtensions.find(extension => extension.id === extensionId);

View File

@@ -1,15 +1,19 @@
import * as vscode from 'vscode'; import * as vscode from 'vscode';
import { window } from 'vscode'; import { window } from 'vscode';
import { Act } from './act';
import ComponentsTreeDataProvider from './views/components/componentsTreeDataProvider'; import ComponentsTreeDataProvider from './views/components/componentsTreeDataProvider';
import { DecorationProvider } from './views/decorationProvider'; import { DecorationProvider } from './views/decorationProvider';
import SettingsTreeDataProvider from './views/settings/settingsTreeDataProvider'; import SettingsTreeDataProvider from './views/settings/settingsTreeDataProvider';
import WorkflowsTreeDataProvider from './views/workflows/workflowsTreeDataProvider'; import WorkflowsTreeDataProvider from './views/workflows/workflowsTreeDataProvider';
export let act: Act;
export function activate(context: vscode.ExtensionContext) { export function activate(context: vscode.ExtensionContext) {
console.log('Congratulations, your extension "github-local-actions" is now active!'); console.log('Congratulations, your extension "github-local-actions" is now active!');
const decorationProvider = new DecorationProvider(); act = new Act();
const decorationProvider = new DecorationProvider();
const componentsTreeDataProvider = new ComponentsTreeDataProvider(context); const componentsTreeDataProvider = new ComponentsTreeDataProvider(context);
const componentsTreeView = window.createTreeView(ComponentsTreeDataProvider.VIEW_ID, { treeDataProvider: componentsTreeDataProvider }); const componentsTreeView = window.createTreeView(ComponentsTreeDataProvider.VIEW_ID, { treeDataProvider: componentsTreeDataProvider });
const workflowsTreeDataProvider = new WorkflowsTreeDataProvider(context); const workflowsTreeDataProvider = new WorkflowsTreeDataProvider(context);

19
src/settingsManager.ts Normal file
View File

@@ -0,0 +1,19 @@
export interface Environment {
}
export interface Secret {
key: string,
value?: string
}
export interface Variable {
key: string,
value?: string
}
export class SettingsManager {
environments: Environment[] = [];
secrets: Secret[] = [];
variables: Variable[] = [];
}

View File

@@ -1,5 +1,5 @@
import { ThemeIcon, TreeItem, TreeItemCollapsibleState, Uri } from "vscode"; import { ThemeIcon, TreeItem, TreeItemCollapsibleState, Uri } from "vscode";
import { CliStatus, Component, ExtensionStatus } from "../../componentManager"; import { CliStatus, Component, ExtensionStatus } from "../../componentsManager";
import { GithubLocalActionsTreeItem } from "../githubLocalActionsTreeItem"; import { GithubLocalActionsTreeItem } from "../githubLocalActionsTreeItem";
export default class ComponentTreeItem extends TreeItem implements GithubLocalActionsTreeItem { export default class ComponentTreeItem extends TreeItem implements GithubLocalActionsTreeItem {

View File

@@ -1,5 +1,5 @@
import { CancellationToken, commands, env, EventEmitter, ExtensionContext, extensions, TreeDataProvider, TreeItem, Uri } from "vscode"; import { CancellationToken, commands, env, EventEmitter, ExtensionContext, extensions, TreeDataProvider, TreeItem, Uri } from "vscode";
import { ComponentManager } from "../../componentManager"; import { act } from "../../extension";
import { GithubLocalActionsTreeItem } from "../githubLocalActionsTreeItem"; import { GithubLocalActionsTreeItem } from "../githubLocalActionsTreeItem";
import ComponentTreeItem from "./component"; import ComponentTreeItem from "./component";
@@ -43,7 +43,7 @@ export default class ComponentsTreeDataProvider implements TreeDataProvider<Gith
if (element) { if (element) {
return element.getChildren(); return element.getChildren();
} else { } else {
const components = await ComponentManager.getComponents(); const components = await act.componentsManager.getComponents();
return components.map(component => new ComponentTreeItem(component)); return components.map(component => new ComponentTreeItem(component));
} }
} }

View File

@@ -1,5 +1,5 @@
import { CancellationToken, Event, FileDecoration, FileDecorationProvider, ProviderResult, ThemeColor, Uri } from "vscode"; import { CancellationToken, Event, FileDecoration, FileDecorationProvider, ProviderResult, ThemeColor, Uri } from "vscode";
import { CliStatus, ExtensionStatus } from "../componentManager"; import { CliStatus, ExtensionStatus } from "../componentsManager";
import ComponentTreeItem from "./components/component"; import ComponentTreeItem from "./components/component";
import WorkflowTreeItem from "./workflows/workflow"; import WorkflowTreeItem from "./workflows/workflow";

View File

@@ -1,5 +1,5 @@
import { ThemeIcon, TreeItem, TreeItemCollapsibleState, Uri } from "vscode"; import { ThemeIcon, TreeItem, TreeItemCollapsibleState, Uri } from "vscode";
import { Workflow } from "../../workflowManager"; import { Workflow } from "../../workflowsManager";
import { GithubLocalActionsTreeItem } from "../githubLocalActionsTreeItem"; import { GithubLocalActionsTreeItem } from "../githubLocalActionsTreeItem";
export default class WorkflowTreeItem extends TreeItem implements GithubLocalActionsTreeItem { export default class WorkflowTreeItem extends TreeItem implements GithubLocalActionsTreeItem {

View File

@@ -1,6 +1,6 @@
import { CancellationToken, commands, EventEmitter, ExtensionContext, TreeDataProvider, TreeItem, window, workspace } from "vscode"; import { CancellationToken, commands, EventEmitter, ExtensionContext, TreeDataProvider, TreeItem, window, workspace } from "vscode";
import { Act, EventTrigger } from "../../act"; import { EventTrigger } from "../../act";
import { WorkflowManager } from "../../workflowManager"; import { act } from "../../extension";
import { GithubLocalActionsTreeItem } from "../githubLocalActionsTreeItem"; import { GithubLocalActionsTreeItem } from "../githubLocalActionsTreeItem";
import WorkflowTreeItem from "./workflow"; import WorkflowTreeItem from "./workflow";
@@ -12,7 +12,7 @@ export default class WorkflowsTreeDataProvider implements TreeDataProvider<Githu
constructor(context: ExtensionContext) { constructor(context: ExtensionContext) {
context.subscriptions.push( context.subscriptions.push(
commands.registerCommand('githubLocalActions.runAllWorkflows', async () => { commands.registerCommand('githubLocalActions.runAllWorkflows', async () => {
await Act.runAllWorkflows(); await act.runAllWorkflows();
}), }),
commands.registerCommand('githubLocalActions.runEvent', async () => { commands.registerCommand('githubLocalActions.runEvent', async () => {
const event = await window.showQuickPick(Object.values(EventTrigger), { const event = await window.showQuickPick(Object.values(EventTrigger), {
@@ -21,7 +21,7 @@ export default class WorkflowsTreeDataProvider implements TreeDataProvider<Githu
}); });
if(event) { if(event) {
await Act.runEvent(event as EventTrigger); await act.runEvent(event as EventTrigger);
} }
}), }),
commands.registerCommand('githubLocalActions.refreshWorkflows', async () => { commands.registerCommand('githubLocalActions.refreshWorkflows', async () => {
@@ -32,7 +32,7 @@ export default class WorkflowsTreeDataProvider implements TreeDataProvider<Githu
await window.showTextDocument(document); await window.showTextDocument(document);
}), }),
commands.registerCommand('githubLocalActions.runWorkflow', async (workflowTreeItem: WorkflowTreeItem) => { commands.registerCommand('githubLocalActions.runWorkflow', async (workflowTreeItem: WorkflowTreeItem) => {
await Act.runWorkflow(workflowTreeItem.workflow); await act.runWorkflow(workflowTreeItem.workflow);
}) })
); );
} }
@@ -57,7 +57,7 @@ export default class WorkflowsTreeDataProvider implements TreeDataProvider<Githu
if (element) { if (element) {
return element.getChildren(); return element.getChildren();
} else { } else {
const workflows = await WorkflowManager.getWorkflows(); const workflows = await act.workflowsManager.getWorkflows();
return workflows.map(workflow => new WorkflowTreeItem(workflow)); return workflows.map(workflow => new WorkflowTreeItem(workflow));
} }
} }

View File

@@ -41,14 +41,14 @@ export enum StepStatus {
Cancelled = 'cancelled' Cancelled = 'cancelled'
} }
export class WorkflowManager { export class WorkflowsManager {
private workflowLogs: WorkflowLog[] = []; private workflowLogs: WorkflowLog[] = [];
constructor() { constructor() {
} }
static async getWorkflows(): Promise<Workflow[]> { async getWorkflows(): Promise<Workflow[]> {
const workflows: Workflow[] = []; const workflows: Workflow[] = [];
const workspaceFolders = workspace.workspaceFolders; const workspaceFolders = workspace.workspaceFolders;