Add actions to create and locate setting files

Signed-off-by: Sanjula Ganepola <sanjulagane@gmail.com>
This commit is contained in:
Sanjula Ganepola
2024-11-22 20:17:35 -05:00
parent 2082c3c312
commit 3634e391cb
7 changed files with 191 additions and 63 deletions

View File

@@ -242,10 +242,16 @@
},
{
"category": "GitHub Local Actions",
"command": "githubLocalActions.addSecretFiles",
"title": "Add Secret Files",
"command": "githubLocalActions.createSecretFile",
"title": "Create Secret File",
"icon": "$(add)"
},
{
"category": "GitHub Local Actions",
"command": "githubLocalActions.locateSecretFiles",
"title": "Locate Secret Files",
"icon": "$(search)"
},
{
"category": "GitHub Local Actions",
"command": "githubLocalActions.show",
@@ -260,22 +266,34 @@
},
{
"category": "GitHub Local Actions",
"command": "githubLocalActions.addVariableFiles",
"title": "Add Variable Files",
"command": "githubLocalActions.createVariableFile",
"title": "Create Variable File",
"icon": "$(add)"
},
{
"category": "GitHub Local Actions",
"command": "githubLocalActions.locateVariableFiles",
"title": "Locate Variable Files",
"icon": "$(search)"
},
{
"category": "GitHub Local Actions",
"command": "githubLocalActions.createInputFile",
"title": "Create Input File",
"icon": "$(add)"
},
{
"category": "GitHub Local Actions",
"command": "githubLocalActions.locateInputFiles",
"title": "Locate Input Files",
"icon": "$(search)"
},
{
"category": "GitHub Local Actions",
"command": "githubLocalActions.importFromGithub",
"title": "Import from GitHub",
"icon": "$(github)"
},
{
"category": "GitHub Local Actions",
"command": "githubLocalActions.addInputFiles",
"title": "Add Input Files",
"icon": "$(add)"
},
{
"category": "GitHub Local Actions",
"command": "githubLocalActions.openSettingFile",
@@ -389,7 +407,11 @@
"when": "never"
},
{
"command": "githubLocalActions.addSecretFiles",
"command": "githubLocalActions.createSecretFile",
"when": "never"
},
{
"command": "githubLocalActions.locateSecretFiles",
"when": "never"
},
{
@@ -401,17 +423,25 @@
"when": "never"
},
{
"command": "githubLocalActions.addVariableFiles",
"command": "githubLocalActions.createVariableFile",
"when": "never"
},
{
"command": "githubLocalActions.locateVariableFiles",
"when": "never"
},
{
"command": "githubLocalActions.createInputFile",
"when": "never"
},
{
"command": "githubLocalActions.locateInputFiles",
"when": "never"
},
{
"command": "githubLocalActions.importFromGithub",
"when": "never"
},
{
"command": "githubLocalActions.addInputFiles",
"when": "never"
},
{
"command": "githubLocalActions.openSettingFile",
"when": "never"
@@ -556,10 +586,15 @@
"group": "inline@3"
},
{
"command": "githubLocalActions.addSecretFiles",
"command": "githubLocalActions.createSecretFile",
"when": "view == settings && viewItem =~ /^githubLocalActions.secrets.*/",
"group": "inline@0"
},
{
"command": "githubLocalActions.locateSecretFiles",
"when": "view == settings && viewItem =~ /^githubLocalActions.secrets.*/",
"group": "inline@1"
},
{
"command": "githubLocalActions.show",
"when": "view == settings && viewItem =~ /^githubLocalActions.secret(?!s)_hide.*/",
@@ -571,20 +606,30 @@
"group": "inline@0"
},
{
"command": "githubLocalActions.addVariableFiles",
"command": "githubLocalActions.createVariableFile",
"when": "view == settings && viewItem =~ /^githubLocalActions.variables.*/",
"group": "inline@0"
},
{
"command": "githubLocalActions.importFromGithub",
"command": "githubLocalActions.locateVariableFiles",
"when": "view == settings && viewItem =~ /^githubLocalActions.variables.*/",
"group": "inline@1"
},
{
"command": "githubLocalActions.addInputFiles",
"command": "githubLocalActions.createInputFile",
"when": "view == settings && viewItem =~ /^githubLocalActions.inputs.*/",
"group": "inline@0"
},
{
"command": "githubLocalActions.locateInputFiles",
"when": "view == settings && viewItem =~ /^githubLocalActions.inputs.*/",
"group": "inline@1"
},
{
"command": "githubLocalActions.importFromGithub",
"when": "view == settings && viewItem =~ /^githubLocalActions.variables.*/",
"group": "inline@2"
},
{
"command": "githubLocalActions.openSettingFile",
"when": "view == settings && viewItem =~ /^githubLocalActions.(secret|variable|input)File.*/",

View File

@@ -309,11 +309,11 @@ export class Act {
`set -o pipefail; ` +
`${Act.base} ${commandArgs.options}` +
(settings.secrets.length > 0 ? ` ${Option.Secret} ${settings.secrets.map(secret => secret.key).join(` ${Option.Secret} `)}` : ``) +
(settings.secretFiles.length > 0 ? ` ${Option.SecretFile} ${settings.secretFiles.map(secretFile => `"${secretFile.path}"`).join(` ${Option.SecretFile} `)}` : ``) +
(settings.secretFiles.length > 0 ? ` ${Option.SecretFile} ${settings.secretFiles[0].path}` : ` ${Option.SecretFile} ""`) +
(settings.variables.length > 0 ? ` ${Option.Variable} ${settings.variables.map(variable => (variable.value ? `${variable.key}=${variable.value}` : variable.key)).join(` ${Option.Variable} `)}` : ``) +
(settings.variableFiles.length > 0 ? ` ${Option.VariableFile} ${settings.variableFiles.map(variableFile => `"${variableFile.path}"`).join(` ${Option.VariableFile} `)}` : ``) +
(settings.variableFiles.length > 0 ? ` ${Option.VariableFile} ${settings.variableFiles[0].path}` : ` ${Option.VariableFile} ""`) +
(settings.inputs.length > 0 ? ` ${Option.Input} ${settings.inputs.map(input => `${input.key}=${input.value}`).join(` ${Option.Input} `)}` : ``) +
(settings.inputFiles.length > 0 ? ` ${Option.InputFile} ${settings.inputFiles.map(inputFile => `"${inputFile.path}"`).join(` ${Option.InputFile} `)}` : ``) +
(settings.inputFiles.length > 0 ? ` ${Option.InputFile} ${settings.inputFiles[0].path}` : ` ${Option.InputFile} ""`) +
(settings.runners.length > 0 ? ` ${Option.Platform} ${settings.runners.map(runner => `${runner.key}=${runner.value}`).join(` ${Option.Platform} `)}` : ``) +
` 2>&1 | tee "${logPath}"`;

View File

@@ -1,3 +1,4 @@
import * as path from "path";
import { Uri, window, workspace, WorkspaceFolder } from "vscode";
import { act } from "./extension";
import { GitHubManager } from "./githubManager";
@@ -34,6 +35,12 @@ export enum Visibility {
hide = 'hide'
}
export enum SettingFileName {
secretFile = '.secrets',
variableFile = '.env',
inputFile = '.input'
}
export class SettingsManager {
storageManager: StorageManager;
secretManager: SecretManager;
@@ -153,6 +160,48 @@ export class SettingsManager {
return environments;
}
async createSettingFile(workspaceFolder: WorkspaceFolder, storageKey: StorageKey, settingFileName: string) {
const settingFileUri = Uri.file(path.join(workspaceFolder.uri.fsPath, settingFileName));
try {
await workspace.fs.stat(settingFileUri);
window.showErrorMessage(`A file or folder named ${settingFileName} already exists at ${workspaceFolder.uri.fsPath}. Please choose another name.`);
} catch (error: any) {
try {
await workspace.fs.writeFile(settingFileUri, new TextEncoder().encode(''));
await this.locateSettingFile(workspaceFolder, storageKey, [settingFileUri]);
const document = await workspace.openTextDocument(settingFileUri);
await window.showTextDocument(document);
} catch (error: any) {
window.showErrorMessage(`Failed to create ${settingFileName}. Error: ${error}`)
}
}
}
async locateSettingFile(workspaceFolder: WorkspaceFolder, storageKey: StorageKey, settingFilesUris: Uri[]) {
const settingFilesPaths = (await act.settingsManager.getSettingFiles(workspaceFolder, storageKey)).map(settingFile => settingFile.path);
const existingSettingFileNames: string[] = [];
for await (const uri of settingFilesUris) {
const settingFileName = path.parse(uri.fsPath).name;
if (settingFilesPaths.includes(uri.fsPath)) {
existingSettingFileNames.push(settingFileName);
} else {
const newSettingFile: SettingFile = {
name: path.parse(uri.fsPath).base,
path: uri.fsPath,
selected: false
};
await act.settingsManager.editSettingFile(workspaceFolder, newSettingFile, storageKey);
}
}
if (existingSettingFileNames.length > 0) {
window.showErrorMessage(`The following file(s) have already been added: ${existingSettingFileNames.join(', ')}`);
}
}
async editSettingFile(workspaceFolder: WorkspaceFolder, newSettingFile: SettingFile, storageKey: StorageKey) {
const existingSettingFiles = this.storageManager.get<{ [path: string]: SettingFile[] }>(storageKey) || {};
if (existingSettingFiles[workspaceFolder.uri.fsPath]) {

View File

@@ -14,7 +14,7 @@ export default class InputsTreeItem extends TreeItem implements GithubLocalActio
super('Inputs', TreeItemCollapsibleState.Collapsed);
const selectedInputFiles = inputFiles.filter(inputFile => inputFile.selected);
this.description = `${inputs.filter(input => input.selected).length}/${inputs.length}` +
(selectedInputFiles.length > 0 ? ` + ${selectedInputFiles.length} input file(s)` : ``);
(selectedInputFiles.length > 0 ? ` + ${selectedInputFiles[0].name}` : ``);
this.contextValue = InputsTreeItem.contextValue;
this.iconPath = new ThemeIcon('record-keys');
}

View File

@@ -14,7 +14,7 @@ export default class SecretsTreeItem extends TreeItem implements GithubLocalActi
super('Secrets', TreeItemCollapsibleState.Collapsed);
const selectedSecretFiles = secretFiles.filter(secretFile => secretFile.selected);
this.description = `${secrets.filter(secret => secret.selected).length}/${secrets.length}` +
(selectedSecretFiles.length > 0 ? ` + ${selectedSecretFiles.length} secret file(s)` : ``);
(selectedSecretFiles.length > 0 ? ` + ${selectedSecretFiles[0].name}` : ``);
this.contextValue = SecretsTreeItem.contextValue;
this.iconPath = new ThemeIcon('lock');
}

View File

@@ -1,7 +1,6 @@
import * as path from "path";
import { CancellationToken, commands, EventEmitter, ExtensionContext, QuickPickItem, QuickPickItemKind, ThemeIcon, TreeCheckboxChangeEvent, TreeDataProvider, TreeItem, TreeItemCheckboxState, window, workspace } from "vscode";
import { act } from "../../extension";
import { SettingFile, Visibility } from "../../settingsManager";
import { SettingFileName, Visibility } from "../../settingsManager";
import { StorageKey } from "../../storageManager";
import { GithubLocalActionsTreeItem } from "../githubLocalActionsTreeItem";
import InputsTreeItem from "./inputs";
@@ -21,48 +20,83 @@ export default class SettingsTreeDataProvider implements TreeDataProvider<Github
commands.registerCommand('githubLocalActions.refreshSettings', async () => {
this.refresh();
}),
commands.registerCommand('githubLocalActions.addSettingFiles', async (treeItem: SecretsTreeItem | VariablesTreeItem | InputsTreeItem, title: string) => {
const settingFilesUris = await window.showOpenDialog({
title: title,
canSelectFiles: true,
canSelectFolders: false,
canSelectMany: true,
defaultUri: treeItem.workspaceFolder.uri
commands.registerCommand('githubLocalActions.createSecretFile', async (secretsTreeItem: SecretsTreeItem) => {
const secretFileName = await window.showInputBox({
prompt: `Enter the name for the secret file`,
placeHolder: `Secret File Name`,
value: SettingFileName.secretFile
});
if (settingFilesUris) {
const settingFilesPaths = (await act.settingsManager.getSettingFiles(treeItem.workspaceFolder, treeItem.storageKey)).map(settingFile => settingFile.path);
const existingSettingFileNames: string[] = [];
for await (const uri of settingFilesUris) {
const settingFileName = path.parse(uri.fsPath).name;
if (settingFilesPaths.includes(uri.fsPath)) {
existingSettingFileNames.push(settingFileName);
} else {
const newSettingFile: SettingFile = {
name: path.parse(uri.fsPath).base,
path: uri.fsPath,
selected: false
};
await act.settingsManager.editSettingFile(treeItem.workspaceFolder, newSettingFile, treeItem.storageKey);
}
}
if (existingSettingFileNames.length > 0) {
window.showErrorMessage(`The following file(s) have already been added: ${existingSettingFileNames.join(', ')}`);
}
if (secretFileName) {
await act.settingsManager.createSettingFile(secretsTreeItem.workspaceFolder, secretsTreeItem.storageKey, secretFileName);
this.refresh();
}
}),
commands.registerCommand('githubLocalActions.addSecretFiles', async (secretsTreeItem: SecretsTreeItem) => {
await commands.executeCommand('githubLocalActions.addSettingFiles', secretsTreeItem, 'Add Secret File');
commands.registerCommand('githubLocalActions.locateSecretFiles', async (secretsTreeItem: SecretsTreeItem) => {
const secretFilesUris = await window.showOpenDialog({
title: 'Locate Secret Files',
canSelectFiles: true,
canSelectFolders: false,
canSelectMany: true,
defaultUri: secretsTreeItem.workspaceFolder.uri
});
if (secretFilesUris) {
await act.settingsManager.locateSettingFile(secretsTreeItem.workspaceFolder, secretsTreeItem.storageKey, secretFilesUris);
this.refresh();
}
}),
commands.registerCommand('githubLocalActions.addVariableFiles', async (variablesTreeItem: VariablesTreeItem) => {
await commands.executeCommand('githubLocalActions.addSettingFiles', variablesTreeItem, 'Add Variable File');
commands.registerCommand('githubLocalActions.createVariableFile', async (variablesTreeItem: VariablesTreeItem) => {
const variableFileName = await window.showInputBox({
prompt: `Enter the name for the variable file`,
placeHolder: `Variable File Name`,
value: SettingFileName.variableFile
});
if (variableFileName) {
await act.settingsManager.createSettingFile(variablesTreeItem.workspaceFolder, variablesTreeItem.storageKey, variableFileName);
this.refresh();
}
}),
commands.registerCommand('githubLocalActions.addInputFiles', async (inputsTreeItem: InputsTreeItem) => {
await commands.executeCommand('githubLocalActions.addSettingFiles', inputsTreeItem, 'Add Input File');
commands.registerCommand('githubLocalActions.locateVariableFiles', async (variablesTreeItem: VariablesTreeItem) => {
const variableFilesUris = await window.showOpenDialog({
title: 'Locate Variable Files',
canSelectFiles: true,
canSelectFolders: false,
canSelectMany: true,
defaultUri: variablesTreeItem.workspaceFolder.uri
});
if (variableFilesUris) {
await act.settingsManager.locateSettingFile(variablesTreeItem.workspaceFolder, variablesTreeItem.storageKey, variableFilesUris);
this.refresh();
}
}),
commands.registerCommand('githubLocalActions.createInputFile', async (inputsTreeItem: InputsTreeItem) => {
const inputFileName = await window.showInputBox({
prompt: `Enter the name for the input file`,
placeHolder: `Input File Name`,
value: SettingFileName.inputFile
});
if (inputFileName) {
await act.settingsManager.createSettingFile(inputsTreeItem.workspaceFolder, inputsTreeItem.storageKey, inputFileName);
this.refresh();
}
}),
commands.registerCommand('githubLocalActions.locateInputFiles', async (inputsTreeItem: InputsTreeItem) => {
const inputFilesUris = await window.showOpenDialog({
title: 'Locate Variable Files',
canSelectFiles: true,
canSelectFolders: false,
canSelectMany: true,
defaultUri: inputsTreeItem.workspaceFolder.uri
});
if (inputFilesUris) {
await act.settingsManager.locateSettingFile(inputsTreeItem.workspaceFolder, inputsTreeItem.storageKey, inputFilesUris);
this.refresh();
}
}),
commands.registerCommand('githubLocalActions.openSettingFile', async (settingFileTreeItem: SettingFileTreeItem) => {
const document = await workspace.openTextDocument(settingFileTreeItem.settingFile.path);

View File

@@ -14,7 +14,7 @@ export default class VariablesTreeItem extends TreeItem implements GithubLocalAc
super('Variables', TreeItemCollapsibleState.Collapsed);
const selectedVariableFiles = variableFiles.filter(variableFile => variableFile.selected);
this.description = `${variables.filter(variable => variable.selected).length}/${variables.length}` +
(selectedVariableFiles.length > 0 ? ` + ${selectedVariableFiles.length} variable file(s)` : ``);
(selectedVariableFiles.length > 0 ? ` + ${selectedVariableFiles[0].name} variable file(s)` : ``);
this.contextValue = VariablesTreeItem.contextValue;
this.iconPath = new ThemeIcon('symbol-key');
}