Add settings view

Signed-off-by: Sanjula Ganepola <sanjulagane@gmail.com>
This commit is contained in:
Sanjula Ganepola
2024-09-29 11:28:03 -04:00
parent f47327dd23
commit b30fc76de5
11 changed files with 178 additions and 10 deletions

View File

@@ -1,5 +1,7 @@
export interface Environment {
import { Workflow } from "./workflowsManager";
export interface Environment {
name: string
}
export interface Secret {
@@ -12,8 +14,67 @@ export interface Variable {
value?: string
}
export interface Input {
key: string,
value?: string
}
export class SettingsManager {
environments: Environment[] = [];
secrets: Secret[] = [];
variables: Variable[] = [];
getEnvironments(workflow: Workflow): Environment[] {
const environments: Environment[] = [];
if (!workflow.yaml) {
return environments;
}
const jobs = workflow.yaml?.jobs;
if (jobs) {
for (const details of Object.values<any>(jobs)) {
if (details.environment) {
environments.push({
name: details.environment
});
}
}
}
return environments;
}
getSecrets(workflow: Workflow): Secret[] {
const secrets: Secret[] = [];
if (!workflow.fileContent) {
return secrets;
}
return this.findInWorkflow(workflow.fileContent, /\${{\s*secrets\.(.*?)\s*}}/g);
}
getVariables(workflow: Workflow): Variable[] {
const variables: Variable[] = [];
if (!workflow.fileContent) {
return variables;
}
return this.findInWorkflow(workflow.fileContent, /\${{\s*vars\.(.*?)(?:\s*==\s*(.*?))?\s*}}/g);
}
getInputs(workflow: Workflow): Input[] {
const inputs: Variable[] = [];
if (!workflow.fileContent) {
return inputs;
}
return this.findInWorkflow(workflow.fileContent, /\${{\s*(?:inputs|github\.event\.inputs)\.(.*?)(?:\s*==\s*(.*?))?\s*}}/g);
}
private findInWorkflow(content: string, regExp: RegExp) {
const results: (Secret | Variable | Input)[] = [];
const matches = content.matchAll(regExp);
for (const match of matches) {
results.push({ key: match[1] });
}
return results;
}
}

View File

@@ -0,0 +1,17 @@
import { ThemeIcon, TreeItem, TreeItemCollapsibleState } from "vscode";
import { Environment } from "../../settingsManager";
import { GithubLocalActionsTreeItem } from "../githubLocalActionsTreeItem";
export default class EnvironmentTreeItem extends TreeItem implements GithubLocalActionsTreeItem {
static contextValue = 'githubLocalActions.environment';
constructor(environment: Environment) {
super(environment.name, TreeItemCollapsibleState.None);
this.contextValue = EnvironmentTreeItem.contextValue;
this.iconPath = new ThemeIcon('server');
}
async getChildren(): Promise<GithubLocalActionsTreeItem[]> {
return [];
}
}

View File

@@ -1,5 +1,7 @@
import { ThemeIcon, TreeItem, TreeItemCollapsibleState } from "vscode";
import { act } from "../../extension";
import { GithubLocalActionsTreeItem } from "../githubLocalActionsTreeItem";
import EnvironmentTreeItem from "./environment";
export default class EnvironmentsTreeItem extends TreeItem implements GithubLocalActionsTreeItem {
static contextValue = 'githubLocalActions.environments';
@@ -11,6 +13,8 @@ export default class EnvironmentsTreeItem extends TreeItem implements GithubLoca
}
async getChildren(): Promise<GithubLocalActionsTreeItem[]> {
return [];
const workflows = await act.workflowsManager.getWorkflows();
const environments = [...new Set(workflows.map(workflow => act.settingsManager.getEnvironments(workflow)).flat())];
return environments.map(environment => new EnvironmentTreeItem(environment));
}
}

View File

@@ -0,0 +1,18 @@
import { ThemeIcon, TreeItem, TreeItemCollapsibleState } from "vscode";
import { Input } from "../../settingsManager";
import { GithubLocalActionsTreeItem } from "../githubLocalActionsTreeItem";
export default class InputTreeItem extends TreeItem implements GithubLocalActionsTreeItem {
static contextValue = 'githubLocalActions.input';
constructor(input: Input) {
super(input.key, TreeItemCollapsibleState.None);
this.description = input.value;
this.contextValue = InputTreeItem.contextValue;
this.iconPath = new ThemeIcon('symbol-parameter');
}
async getChildren(): Promise<GithubLocalActionsTreeItem[]> {
return [];
}
}

View File

@@ -0,0 +1,20 @@
import { ThemeIcon, TreeItem, TreeItemCollapsibleState } from "vscode";
import { act } from "../../extension";
import { GithubLocalActionsTreeItem } from "../githubLocalActionsTreeItem";
import InputTreeItem from "./input";
export default class InputsTreeItem extends TreeItem implements GithubLocalActionsTreeItem {
static contextValue = 'githubLocalActions.inputs';
constructor() {
super('Inputs', TreeItemCollapsibleState.Collapsed);
this.contextValue = InputsTreeItem.contextValue;
this.iconPath = new ThemeIcon('record-keys');
}
async getChildren(): Promise<GithubLocalActionsTreeItem[]> {
const workflows = await act.workflowsManager.getWorkflows();
const inputs = [...new Set(workflows.map(workflow => act.settingsManager.getInputs(workflow)).flat())];
return inputs.map(input => new InputTreeItem(input));
}
}

View File

@@ -0,0 +1,18 @@
import { ThemeIcon, TreeItem, TreeItemCollapsibleState } from "vscode";
import { Secret } from "../../settingsManager";
import { GithubLocalActionsTreeItem } from "../githubLocalActionsTreeItem";
export default class SecretTreeItem extends TreeItem implements GithubLocalActionsTreeItem {
static contextValue = 'githubLocalActions.secret';
constructor(secret: Secret) {
super(secret.key, TreeItemCollapsibleState.None);
this.description = secret.value;
this.contextValue = SecretTreeItem.contextValue;
this.iconPath = new ThemeIcon('key');
}
async getChildren(): Promise<GithubLocalActionsTreeItem[]> {
return [];
}
}

View File

@@ -1,5 +1,7 @@
import { ThemeIcon, TreeItem, TreeItemCollapsibleState } from "vscode";
import { act } from "../../extension";
import { GithubLocalActionsTreeItem } from "../githubLocalActionsTreeItem";
import SecretTreeItem from "./secret";
export default class SecretsTreeItem extends TreeItem implements GithubLocalActionsTreeItem {
static contextValue = 'githubLocalActions.secrets';
@@ -11,6 +13,8 @@ export default class SecretsTreeItem extends TreeItem implements GithubLocalActi
}
async getChildren(): Promise<GithubLocalActionsTreeItem[]> {
return [];
const workflows = await act.workflowsManager.getWorkflows();
const secrets = [...new Set(workflows.map(workflow => act.settingsManager.getSecrets(workflow)).flat())];
return secrets.map(secret => new SecretTreeItem(secret));
}
}

View File

@@ -1,6 +1,7 @@
import { CancellationToken, commands, EventEmitter, ExtensionContext, TreeDataProvider, TreeItem } from "vscode";
import { GithubLocalActionsTreeItem } from "../githubLocalActionsTreeItem";
import EnvironmentsTreeItem from "./environments";
import InputsTreeItem from "./inputs";
import SecretsTreeItem from "./secrets";
import VariablesTreeItem from "./variables";
@@ -40,7 +41,8 @@ export default class SettingsTreeDataProvider implements TreeDataProvider<Github
return [
new EnvironmentsTreeItem(),
new SecretsTreeItem(),
new VariablesTreeItem()
new VariablesTreeItem(),
new InputsTreeItem()
];
}
}

View File

@@ -0,0 +1,18 @@
import { ThemeIcon, TreeItem, TreeItemCollapsibleState } from "vscode";
import { Variable } from "../../settingsManager";
import { GithubLocalActionsTreeItem } from "../githubLocalActionsTreeItem";
export default class VariableTreeItem extends TreeItem implements GithubLocalActionsTreeItem {
static contextValue = 'githubLocalActions.variable';
constructor(variable: Variable) {
super(variable.key, TreeItemCollapsibleState.None);
this.description = variable.value;
this.contextValue = VariableTreeItem.contextValue;
this.iconPath = new ThemeIcon('symbol-variable');
}
async getChildren(): Promise<GithubLocalActionsTreeItem[]> {
return [];
}
}

View File

@@ -1,5 +1,7 @@
import { ThemeIcon, TreeItem, TreeItemCollapsibleState } from "vscode";
import { act } from "../../extension";
import { GithubLocalActionsTreeItem } from "../githubLocalActionsTreeItem";
import VariableTreeItem from "./variable";
export default class VariablesTreeItem extends TreeItem implements GithubLocalActionsTreeItem {
static contextValue = 'githubLocalActions.variables';
@@ -11,6 +13,8 @@ export default class VariablesTreeItem extends TreeItem implements GithubLocalAc
}
async getChildren(): Promise<GithubLocalActionsTreeItem[]> {
return [];
const workflows = await act.workflowsManager.getWorkflows();
const variables = [...new Set(workflows.map(workflow => act.settingsManager.getVariables(workflow)).flat())];
return variables.map(variable => new VariableTreeItem(variable));
}
}

View File

@@ -6,7 +6,8 @@ import * as yaml from "yaml";
export interface Workflow {
name: string,
uri: Uri,
content?: any,
fileContent?: string,
yaml?: any,
error?: string
}
@@ -65,7 +66,8 @@ export class WorkflowsManager {
workflows.push({
name: yamlContent.name || path.parse(workflowFileUri.fsPath).name,
uri: workflowFileUri,
content: yaml.parse(fileContent)
fileContent: fileContent,
yaml: yaml.parse(fileContent)
});
} catch (error) {
workflows.push({