Skip to content

Commit 0fd7e48

Browse files
authored
Merge pull request #2803 from codefori/feature/modular_action_api
2 parents d7f9f6f + dc1ff7f commit 0fd7e48

File tree

1 file changed

+60
-41
lines changed

1 file changed

+60
-41
lines changed

src/ui/actions.ts

Lines changed: 60 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,12 @@ type CommandObject = {
2121
library?: string
2222
}
2323

24-
type ActionTarget = {
24+
export type ActionTarget = {
2525
uri: vscode.Uri
2626
extension: string
2727
fragment: string
2828
protected: boolean
29-
workspaceFolder: vscode.WorkspaceFolder
29+
workspaceFolder?: vscode.WorkspaceFolder
3030
executionOK: boolean,
3131
hasRun: boolean,
3232
processed: boolean,
@@ -42,6 +42,20 @@ export function registerActionTools(context: vscode.ExtensionContext) {
4242
);
4343
}
4444

45+
export function uriToActionTarget(uri: vscode.Uri, workspaceFolder?: WorkspaceFolder): ActionTarget {
46+
return {
47+
uri,
48+
extension: uri.path.substring(uri.path.lastIndexOf(`.`) + 1).toUpperCase(),
49+
fragment: uri.fragment.toUpperCase(),
50+
protected: parseFSOptions(uri).readonly || false,
51+
workspaceFolder: workspaceFolder || vscode.workspace.getWorkspaceFolder(uri),
52+
executionOK: false,
53+
hasRun: false,
54+
processed: false,
55+
output: []
56+
};
57+
}
58+
4559
export async function runAction(instance: Instance, uris: vscode.Uri | vscode.Uri[], customAction?: Action, method?: DeploymentMethod, browserItems?: BrowserItem[], workspaceFolder?: WorkspaceFolder): Promise<boolean> {
4660
uris = Array.isArray(uris) ? uris : [uris];
4761
//Global scheme: all URIs share the same
@@ -56,17 +70,7 @@ export async function runAction(instance: Instance, uris: vscode.Uri | vscode.Ur
5670
const config = connection.getConfig();
5771
const content = connection.getContent();
5872

59-
const targets = uris.map(uri => ({
60-
uri,
61-
extension: uri.path.substring(uri.path.lastIndexOf(`.`) + 1).toUpperCase(),
62-
fragment: uri.fragment.toUpperCase(),
63-
protected: parseFSOptions(uri).readonly || config?.readOnlyMode,
64-
workspaceFolder: workspaceFolder || vscode.workspace.getWorkspaceFolder(uri),
65-
executionOK: false,
66-
hasRun: false,
67-
processed: false,
68-
output: []
69-
}) as ActionTarget);
73+
const targets = uris.map(uri => uriToActionTarget(uri, workspaceFolder));
7074

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

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

79-
let availableActions: { label: string; action: Action; }[] = [];
83+
let availableActions: AvailableAction[] = [];
8084
if (!customAction) {
8185
// First we grab a copy the predefined Actions in the VS Code settings
82-
const allActions = [...IBMi.connectionManager.get<Action[]>(`actions`) || []];
83-
84-
// Then, if we're being called from a local file
85-
// we fetch the Actions defined from the workspace.
86-
if (targets[0].workspaceFolder && scheme === `file`) {
87-
const localActions = await getLocalActions(targets[0].workspaceFolder);
88-
allActions.push(...localActions);
89-
}
90-
91-
// We make sure all extensions are uppercase
92-
allActions.forEach(action => {
93-
if (action.extensions) {
94-
action.extensions = action.extensions.map(ext => ext.toUpperCase());
95-
};
96-
});
97-
98-
// Then we get all the available Actions for the current context
99-
availableActions = allActions.filter(action => action.type === scheme)
100-
.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`))
101-
.filter(action => action.runOnProtected || !targets.some(t => t.protected))
102-
.sort((a, b) => (actionUsed.get(b.name) || 0) - (actionUsed.get(a.name) || 0))
103-
.map(action => ({
104-
label: action.name,
105-
action
106-
}));
86+
availableActions = await getAllAvailableActions(targets, scheme);
10787
}
10888

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

502482
// Process locally downloaded evfevent files:
503483
if (useLocalEvfevent) {
504-
refreshDiagnosticsFromLocal(instance, evfeventInfo);
484+
await refreshDiagnosticsFromLocal(instance, evfeventInfo);
505485
problemsFetched = true;
506486
}
507487
})
@@ -604,6 +584,45 @@ export async function runAction(instance: Instance, uris: vscode.Uri | vscode.Ur
604584
}
605585
}
606586

587+
export type AvailableAction = { label: string; action: Action; }
588+
589+
export async function getAllAvailableActions(targets: ActionTarget[], scheme: string) {
590+
const allActions = [...IBMi.connectionManager.get<Action[]>(`actions`) || []];
591+
592+
// Then, if we're being called from a local file
593+
// we fetch the Actions defined from the workspace.
594+
const firstWorkspace = targets[0].workspaceFolder;
595+
596+
// We need to make sure that all targets are from the same workspace
597+
if (firstWorkspace && firstWorkspace.uri.scheme === `file`) {
598+
const workspaceId = firstWorkspace.index;
599+
const allTargetsInOne = targets.every(t => t.workspaceFolder?.index === workspaceId);
600+
601+
if (allTargetsInOne) {
602+
const localActions = await getLocalActions(firstWorkspace);
603+
allActions.push(...localActions);
604+
}
605+
}
606+
607+
// We make sure all extensions are uppercase
608+
allActions.forEach(action => {
609+
if (action.extensions) {
610+
action.extensions = action.extensions.map(ext => ext.toUpperCase());
611+
};
612+
});
613+
614+
// Then we get all the available Actions for the current context
615+
const availableActions: AvailableAction[] = allActions.filter(action => action.type === scheme)
616+
.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`))
617+
.filter(action => action.runOnProtected || !targets.some(t => t.protected))
618+
.sort((a, b) => (actionUsed.get(b.name) || 0) - (actionUsed.get(a.name) || 0))
619+
.map(action => ({
620+
label: action.name,
621+
action
622+
}));
623+
624+
return availableActions;
625+
}
607626

608627
function getObjectFromCommand(baseCommand?: string): CommandObject | undefined {
609628
if (baseCommand) {

0 commit comments

Comments
 (0)