Skip to content
Merged
Changes from all 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
101 changes: 60 additions & 41 deletions src/ui/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,12 @@ type CommandObject = {
library?: string
}

type ActionTarget = {
export type ActionTarget = {
uri: vscode.Uri
extension: string
fragment: string
protected: boolean
workspaceFolder: vscode.WorkspaceFolder
workspaceFolder?: vscode.WorkspaceFolder
executionOK: boolean,
hasRun: boolean,
processed: boolean,
Expand All @@ -42,6 +42,20 @@ export function registerActionTools(context: vscode.ExtensionContext) {
);
}

export function uriToActionTarget(uri: vscode.Uri, workspaceFolder?: WorkspaceFolder): ActionTarget {
return {
uri,
extension: uri.path.substring(uri.path.lastIndexOf(`.`) + 1).toUpperCase(),
fragment: uri.fragment.toUpperCase(),
protected: parseFSOptions(uri).readonly || false,
workspaceFolder: workspaceFolder || vscode.workspace.getWorkspaceFolder(uri),
executionOK: false,
hasRun: false,
processed: false,
output: []
};
}

export async function runAction(instance: Instance, uris: vscode.Uri | vscode.Uri[], customAction?: Action, method?: DeploymentMethod, browserItems?: BrowserItem[], workspaceFolder?: WorkspaceFolder): Promise<boolean> {
uris = Array.isArray(uris) ? uris : [uris];
//Global scheme: all URIs share the same
Expand All @@ -56,17 +70,7 @@ export async function runAction(instance: Instance, uris: vscode.Uri | vscode.Ur
const config = connection.getConfig();
const content = connection.getContent();

const targets = uris.map(uri => ({
uri,
extension: uri.path.substring(uri.path.lastIndexOf(`.`) + 1).toUpperCase(),
fragment: uri.fragment.toUpperCase(),
protected: parseFSOptions(uri).readonly || config?.readOnlyMode,
workspaceFolder: workspaceFolder || vscode.workspace.getWorkspaceFolder(uri),
executionOK: false,
hasRun: false,
processed: false,
output: []
}) as ActionTarget);
const targets = uris.map(uri => uriToActionTarget(uri, workspaceFolder));

workspaceFolder = targets[0].workspaceFolder;
if (!targets.every(target => target.workspaceFolder === workspaceFolder)) {
Expand All @@ -76,34 +80,10 @@ export async function runAction(instance: Instance, uris: vscode.Uri | vscode.Ur

let remoteCwd = config?.homeDirectory || `.`;

let availableActions: { label: string; action: Action; }[] = [];
let availableActions: AvailableAction[] = [];
if (!customAction) {
// First we grab a copy the predefined Actions in the VS Code settings
const allActions = [...IBMi.connectionManager.get<Action[]>(`actions`) || []];

// Then, if we're being called from a local file
// we fetch the Actions defined from the workspace.
if (targets[0].workspaceFolder && scheme === `file`) {
const localActions = await getLocalActions(targets[0].workspaceFolder);
allActions.push(...localActions);
}

// We make sure all extensions are uppercase
allActions.forEach(action => {
if (action.extensions) {
action.extensions = action.extensions.map(ext => ext.toUpperCase());
};
});

// Then we get all the available Actions for the current context
availableActions = allActions.filter(action => action.type === scheme)
.filter(action => !action.extensions || action.extensions.every(e => !e) || targets.every(t => action.extensions!.includes(t.extension) || action.extensions!.includes(t.fragment)) || action.extensions.includes(`GLOBAL`))
.filter(action => action.runOnProtected || !targets.some(t => t.protected))
.sort((a, b) => (actionUsed.get(b.name) || 0) - (actionUsed.get(a.name) || 0))
.map(action => ({
label: action.name,
action
}));
availableActions = await getAllAvailableActions(targets, scheme);
}

if (customAction || availableActions.length) {
Expand Down Expand Up @@ -416,7 +396,7 @@ export async function runAction(instance: Instance, uris: vscode.Uri | vscode.Ur
else if (evfeventInfo.object && evfeventInfo.library) {
if (chosenAction.command.includes(`*EVENTF`)) {
writeEmitter.fire(`Fetching errors for ${evfeventInfo.library}/${evfeventInfo.object}.` + CompileTools.NEWLINE);
refreshDiagnosticsFromServer(instance, evfeventInfo);
await refreshDiagnosticsFromServer(instance, evfeventInfo);
problemsFetched = true;
} else if (chosenAction.command.trimStart().toUpperCase().startsWith(`CRT`)) {
writeEmitter.fire(`*EVENTF not found in command string. Not fetching errors for ${evfeventInfo.library}/${evfeventInfo.object}.` + CompileTools.NEWLINE);
Expand Down Expand Up @@ -501,7 +481,7 @@ export async function runAction(instance: Instance, uris: vscode.Uri | vscode.Ur

// Process locally downloaded evfevent files:
if (useLocalEvfevent) {
refreshDiagnosticsFromLocal(instance, evfeventInfo);
await refreshDiagnosticsFromLocal(instance, evfeventInfo);
problemsFetched = true;
}
})
Expand Down Expand Up @@ -604,6 +584,45 @@ export async function runAction(instance: Instance, uris: vscode.Uri | vscode.Ur
}
}

export type AvailableAction = { label: string; action: Action; }

export async function getAllAvailableActions(targets: ActionTarget[], scheme: string) {
const allActions = [...IBMi.connectionManager.get<Action[]>(`actions`) || []];

// Then, if we're being called from a local file
// we fetch the Actions defined from the workspace.
const firstWorkspace = targets[0].workspaceFolder;

// We need to make sure that all targets are from the same workspace
if (firstWorkspace && firstWorkspace.uri.scheme === `file`) {
const workspaceId = firstWorkspace.index;
const allTargetsInOne = targets.every(t => t.workspaceFolder?.index === workspaceId);

if (allTargetsInOne) {
const localActions = await getLocalActions(firstWorkspace);
allActions.push(...localActions);
}
}

// We make sure all extensions are uppercase
allActions.forEach(action => {
if (action.extensions) {
action.extensions = action.extensions.map(ext => ext.toUpperCase());
};
});

// Then we get all the available Actions for the current context
const availableActions: AvailableAction[] = allActions.filter(action => action.type === scheme)
.filter(action => !action.extensions || action.extensions.every(e => !e) || targets.every(t => action.extensions!.includes(t.extension) || action.extensions!.includes(t.fragment)) || action.extensions.includes(`GLOBAL`))
.filter(action => action.runOnProtected || !targets.some(t => t.protected))
.sort((a, b) => (actionUsed.get(b.name) || 0) - (actionUsed.get(a.name) || 0))
.map(action => ({
label: action.name,
action
}));

return availableActions;
}

function getObjectFromCommand(baseCommand?: string): CommandObject | undefined {
if (baseCommand) {
Expand Down
Loading