-
-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #6 from sasjs/execute-code-button
feat(*): add execute code button, add default targets
- Loading branch information
Showing
9 changed files
with
231 additions
and
156 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
import SASjs from '@sasjs/adapter/node' | ||
import * as os from 'os' | ||
import * as path from 'path' | ||
import { | ||
window, | ||
ExtensionContext, | ||
commands, | ||
StatusBarAlignment, | ||
OutputChannel, | ||
ViewColumn, | ||
workspace, | ||
StatusBarItem | ||
} from 'vscode' | ||
import { getEditorContent } from '../../utils/editor' | ||
import { createFile } from '../../utils/file' | ||
import { selectTarget, getAccessToken } from './internal/configuration' | ||
import { getTimestamp } from './internal/utils' | ||
|
||
export class ExecuteCodeCommand { | ||
private outputChannel: OutputChannel | ||
private runSasCodeButton: StatusBarItem | ||
|
||
constructor(private context: ExtensionContext) { | ||
this.outputChannel = window.createOutputChannel('SASjs') | ||
} | ||
|
||
initialise = () => { | ||
const executeCodeCommand = commands.registerCommand( | ||
'sasjs-for-vscode.executeCode', | ||
() => this.executeCode() | ||
) | ||
this.context.subscriptions.push(executeCodeCommand) | ||
|
||
this.initialiseRunSasCodeButton() | ||
} | ||
|
||
private initialiseRunSasCodeButton = () => { | ||
this.runSasCodeButton = window.createStatusBarItem( | ||
StatusBarAlignment.Right, | ||
100 | ||
) | ||
this.runSasCodeButton.text = '$(notebook-execute) Run SAS code' | ||
this.runSasCodeButton.command = 'sasjs-for-vscode.executeCode' | ||
this.runSasCodeButton.show() | ||
this.context.subscriptions.push(this.runSasCodeButton) | ||
} | ||
|
||
private executeCode = async () => { | ||
this.outputChannel.appendLine('Initialising SASjs.') | ||
const target = await selectTarget(this.outputChannel) | ||
if (!target) { | ||
return | ||
} | ||
const accessToken = await getAccessToken(target) | ||
const currentFileContent = getEditorContent() | ||
|
||
const adapter = new SASjs({ | ||
serverUrl: target.serverUrl, | ||
serverType: target.serverType, | ||
appLoc: target.appLoc, | ||
contextName: target.contextName, | ||
useComputeApi: true, | ||
debug: true | ||
}) | ||
|
||
this.runSasCodeButton.text = '$(sync~spin) Running your SAS code' | ||
adapter | ||
.executeScriptSASViya( | ||
'vscode-test-exec', | ||
(currentFileContent || '').split('\n'), | ||
'', | ||
accessToken | ||
) | ||
.then(async (res) => { | ||
this.runSasCodeButton.text = | ||
'$(notebook-state-success) SAS code executed successfully!' | ||
|
||
const timeout = setTimeout(() => { | ||
this.runSasCodeButton.text = '$(notebook-execute) Run SAS code' | ||
clearTimeout(timeout) | ||
}, 3000) | ||
const timestamp = getTimestamp() | ||
const resultsPath = workspace.workspaceFolders?.length | ||
? path.join( | ||
workspace.workspaceFolders![0].uri.fsPath, | ||
'sasjsresults', | ||
`${timestamp}.log` | ||
) | ||
: path.join(os.homedir(), 'sasjsresults', `${timestamp}.log`) | ||
await createFile(resultsPath, res.log) | ||
const document = await workspace.openTextDocument(resultsPath) | ||
window.showTextDocument(document, { | ||
viewColumn: ViewColumn.Beside | ||
}) | ||
|
||
this.outputChannel.append(JSON.stringify(res, null, 2)) | ||
}) | ||
.catch((e) => { | ||
this.runSasCodeButton.text = | ||
'$(notebook-state-error) SAS code execution failed' | ||
const timeout = setTimeout(() => { | ||
this.runSasCodeButton.text = '$(notebook-execute) Run SAS code' | ||
clearTimeout(timeout) | ||
}, 3000) | ||
this.outputChannel.append(JSON.stringify(e, null, 2)) | ||
}) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
import { OutputChannel, env, Uri } from 'vscode' | ||
|
||
import SASjs from '@sasjs/adapter/node' | ||
import { Target, Configuration } from '@sasjs/utils/types' | ||
import { | ||
getAuthCode, | ||
getChoiceInput, | ||
getClientId, | ||
getClientSecret, | ||
getIsDefault, | ||
getServerType, | ||
getServerUrl, | ||
getTargetName | ||
} from '../../../utils/input' | ||
import { getAuthUrl, getTokens } from '../../../utils/auth' | ||
import { | ||
getGlobalConfiguration, | ||
saveGlobalRcFile, | ||
saveToGlobalConfig | ||
} from '../../../utils/config' | ||
|
||
export const selectTarget = async (outputChannel: OutputChannel) => { | ||
const config = await getGlobalConfiguration(outputChannel) as Configuration | ||
|
||
if (config?.targets?.length) { | ||
let targetName = config.targets.find((t) => t.name === config.defaultTarget)?.name | ||
if (!targetName) { | ||
const targetNames = (config?.targets || []).map((t: any) => t.name) | ||
targetName = await getChoiceInput(targetNames, 'Please select a target') | ||
} | ||
|
||
if (!targetName) { | ||
return | ||
} | ||
|
||
const selectedTarget = config.targets.find( | ||
(t: any) => t.name === targetName | ||
) | ||
return new Target(selectedTarget) | ||
} else { | ||
return await createTarget(outputChannel) | ||
} | ||
} | ||
|
||
export const createTarget = async (outputChannel: OutputChannel) => { | ||
const name = await getTargetName() | ||
const serverUrl = await getServerUrl() | ||
const serverType = await getServerType() | ||
const clientId = await getClientId() | ||
|
||
const clientSecret = await getClientSecret() | ||
|
||
env.openExternal(Uri.parse(getAuthUrl(serverUrl, clientId))) | ||
|
||
const authCode = await getAuthCode() | ||
|
||
const adapter = new SASjs({ | ||
serverUrl: serverUrl, | ||
serverType: serverType, | ||
appLoc: '/Public/app', | ||
useComputeApi: true, | ||
debug: true | ||
}) | ||
|
||
const authResponse = await getTokens( | ||
adapter, | ||
clientId, | ||
clientSecret, | ||
authCode | ||
) | ||
|
||
const isDefault = await getIsDefault() | ||
const target = new Target({ | ||
name, | ||
serverUrl, | ||
serverType, | ||
appLoc: '/Public/app', | ||
authConfig: authResponse, | ||
isDefault | ||
}) | ||
|
||
await saveToGlobalConfig(target, outputChannel) | ||
|
||
if (isDefault) { | ||
await setTargetAsDefault(name, outputChannel) | ||
} | ||
return target | ||
} | ||
|
||
export const getAccessToken = async (target: Target) => { | ||
return target.authConfig?.access_token | ||
} | ||
|
||
const setTargetAsDefault = async (targetName: string, outputChannel: OutputChannel) => { | ||
const globalConfig = await getGlobalConfiguration(outputChannel) | ||
globalConfig.defaultTarget = targetName | ||
await saveGlobalRcFile(JSON.stringify(globalConfig, null, 2)) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
import { timestampToYYYYMMDDHHMMSS } from '@sasjs/utils/time' | ||
|
||
export const getTimestamp = () => | ||
timestampToYYYYMMDDHHMMSS() | ||
.replace(/ /g, '') | ||
.replace(/\//g, '') | ||
.replace(/:/g, '') |
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.