From 0c488327db85f03678c23da68c0603cb8807cee6 Mon Sep 17 00:00:00 2001 From: Yury Shkoda Date: Thu, 4 May 2023 11:13:20 +0300 Subject: [PATCH 1/2] feat(execute): save webout, log, print and code after completion --- .../execute-code/ExecuteCodeCommand.ts | 56 ++++++++++++++----- src/utils/executeCode.ts | 5 +- src/utils/file.ts | 4 ++ src/utils/utils.ts | 5 +- 4 files changed, 50 insertions(+), 20 deletions(-) diff --git a/src/commands/execute-code/ExecuteCodeCommand.ts b/src/commands/execute-code/ExecuteCodeCommand.ts index abc0938..73bb27e 100644 --- a/src/commands/execute-code/ExecuteCodeCommand.ts +++ b/src/commands/execute-code/ExecuteCodeCommand.ts @@ -1,10 +1,19 @@ import { window, ExtensionContext, commands } from 'vscode' import { getEditorContent } from '../../utils/editor' -import { selectTarget } from '../../utils/target' -import { createAndOpenLogFile, handleErrorResponse } from '../../utils/utils' +import { + createAndOpenLogFile, + handleErrorResponse, + getTimestamp +} from '../../utils/utils' import { executeCode } from '../../utils/executeCode' -import { updateSasjsConstants } from '../../utils/setConstants' import { TargetCommand } from '../../types/commands/targetCommand' +import { ScriptExecutionResult } from '@sasjs/adapter' +import { createFile, createFolder } from '../../utils/file' +import * as path from 'path' + +interface ExecutionArtifacts extends ScriptExecutionResult { + code?: string +} export class ExecuteCodeCommand extends TargetCommand { constructor(private context: ExtensionContext) { @@ -29,17 +38,21 @@ export class ExecuteCodeCommand extends TargetCommand { } const execFilePath = window.activeTextEditor?.document.fileName - const sasCodeInjection = `options set=SAS_EXECFILEPATH "${execFilePath}";` - - const currentFileContent = `${sasCodeInjection}\n${getEditorContent()}` + const editorContent = getEditorContent() + const currentFileContent = `${sasCodeInjection}\n${editorContent}` commands.executeCommand('setContext', 'isSasjsCodeExecuting', true) await executeCode(target, currentFileContent || '') - .then(async ({ log }) => { + .then(async (res) => { process.outputChannel.appendLine('SASjs: Code executed successfully!') - await handleSuccessResponse(log) + + if (typeof res.log === 'object') { + res.log = JSON.stringify(res.log, null, 2) + } + + await this.saveExecutionArtifacts({ ...res, code: editorContent }) }) .catch(async (err) => { await handleErrorResponse(err, 'Error executing code') @@ -48,14 +61,27 @@ export class ExecuteCodeCommand extends TargetCommand { commands.executeCommand('setContext', 'isSasjsCodeExecuting', false) }) } -} -const handleSuccessResponse = async (log: any) => { - if (typeof log === 'object') { - return await createAndOpenLogFile(JSON.stringify(log, null, 2)) - } + private saveExecutionArtifacts = async (result: ExecutionArtifacts) => { + const { buildDestinationResultsFolder: resultsFolder } = + process.sasjsConstants + const timestamp = getTimestamp() + const folderPath = path.join(resultsFolder, timestamp) + + await createFolder(folderPath) + + const { log, webout, printOutput, code } = result + + if (webout) { + await createFile(path.join(folderPath, 'webout.txt'), webout) + } + if (printOutput) { + await createFile(path.join(folderPath, 'print.lst'), printOutput) + } + if (code) { + await createFile(path.join(folderPath, 'code.sas'), code) + } - if (typeof log === 'string') { - return await createAndOpenLogFile(log) + await createAndOpenLogFile(log, path.join(folderPath, 'log.log')) } } diff --git a/src/utils/executeCode.ts b/src/utils/executeCode.ts index eef0958..1007149 100644 --- a/src/utils/executeCode.ts +++ b/src/utils/executeCode.ts @@ -1,6 +1,7 @@ import { Target, ServerType, decodeFromBase64 } from '@sasjs/utils' import { getAuthConfig, getAuthConfigSas9 } from './config' import { getSASjs } from './getSASjs' +import { ScriptExecutionResult } from '@sasjs/adapter' export const executeCode = async (target: Target, code: string) => { if (target.serverType === ServerType.SasViya) { @@ -55,11 +56,11 @@ const executeOnSasJS = async (target: Target, code: string) => { const sasjs = getSASjs(target) const authConfig = await getAuthConfig(target) - const executionResult = await sasjs.executeScript({ + const executionResult: ScriptExecutionResult = await sasjs.executeScript({ linesOfCode: code.split('\n'), runTime: 'sas', authConfig }) - return { log: executionResult } + return executionResult } diff --git a/src/utils/file.ts b/src/utils/file.ts index 96596d9..7951335 100644 --- a/src/utils/file.ts +++ b/src/utils/file.ts @@ -9,3 +9,7 @@ export async function readFile(filePath: string) { .readFile(Uri.file(filePath)) .then((content) => Buffer.from(content).toString('utf8')) } + +export async function createFolder(filePath: string) { + return await workspace.fs.createDirectory(Uri.file(filePath)) +} diff --git a/src/utils/utils.ts b/src/utils/utils.ts index fb315b9..6bfc4e0 100644 --- a/src/utils/utils.ts +++ b/src/utils/utils.ts @@ -5,7 +5,6 @@ import { window, workspace, ViewColumn } from 'vscode' import { Target, timestampToYYYYMMDDHHMMSS, - fileExists, folderExists, copy } from '@sasjs/utils' @@ -103,12 +102,12 @@ export const handleErrorResponse = async (e: any, message: string) => { } } -export const createAndOpenLogFile = async (log: string) => { +export const createAndOpenLogFile = async (log: string, filePath?: string) => { const { buildDestinationResultsFolder: resultsFolder } = process.sasjsConstants const timestamp = getTimestamp() - const resultsPath = path.join(resultsFolder, `${timestamp}.log`) + const resultsPath = filePath || path.join(resultsFolder, `${timestamp}.log`) process.outputChannel.appendLine( `SASjs: Attempting to create log file at ${resultsPath}.` From dde7aee601398d9e69b6ff516542fc97f6662e88 Mon Sep 17 00:00:00 2001 From: Yury Shkoda Date: Thu, 4 May 2023 12:56:02 +0300 Subject: [PATCH 2/2] chore(deps): bumped @sasjs/adapter --- package-lock.json | 36 +++++++++++++++++++----------------- package.json | 2 +- 2 files changed, 20 insertions(+), 18 deletions(-) diff --git a/package-lock.json b/package-lock.json index 130311e..8e361f5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "version": "1.0.0", "hasInstallScript": true, "dependencies": { - "@sasjs/adapter": "4.1.2", + "@sasjs/adapter": "4.3.3", "@sasjs/cli": "4.1.1", "@sasjs/lint": "2.3.1", "@sasjs/utils": "3.2.0", @@ -537,13 +537,13 @@ } }, "node_modules/@sasjs/adapter": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/@sasjs/adapter/-/adapter-4.1.2.tgz", - "integrity": "sha512-2IwUfbewvCJEubXGk7uocB32DH+R6DKm5jf4o/sU3qLFp74C8ayqQng7h8ccT2ah7M7Sh6FSlkJaYwlkoWoiRQ==", + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@sasjs/adapter/-/adapter-4.3.3.tgz", + "integrity": "sha512-WVaJA4uAGTehi2Duz9gIfVWpCZDTHuk7YL6qVtRj2cH0Gc6MqnGYVYW7awmEWO55t1Kmx2LqdJ16dSKpy/GnVw==", "hasInstallScript": true, "dependencies": { "@sasjs/utils": "2.52.0", - "axios": "0.26.0", + "axios": "0.27.2", "axios-cookiejar-support": "1.0.1", "form-data": "4.0.0", "https": "1.0.0", @@ -571,11 +571,12 @@ } }, "node_modules/@sasjs/adapter/node_modules/axios": { - "version": "0.26.0", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.26.0.tgz", - "integrity": "sha512-lKoGLMYtHvFrPVt3r+RBMp9nh34N0M8zEfCWqdWZx6phynIEhQqAdydpyBAAG211zlhX9Rgu08cOamy6XjE5Og==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.27.2.tgz", + "integrity": "sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==", "dependencies": { - "follow-redirects": "^1.14.8" + "follow-redirects": "^1.14.9", + "form-data": "^4.0.0" } }, "node_modules/@sasjs/adapter/node_modules/chalk": { @@ -11580,12 +11581,12 @@ } }, "@sasjs/adapter": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/@sasjs/adapter/-/adapter-4.1.2.tgz", - "integrity": "sha512-2IwUfbewvCJEubXGk7uocB32DH+R6DKm5jf4o/sU3qLFp74C8ayqQng7h8ccT2ah7M7Sh6FSlkJaYwlkoWoiRQ==", + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@sasjs/adapter/-/adapter-4.3.3.tgz", + "integrity": "sha512-WVaJA4uAGTehi2Duz9gIfVWpCZDTHuk7YL6qVtRj2cH0Gc6MqnGYVYW7awmEWO55t1Kmx2LqdJ16dSKpy/GnVw==", "requires": { "@sasjs/utils": "2.52.0", - "axios": "0.26.0", + "axios": "0.27.2", "axios-cookiejar-support": "1.0.1", "form-data": "4.0.0", "https": "1.0.0", @@ -11612,11 +11613,12 @@ } }, "axios": { - "version": "0.26.0", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.26.0.tgz", - "integrity": "sha512-lKoGLMYtHvFrPVt3r+RBMp9nh34N0M8zEfCWqdWZx6phynIEhQqAdydpyBAAG211zlhX9Rgu08cOamy6XjE5Og==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.27.2.tgz", + "integrity": "sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==", "requires": { - "follow-redirects": "^1.14.8" + "follow-redirects": "^1.14.9", + "form-data": "^4.0.0" } }, "chalk": { diff --git a/package.json b/package.json index 338af45..2ede9a4 100644 --- a/package.json +++ b/package.json @@ -250,7 +250,7 @@ "vscode-test": "^1.6.1" }, "dependencies": { - "@sasjs/adapter": "4.1.2", + "@sasjs/adapter": "4.3.3", "@sasjs/cli": "4.1.1", "@sasjs/lint": "2.3.1", "@sasjs/utils": "3.2.0",