Skip to content

Commit

Permalink
Merge pull request #2175 from codefori/feature/local_temp_member
Browse files Browse the repository at this point in the history
Compile non-IFS sources from local
  • Loading branch information
worksofliam authored Jul 22, 2024
2 parents 0933ae7 + e5d4c95 commit e265f56
Show file tree
Hide file tree
Showing 7 changed files with 91 additions and 3 deletions.
34 changes: 34 additions & 0 deletions src/api/CompileTools.ts
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,11 @@ export namespace CompileTools {
evfeventInfo.object = name.toUpperCase();
evfeventInfo.extension = ext;

if (chosenAction.command.includes(`&SRCFILE`)) {
variables[`&SRCLIB`] = evfeventInfo.library;
variables[`&SRCPF`] = `QTMPSRC`;
variables[`&SRCFILE`] = `${evfeventInfo.library}/QTMPSRC`;
}

switch (chosenAction.type) {
case `file`:
Expand Down Expand Up @@ -330,6 +335,35 @@ export namespace CompileTools {
try {
writeEmitter.fire(`Running Action: ${chosenAction.name} (${new Date().toLocaleTimeString()})` + NEWLINE);

// If &SRCFILE is set, we need to copy the file to a temporary source file from the IFS
if (variables[`&FULLPATH`] && variables[`&SRCFILE`] && evfeventInfo.object) {
const [lib, srcpf] = variables[`&SRCFILE`].split(`/`);

const createSourceFile = content.toCl(`CRTSRCPF`, {
rcdlen: 112, //NICE: this configurable in a VS Code setting?
file: `${lib}/${srcpf}`,
});

const copyFromStreamfile = content.toCl(`CPYFRMSTMF`, {
fromstmf: variables[`&FULLPATH`],
tombr: `'${Tools.qualifyPath(lib, srcpf, evfeventInfo.object)}'`,
mbropt: `*REPLACE`,
dbfccsid: `*FILE`,
stmfccsid: 1208,
});

// We don't care if this fails. Usually it's because the source file already exists.
await runCommand(instance, {command: createSourceFile, environment: `ile`, noLibList: true});

// Attempt to copy to member
const copyResult = await runCommand(instance, {command: copyFromStreamfile, environment: `ile`, noLibList: true});

if (copyResult.code !== 0) {
writeEmitter.fire(`Failed to copy file to a temporary member.\n\t${copyResult.stderr}\n\n`);
closeEmitter.fire(copyResult.code || 1);
}
}

const commandResult = await runCommand(instance, {
title: chosenAction.name,
environment,
Expand Down
5 changes: 4 additions & 1 deletion src/api/IBMi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1059,7 +1059,10 @@ export default class IBMi {

this.appendOutput(JSON.stringify(result, null, 4) + `\n\n`);

return result;
return {
...result,
code: result.code || 0,
};
}

private appendOutput(content: string) {
Expand Down
5 changes: 5 additions & 0 deletions src/api/Tools.ts
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,11 @@ export namespace Tools {
return possibleDoc;
}

export function findExistingDocumentByName(nameAndExt: string) {
const possibleDoc = vscode.workspace.textDocuments.find(document => document.fileName.toLowerCase().endsWith(nameAndExt.toLowerCase()));
return possibleDoc ? possibleDoc.uri : undefined;
}

/**
* We convert member to lowercase as members are case insensitive.
*/
Expand Down
12 changes: 12 additions & 0 deletions src/api/errors/diagnostics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,18 @@ export function handleEvfeventLines(lines: string[], instance: Instance, evfeven
}
continue;
}

// If we get there, that means that even though we compiled from local, we likely had to use a temp member.
// We should try to find the file in the workspace. Since we can use findFile (it's async), then we look for open
// tabs like we do below.
if (evfeventInfo.extension) {
const baseName = file.split(`/`).pop();
const openFile = Tools.findExistingDocumentByName(`${baseName}.${evfeventInfo.extension}`);
if (openFile) {
ileDiagnostics.set(openFile, diagnostics);
continue;
}
}
}
}

Expand Down
11 changes: 11 additions & 0 deletions src/api/local/LocalLanguageActions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,17 @@ export const LocalLanguageActions: Record<string, Action[]> = {
environment: `ile`,
}
],
DSPF: [
{
"name": "Create DSPF",
"command": "CRTDSPF FILE(&CURLIB/&NAME) SRCFILE(&SRCFILE) RSTDSP(*NO) OPTION(*EVENTF)",
"environment": "ile",
"deployFirst": true,
"extensions": [
"dspf"
]
}
],
"Service Programs": [
{
"extensions": [
Expand Down
25 changes: 24 additions & 1 deletion src/testing/action.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,15 @@ export const helloWorldProject: Folder = {
name: `DeleteMe_${Tools.makeid()}`,
files: [
new File("hello.pgm.rpgle", ['**free', 'dsply \'Hello World\';', 'return;']),
new File("thebadone.pgm.rpgle", ['**free', 'dsply Hello world;', 'return;'])
new File("thebadone.pgm.rpgle", ['**free', 'dsply Hello world;', 'return;']),
new File("ugly.dspf", [
` A INDARA`,
` A CA12(12)`,
` A R DETAIL `,
` A 6 10'ID'`,
` A DSPATR(HI)`,
` A DSPATR(UL)`,
])
],
}

Expand Down Expand Up @@ -72,6 +80,21 @@ export const ActionSuite: TestSuite = {
await testHelloWorldProgram(uri, action, currentLibrary);
}
},
{
name: `Create display file (from local, custom action)`, test: async () => {
const uri = helloWorldProject.files![2].localPath!;
const action: Action = {
command: `CRTDSPF FILE(&CURLIB/&NAME) SRCFILE(&SRCFILE) TEXT('DSPF from local')`,
environment: `ile`,
type: `file`,
name: `Create Display File (CRTDSPF)`,
};

const success = await CompileTools.runAction(instance, uri, action, `all`);
console.log(success);
assert.ok(success);
}
},
{
name: `Create Bound RPG Program (from IFS, custom action)`, test: async () => {
const action: Action = {
Expand Down
2 changes: 1 addition & 1 deletion src/typings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ export interface CommandData extends StandardIO {
}

export interface CommandResult {
code: number | null;
code: number;
stdout: string;
stderr: string;
command?: string;
Expand Down

0 comments on commit e265f56

Please sign in to comment.