Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for local and server profiles and actions #2341

Draft
wants to merge 13 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 20 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,13 @@
".vscode/actions.json"
],
"url": "./schemas/actions.json"
},
{
"fileMatch": [
".vscode/profiles.json",
"/.vscode/profiles.json"
],
"url": "./schemas/profiles.json"
}
],
"configuration": {
Expand Down Expand Up @@ -1242,6 +1249,13 @@
"category": "IBM i",
"icon": "$(arrow-circle-right)"
},
{
"command": "code-for-ibmi.profiles.copyAsJson",
"enablement": "code-for-ibmi:connected",
"title": "Copy as JSON",
"category": "IBM i",
"icon": "$(clippy)"
},
{
"command": "code-for-ibmi.searchSourceFile",
"enablement": "code-for-ibmi:connected",
Expand Down Expand Up @@ -2536,7 +2550,7 @@
},
{
"command": "code-for-ibmi.loadConnectionProfile",
"when": "view == profilesView && viewItem == profile",
"when": "view == profilesView && (viewItem == profile || viewItem == localProfile)",
"group": "inline"
},
{
Expand Down Expand Up @@ -2579,6 +2593,11 @@
"when": "view == profilesView && viewItem == profile",
"group": "profiles@1"
},
{
"command": "code-for-ibmi.profiles.copyAsJson",
"when": "view == profilesView && viewItem == profile",
"group": "profiles@3"
},
{
"command": "code-for-ibmi.manageCommandProfile",
"when": "view == profilesView && viewItem == commandProfile",
Expand Down
12 changes: 12 additions & 0 deletions schemas/actions.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,18 @@
"description": "The command that will be run when executing this Action.",
"default": ""
},
"type": {
"$id": "#/actions/items/anyOf/0/properties/type",
"type": "string",
"title": "File system type",
"description": "Which environment the command will run in.",
"default": "file",
"enum": [
"file",
"member",
"streamfile"
]
},
"environment": {
"$id": "#/actions/items/anyOf/0/properties/commandEnvironment",
"type": "string",
Expand Down
93 changes: 93 additions & 0 deletions schemas/profiles.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"definitions": {
"FilterType": {
"type": "string",
"enum": ["simple", "regex"]
},
"ObjectFilters": {
"type": "object",
"properties": {
"name": { "type": "string" },
"filterType": { "$ref": "#/definitions/FilterType" },
"library": { "type": "string" },
"object": { "type": "string" },
"types": {
"type": "array",
"items": { "type": "string" }
},
"member": { "type": "string" },
"memberType": { "type": "string" },
"protected": { "type": "boolean" }
},
"required": ["name", "filterType", "library", "object", "types", "member", "memberType", "protected"]
},
"CustomVariable": {
"type": "object",
"properties": {
"name": { "type": "string" },
"value": { "type": "string" }
},
"required": ["name", "value"]
},
"ConnectionProfile": {
"type": "object",
"properties": {
"name": { "type": "string" },
"homeDirectory": { "type": "string" },
"currentLibrary": { "type": "string" },
"libraryList": {
"type": "array",
"items": { "type": "string" }
},
"objectFilters": {
"type": "array",
"items": { "$ref": "#/definitions/ObjectFilters" }
},
"ifsShortcuts": {
"type": "array",
"items": { "type": "string" }
},
"customVariables": {
"type": "array",
"items": { "$ref": "#/definitions/CustomVariable" }
}
},
"required": ["name"]
},
"TopLevel": {
"type": "object",
"properties": {
"profiles": {
"type": "array",
"items": {
"type": "object",
"properties": {
"name": { "type": "string" },
"homeDirectory": { "type": "string" },
"currentLibrary": { "type": "string" },
"libraryList": {
"type": "array",
"items": { "type": "string" }
},
"objectFilters": {
"type": "array",
"items": { "$ref": "#/definitions/ObjectFilters" }
},
"ifsShortcuts": {
"type": "array",
"items": { "type": "string" }
},
"customVariables": {
"type": "array",
"items": { "$ref": "#/definitions/CustomVariable" }
}
}
}
worksofliam marked this conversation as resolved.
Show resolved Hide resolved
}
},
"required": ["profiles"]
}
},
"$ref": "#/definitions/TopLevel"
}
7 changes: 4 additions & 3 deletions src/api/CompileTools.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import IBMi from './IBMi';
import Instance from './Instance';
import { Tools } from './Tools';
import { EvfEventInfo, refreshDiagnosticsFromLocal, refreshDiagnosticsFromServer, registerDiagnostics } from './errors/diagnostics';
import { getLocalActions } from './local/actions';
import { DeployTools } from './local/deployTools';
import { getBranchLibraryName, getEnvConfig } from './local/env';
import { getGitBranch } from './local/git';
Expand Down Expand Up @@ -102,8 +101,10 @@ export namespace CompileTools {
// Then, if we're being called from a local file
// we fetch the Actions defined from the workspace.
if (workspaceFolder && uri.scheme === `file`) {
const localActions = await getLocalActions(workspaceFolder);
allActions.push(...localActions);
const localActions = await connection.getConfigFile<Action[]>(`actions`).get(workspaceFolder);
if (localActions) {
allActions.push(...localActions);
}
}

// We make sure all extensions are uppercase
Expand Down
42 changes: 41 additions & 1 deletion src/api/IBMi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { IBMiComponent } from "../components/component";
import { CopyToImport } from "../components/copyToImport";
import { CustomQSh } from '../components/cqsh';
import { ComponentManager } from "../components/manager";
import { CommandData, CommandResult, ConnectionData, IBMiMember, RemoteCommand, WrapResult } from "../typings";
import { Action, CommandData, CommandResult, ConnectionData, IBMiMember, RemoteCommand, WrapResult } from "../typings";
import { CompileTools } from "./CompileTools";
import { ConnectionConfiguration } from "./Configuration";
import IBMiContent from "./IBMiContent";
Expand All @@ -17,6 +17,9 @@ import { Tools } from './Tools';
import * as configVars from './configVars';
import { DebugConfiguration } from "./debug/config";
import { debugPTFInstalled } from "./debug/server";
import { ConfigFile } from './config/configFile';
import { getProfilesConfig, ProfilesConfigFile } from './config/profiles';
import { getActionsConfig } from './config/actions';

export interface MemberParts extends IBMiMember {
basename: string
Expand Down Expand Up @@ -53,6 +56,11 @@ const remoteApps = [ // All names MUST also be defined as key in 'remoteFeatures

type DisconnectCallback = (conn: IBMi) => Promise<void>;

interface ConnectionConfigFiles {
profiles: ConfigFile<ProfilesConfigFile>
actions: ConfigFile<Action[]>
worksofliam marked this conversation as resolved.
Show resolved Hide resolved
}

export default class IBMi {
static readonly CCSID_NOCONVERSION = 65535;
static readonly CCSID_SYSVAL = -2;
Expand All @@ -71,6 +79,12 @@ export default class IBMi {
* @deprecated Will become private in v3.0.0 - use {@link IBMi.getConfig} instead.
*/
config?: ConnectionConfiguration.Parameters;

private configFiles: ConnectionConfigFiles = {
profiles: getProfilesConfig(this),
actions: getActionsConfig(this)
}

/**
* @deprecated Will become private in v3.0.0 - use {@link IBMi.getContent} instead.
*/
Expand Down Expand Up @@ -115,6 +129,10 @@ export default class IBMi {
this.disconnectedCallback = callback;
}

getConfigFile<T>(id: keyof ConnectionConfigFiles) {
return this.configFiles[id] as ConfigFile<T>;
}

get canUseCqsh() {
return this.getComponent(CustomQSh.ID) !== undefined;
}
Expand Down Expand Up @@ -482,6 +500,14 @@ export default class IBMi {
}
this.appendOutput(`\n`);

// Next, load in all the config files!

progress.report({
message: `Loading remote configuration files.`
});

await this.loadRemoteConfigs();

progress.report({
message: `Checking library list configuration.`
});
Expand Down Expand Up @@ -1127,6 +1153,20 @@ export default class IBMi {
}
}

async loadRemoteConfigs() {
for (const configFile in this.configFiles) {
const currentConfig = this.configFiles[configFile as keyof ConnectionConfigFiles];

this.configFiles[configFile as keyof ConnectionConfigFiles].reset();

try {
await this.configFiles[configFile as keyof ConnectionConfigFiles].loadFromServer();
} catch (e) { }

this.appendOutput(`${configFile} config state: ` + JSON.stringify(currentConfig.getState()) + `\n`);
}
}

/**
* Can return 0 if the OS version was not detected.
*/
Expand Down
37 changes: 37 additions & 0 deletions src/api/config/actions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { Action } from "../../typings";
import { ConnectionConfiguration } from "../Configuration";
import IBMi from "../IBMi";
import { ConfigFile } from "./configFile";

export function getActionsConfig(connection: IBMi) {
const ActionsConfig = new ConfigFile<Action[]>(connection, `actions`);

ActionsConfig.hasServerFile = true;
ActionsConfig.mergeArrays = true;

ActionsConfig.validateAndCleanInPlace = (loadedConfig) => {
let actions: Action[] = [];
// Maybe one day replace this with real schema validation
if (Array.isArray(loadedConfig)) {
loadedConfig.forEach((action, index) => {
if (
typeof action.name === `string` &&
typeof action.command === `string` &&
[`ile`, `pase`, `qsh`].includes(action.environment) &&
Array.isArray(action.extensions)
) {
actions.push({
type: `file`,
...action,
});
} else {
throw new Error(`Invalid Action defined at index ${index}.`);
}
})
}

return actions;
}

return ActionsConfig;
}
Loading
Loading