Fix cli and extension status
Signed-off-by: Sanjula Ganepola <sanjulagane@gmail.com>
This commit is contained in:
@@ -1,51 +1,93 @@
|
|||||||
export interface Component {
|
import * as child_process from "child_process";
|
||||||
|
import { extensions } from "vscode";
|
||||||
|
|
||||||
|
export interface Component<T extends CliStatus | ExtensionStatus> {
|
||||||
name: string,
|
name: string,
|
||||||
icon: string,
|
icon: string,
|
||||||
status: ComponentStatus,
|
status: T,
|
||||||
required: boolean
|
required: boolean
|
||||||
message?: string
|
message?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum ComponentStatus {
|
export enum CliStatus {
|
||||||
Enabled = 'Enabled',
|
Installed = 'Installed',
|
||||||
Warning = 'Warning',
|
NotInstalled = 'Not Installed'
|
||||||
Disabled = 'Disabled'
|
}
|
||||||
|
|
||||||
|
export enum ExtensionStatus {
|
||||||
|
Activated = 'Activated',
|
||||||
|
NotActivated = 'Not Activated'
|
||||||
}
|
}
|
||||||
|
|
||||||
export class ComponentManager {
|
export class ComponentManager {
|
||||||
static async getComponents(): Promise<Component[]> {
|
static async getComponents(): Promise<Component<CliStatus | ExtensionStatus>[]> {
|
||||||
return [
|
const components: Component<CliStatus | ExtensionStatus>[] = [];
|
||||||
{
|
|
||||||
name: 'nektos/act',
|
const actCliStatus = await ComponentManager.getCliStatus('act');
|
||||||
icon: 'package',
|
components.push({
|
||||||
status: ComponentStatus.Enabled,
|
name: 'nektos/act CLI',
|
||||||
required: true
|
icon: 'terminal',
|
||||||
},
|
status: actCliStatus,
|
||||||
{
|
required: true
|
||||||
name: 'Docker Engine',
|
});
|
||||||
icon: 'dashboard',
|
|
||||||
status: ComponentStatus.Enabled,
|
const dockerEngineStatus = CliStatus.Installed;
|
||||||
required: true
|
components.push({
|
||||||
},
|
name: 'Docker Engine',
|
||||||
{
|
icon: 'dashboard',
|
||||||
name: 'GitHub Actions Extension',
|
status: dockerEngineStatus,
|
||||||
icon: 'extensions',
|
required: true
|
||||||
status: ComponentStatus.Warning,
|
});
|
||||||
required: false,
|
|
||||||
message: 'GitHub Actions extension is not required, but is recommended to take advantage of workflow editor features.'
|
const githubActionsExtensionStatus = await ComponentManager.getExtensionStatus('github.vscode-github-actions');
|
||||||
},
|
components.push({
|
||||||
{
|
name: 'GitHub Actions Extension',
|
||||||
name: 'GitHub CLI',
|
icon: 'extensions',
|
||||||
icon: 'terminal',
|
status: githubActionsExtensionStatus,
|
||||||
status: ComponentStatus.Warning,
|
required: false,
|
||||||
required: false,
|
message: 'GitHub Actions extension is not required, but is recommended to take advantage of workflow editor features.'
|
||||||
message: 'GitHub CLI is not required, but is recommended if you plan to use it to retrieve GitHub tokens.'
|
});
|
||||||
}
|
|
||||||
];
|
const isGithubCliInstalled = await ComponentManager.getCliStatus('gh');
|
||||||
|
components.push({
|
||||||
|
name: 'GitHub CLI',
|
||||||
|
icon: 'terminal',
|
||||||
|
status: isGithubCliInstalled,
|
||||||
|
required: false,
|
||||||
|
message: 'GitHub CLI is not required, but is recommended if you plan to use it to retrieve GitHub tokens.'
|
||||||
|
});
|
||||||
|
|
||||||
|
return components;
|
||||||
}
|
}
|
||||||
|
|
||||||
static async getUnreadyComponents(): Promise<Component[]> {
|
static async getUnreadyComponents(): Promise<Component<CliStatus | ExtensionStatus>[]> {
|
||||||
const components = await ComponentManager.getComponents();
|
const components = await ComponentManager.getComponents();
|
||||||
return components.filter(component => component.required && component.status !== ComponentStatus.Enabled);
|
return components.filter(component => component.required && (component.status === CliStatus.NotInstalled || component.status === ExtensionStatus.NotActivated));
|
||||||
|
}
|
||||||
|
|
||||||
|
static async getCliStatus(component: string): Promise<CliStatus> {
|
||||||
|
return new Promise<CliStatus>((resolve, reject) => {
|
||||||
|
child_process.exec(`${component} --version`, (error, stdout, stderr) => {
|
||||||
|
if (error) {
|
||||||
|
resolve(CliStatus.NotInstalled);
|
||||||
|
} else {
|
||||||
|
resolve(CliStatus.Installed);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
static async getExtensionStatus(extensionId: string): Promise<ExtensionStatus> {
|
||||||
|
const allExtensions = extensions.all;
|
||||||
|
const extension = allExtensions.find(extension => extension.id === extensionId);
|
||||||
|
if (extension) {
|
||||||
|
if (!extension.isActive) {
|
||||||
|
await extension.activate();
|
||||||
|
}
|
||||||
|
|
||||||
|
return ExtensionStatus.Activated;
|
||||||
|
} else {
|
||||||
|
return ExtensionStatus.NotActivated;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,17 +1,17 @@
|
|||||||
import { ThemeIcon, TreeItem, TreeItemCollapsibleState, Uri } from "vscode";
|
import { ThemeIcon, TreeItem, TreeItemCollapsibleState, Uri } from "vscode";
|
||||||
import { Component } from "../../componentManager";
|
import { CliStatus, Component, ExtensionStatus } from "../../componentManager";
|
||||||
import { GithubLocalActionsTreeItem } from "../githubLocalActionsTreeItem";
|
import { GithubLocalActionsTreeItem } from "../githubLocalActionsTreeItem";
|
||||||
|
|
||||||
export default class ComponentTreeItem extends TreeItem implements GithubLocalActionsTreeItem {
|
export default class ComponentTreeItem extends TreeItem implements GithubLocalActionsTreeItem {
|
||||||
static contextValue = 'githubLocalActions.component';
|
static contextValue = 'githubLocalActions.component';
|
||||||
component: Component;
|
component: Component<CliStatus | ExtensionStatus>;
|
||||||
|
|
||||||
constructor(component: Component) {
|
constructor(component: Component<CliStatus | ExtensionStatus>) {
|
||||||
super(component.name, TreeItemCollapsibleState.None);
|
super(component.name, TreeItemCollapsibleState.None);
|
||||||
this.component = component;
|
this.component = component;
|
||||||
this.contextValue = ComponentTreeItem.contextValue;
|
this.contextValue = ComponentTreeItem.contextValue;
|
||||||
this.iconPath = new ThemeIcon(component.icon);
|
this.iconPath = new ThemeIcon(component.icon);
|
||||||
this.resourceUri = Uri.parse(`${ComponentTreeItem.contextValue}:${component.name}?status=${component.status}`, true);
|
this.resourceUri = Uri.parse(`${ComponentTreeItem.contextValue}:${component.name}?status=${component.status}&required=${component.required}`, true);
|
||||||
this.tooltip = `Name: ${component.name}\n` +
|
this.tooltip = `Name: ${component.name}\n` +
|
||||||
`Status: ${component.status}\n` +
|
`Status: ${component.status}\n` +
|
||||||
(component.message ? `Message: ${component.message}` : ``);
|
(component.message ? `Message: ${component.message}` : ``);
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { CancellationToken, commands, EventEmitter, ExtensionContext, TreeDataProvider, TreeItem } from "vscode";
|
import { CancellationToken, commands, EventEmitter, ExtensionContext, extensions, TreeDataProvider, TreeItem } from "vscode";
|
||||||
import { ComponentManager } from "../../componentManager";
|
import { ComponentManager } from "../../componentManager";
|
||||||
import { GithubLocalActionsTreeItem } from "../githubLocalActionsTreeItem";
|
import { GithubLocalActionsTreeItem } from "../githubLocalActionsTreeItem";
|
||||||
import ComponentTreeItem from "./component";
|
import ComponentTreeItem from "./component";
|
||||||
@@ -9,7 +9,11 @@ export default class ComponentsTreeDataProvider implements TreeDataProvider<Gith
|
|||||||
static VIEW_ID = 'components';
|
static VIEW_ID = 'components';
|
||||||
|
|
||||||
constructor(context: ExtensionContext) {
|
constructor(context: ExtensionContext) {
|
||||||
context.subscriptions.push(
|
extensions.onDidChange(e => {
|
||||||
|
this.refresh();
|
||||||
|
});
|
||||||
|
|
||||||
|
context.subscriptions.push(
|
||||||
commands.registerCommand('githubLocalActions.refreshComponents', async () => {
|
commands.registerCommand('githubLocalActions.refreshComponents', async () => {
|
||||||
this.refresh();
|
this.refresh();
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -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 { ComponentStatus } from "../componentManager";
|
import { CliStatus, ExtensionStatus } from "../componentManager";
|
||||||
import ComponentTreeItem from "./components/component";
|
import ComponentTreeItem from "./components/component";
|
||||||
import WorkflowTreeItem from "./workflows/workflow";
|
import WorkflowTreeItem from "./workflows/workflow";
|
||||||
|
|
||||||
@@ -9,25 +9,29 @@ export class DecorationProvider implements FileDecorationProvider {
|
|||||||
const params = new URLSearchParams(uri.query);
|
const params = new URLSearchParams(uri.query);
|
||||||
|
|
||||||
if (uri.scheme === ComponentTreeItem.contextValue) {
|
if (uri.scheme === ComponentTreeItem.contextValue) {
|
||||||
if (params.get('status') === ComponentStatus.Enabled) {
|
const status = params.get('status');
|
||||||
|
const required = params.get('required');
|
||||||
|
|
||||||
|
if (status === CliStatus.Installed || status === ExtensionStatus.Activated) {
|
||||||
return {
|
return {
|
||||||
badge: '✅',
|
badge: '✅',
|
||||||
color: new ThemeColor('GitHubLocalActions.green')
|
color: new ThemeColor('GitHubLocalActions.green')
|
||||||
};
|
};
|
||||||
} else if (params.get('status') === ComponentStatus.Warning) {
|
} else if (!required && (status === CliStatus.NotInstalled || status === ExtensionStatus.NotActivated)) {
|
||||||
return {
|
return {
|
||||||
badge: '⚠️',
|
badge: '⚠️',
|
||||||
color: new ThemeColor('GitHubLocalActions.yellow')
|
color: new ThemeColor('GitHubLocalActions.yellow')
|
||||||
};
|
};
|
||||||
} else if (params.get('status') === ComponentStatus.Disabled) {
|
} else if (required && (status === CliStatus.NotInstalled || status === ExtensionStatus.NotActivated)) {
|
||||||
return {
|
return {
|
||||||
badge: '❌',
|
badge: '❌',
|
||||||
color: new ThemeColor('GitHubLocalActions.red')
|
color: new ThemeColor('GitHubLocalActions.red')
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
} else if (uri.scheme === WorkflowTreeItem.contextValue) {
|
} else if (uri.scheme === WorkflowTreeItem.contextValue) {
|
||||||
// TODO: Fix color
|
const error = params.get('error');
|
||||||
if (params.get('error')) {
|
|
||||||
|
if (error) {
|
||||||
return {
|
return {
|
||||||
badge: '❌',
|
badge: '❌',
|
||||||
color: new ThemeColor('GitHubLocalActions.red')
|
color: new ThemeColor('GitHubLocalActions.red')
|
||||||
|
|||||||
Reference in New Issue
Block a user