Skip to content

Commit faa1289

Browse files
authored
Merge pull request #4 from sprodribaba/CTX-3998
Add initial Job run mechanism
2 parents e9b6fe0 + bd06e1c commit faa1289

File tree

6 files changed

+299
-100
lines changed

6 files changed

+299
-100
lines changed

media/projectViewScripts.js

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// Copyright (C) 2023 Coretex LLC
2+
3+
// This file is part of Coretex.ai
4+
5+
// This program is free software: you can redistribute it and/or modify
6+
// it under the terms of the GNU Affero General Public License as
7+
// published by the Free Software Foundation, either version 3 of the
8+
// License, or (at your option) any later version.
9+
10+
// This program is distributed in the hope that it will be useful,
11+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
// GNU Affero General Public License for more details.
14+
15+
// You should have received a copy of the GNU Affero General Public License
16+
// along with this program. If not, see <https://www.gnu.org/licenses/>.
17+
18+
// This script will be run within the webview itself
19+
// It cannot access the main VS Code APIs directly.
20+
(function () {
21+
const vscode = acquireVsCodeApi();
22+
23+
document.querySelector('.start-action').addEventListener('click', () => {
24+
onStartClicked();
25+
});
26+
27+
document.querySelector('.update-action-new').addEventListener('click', () => {
28+
onListNodesClicked();
29+
});
30+
31+
function onStartClicked() {
32+
vscode.postMessage({ type: 'start'});
33+
}
34+
35+
function onListNodesClicked() {
36+
vscode.postMessage({ type: 'nodes'});
37+
}
38+
}());
39+

package.json

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,16 @@
4141
"type": "string",
4242
"default": "",
4343
"description": "Your Node Storage Path"
44+
},
45+
"Space": {
46+
"type": "integer",
47+
"default": 0,
48+
"description": "Your Current Coretex Space"
49+
},
50+
"NodeID": {
51+
"type": "integer",
52+
"default": 0,
53+
"description": "Your Current Coretex Node"
4454
}
4555
}
4656
}
@@ -101,6 +111,10 @@
101111
{
102112
"command": "coretex.configureUser",
103113
"title": "Coretex: Log in"
114+
},
115+
{
116+
"command": "coretex.listNodes",
117+
"title": "Coretex: List Nodes"
104118
}
105119
],
106120
"views": {

src/commands/listNodes.ts

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
// Copyright (C) 2023 Coretex LLC
2+
3+
// This file is part of Coretex.ai
4+
5+
// This program is free software: you can redistribute it and/or modify
6+
// it under the terms of the GNU Affero General Public License as
7+
// published by the Free Software Foundation, either version 3 of the
8+
// License, or (at your option) any later version.
9+
10+
// This program is distributed in the hope that it will be useful,
11+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
// GNU Affero General Public License for more details.
14+
15+
// You should have received a copy of the GNU Affero General Public License
16+
// along with this program. If not, see <https://www.gnu.org/licenses/>.
17+
18+
import { ExecException, exec } from 'child_process';
19+
import * as vscode from 'vscode';
20+
21+
const listNodesCommand = vscode.commands.registerCommand(
22+
'coretex.listNodes',
23+
async () => {
24+
// Execute the config user command in the integrated terminal
25+
const command = getNodeListCommand();
26+
27+
vscode.window.terminals.forEach((terminal) => {
28+
terminal.dispose();
29+
});
30+
const terminal = vscode.window.createTerminal();
31+
terminal.show();
32+
terminal.sendText(command);
33+
}
34+
);
35+
36+
function getNodeListCommand(): string {
37+
const platform = process.platform;
38+
if (platform === 'darwin' || platform === 'linux') {
39+
return 'coretex node list';
40+
} else if (platform === 'win32') {
41+
return 'coretex.exe node list';
42+
}
43+
44+
throw new Error('Platform not supported.');
45+
}
46+
47+
export default listNodesCommand;

src/extension.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,11 @@ import openDocumentationPythonLibCommand from './commands/openDocumentationPytho
1414
import addParameterCommand from './commands/addParameter';
1515
import showNodeLogsCommand from './commands/showLogs';
1616
import configureUserCommand from './commands/configureUser';
17+
import listNodesCommand from './commands/listNodes';
1718

1819
import {CLIView} from './views/cliView';
1920
import {NodeView} from './views/nodeView';
20-
import {ProjectView} from './views/projectView.ts';
21+
import {ProjectView} from './views/projectView';
2122
import { HelpView } from './views/helpView';
2223
import { UserView } from './views/userView';
2324

@@ -38,6 +39,7 @@ export function activate(context: vscode.ExtensionContext) {
3839
context.subscriptions.push(addParameterCommand);
3940
context.subscriptions.push(showNodeLogsCommand);
4041
context.subscriptions.push(configureUserCommand);
42+
context.subscriptions.push(listNodesCommand);
4143

4244
// VIEWS
4345

src/views/projectView.ts

Lines changed: 196 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,196 @@
1+
// Copyright (C) 2023 Coretex LLC
2+
3+
// This file is part of Coretex.ai
4+
5+
// This program is free software: you can redistribute it and/or modify
6+
// it under the terms of the GNU Affero General Public License as
7+
// published by the Free Software Foundation, either version 3 of the
8+
// License, or (at your option) any later version.
9+
10+
// This program is distributed in the hope that it will be useful,
11+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
// GNU Affero General Public License for more details.
14+
15+
// You should have received a copy of the GNU Affero General Public License
16+
// along with this program. If not, see <https://www.gnu.org/licenses/>.
17+
18+
import * as vscode from 'vscode';
19+
import * as child_process from 'child_process';
20+
import { getNonce } from '../utilities/getNonce';
21+
22+
export class ProjectView implements vscode.WebviewViewProvider {
23+
viewId = 'coretex.project';
24+
private _view?: vscode.WebviewView;
25+
26+
constructor(private readonly _extensionUri: vscode.Uri) {}
27+
28+
public resolveWebviewView(webviewView: vscode.WebviewView): void {
29+
this._view = webviewView;
30+
31+
webviewView.webview.options = {
32+
// Allow scripts in the webview
33+
enableScripts: true,
34+
35+
localResourceRoots: [
36+
this._extensionUri
37+
]
38+
};
39+
40+
this.updateView();
41+
42+
this._view.onDidChangeVisibility(async event => {
43+
this.updateView();
44+
});
45+
46+
this._view.webview.onDidReceiveMessage(data => {
47+
this.runCommand(data);
48+
});
49+
}
50+
51+
private updateView(): void {
52+
if (!this._view) {
53+
return;
54+
}
55+
56+
const storagePath = this.checkStoragePath();
57+
const text = storagePath == '' ? 'Storage path not set. Check your configuration.' : storagePath.substring(storagePath.indexOf(':') + 1, storagePath.length);
58+
59+
this._view.webview.html = this.getWebviewContent(this._view.webview, text);
60+
}
61+
62+
private getRunCommand(space: number, node: number, path: string): string {
63+
const platform = process.platform;
64+
if (platform === 'darwin' || platform === 'linux') {
65+
return `coretex run create ${node} -s ${space} -f ${path}`;
66+
} else if (platform === 'win32') {
67+
return `coretex.exe run create ${node} -s ${space} -f ${path}`;
68+
}
69+
70+
return '';
71+
}
72+
73+
private async runCommand(data: any) {
74+
switch (data.type) {
75+
case 'start':
76+
{
77+
const spaceConf = 'Space';
78+
const nodeConf = 'NodeID';
79+
80+
const conf = vscode.workspace.getConfiguration();
81+
const spaceID = conf.get<{}>(spaceConf);
82+
const spaceDefaultValue = spaceID ? spaceID.toString() : '';
83+
84+
const space = await vscode.window.showInputBox({
85+
prompt: 'Enter Space ID in which you wish to run the Job',
86+
placeHolder: 'Space',
87+
validateInput: (value) => (value ? null : 'Space is required'),
88+
value: spaceDefaultValue, // Default value
89+
});
90+
91+
if (!space) {
92+
vscode.window.showErrorMessage(
93+
'Space is required to run a Job.'
94+
);
95+
return;
96+
}
97+
98+
const nodeID = conf.get<{}>(nodeConf);
99+
const nodeDefaultValue = nodeID ? nodeID.toString() : '';
100+
101+
const node = await vscode.window.showInputBox({
102+
prompt: 'Enter Node ID on which you wish to run the Job',
103+
placeHolder: 'Node',
104+
validateInput: (value) => (value ? null : 'Node is required'),
105+
value: nodeDefaultValue, // Default value
106+
});
107+
108+
if (!node) {
109+
vscode.window.showErrorMessage(
110+
'Node is required to run a Job.'
111+
);
112+
return;
113+
}
114+
115+
let currentWorkspacePath = '';
116+
117+
if (vscode.workspace.workspaceFolders) {
118+
currentWorkspacePath = vscode.workspace.workspaceFolders[0].uri.path;
119+
}
120+
121+
const command = this.getRunCommand(Number(space), Number(node), currentWorkspacePath);
122+
123+
vscode.window.terminals.forEach((terminal) => {
124+
terminal.dispose();
125+
});
126+
const terminal = vscode.window.createTerminal();
127+
terminal.show();
128+
terminal.sendText(command);
129+
break;
130+
}
131+
case 'nodes':
132+
{
133+
vscode.commands.executeCommand('coretex.listNodes');
134+
}
135+
}
136+
}
137+
138+
private checkStoragePath(): string {
139+
const platform = process.platform;
140+
if (platform === 'darwin' || platform === 'linux') {
141+
try {
142+
const version = child_process.execSync('coretex storage');
143+
return version.toString();
144+
} catch (error) {
145+
return '';
146+
}
147+
} else if (platform === 'win32') {
148+
try {
149+
const version = child_process.execSync('coretex storage');
150+
return version.toString();
151+
} catch (error) {
152+
try {
153+
const version = child_process.execSync('coretex.exe storage');
154+
return version.toString();
155+
} catch (error) {
156+
return '';
157+
}
158+
}
159+
}
160+
161+
return '';
162+
}
163+
164+
private getWebviewContent(webview: vscode.Webview, text: string): string {
165+
const viewStyle = webview.asWebviewUri(vscode.Uri.joinPath(this._extensionUri, 'media', 'views.css'));
166+
const runStyle = 'start-action button'
167+
const nodesStyle = 'update-action-new button'
168+
169+
const scriptUri = webview.asWebviewUri(vscode.Uri.joinPath(this._extensionUri, 'media', 'projectViewScripts.js'));
170+
171+
// Use a nonce to only allow a specific script to be run.
172+
const nonce = getNonce();
173+
174+
return `
175+
<!DOCTYPE html>
176+
<html lang="en">
177+
<head>
178+
<meta charset="UTF-8">
179+
<meta http-equiv="Content-Security-Policy" content="default-src 'none'; style-src ${webview.cspSource}; script-src 'nonce-${nonce}';">
180+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
181+
<link href="${viewStyle}" rel="stylesheet">
182+
<title>Project</title>
183+
</head>
184+
<body>
185+
<p>Run a Job with the current workspace contents:</p>
186+
<button class="${runStyle}">Run Job</button>
187+
<p>List nodes available for Job execution (set default in global extension settings):</p>
188+
<button class="${nodesStyle}">List Nodes</button>
189+
<p class="title">Storage path:</p>
190+
<p class="subtitle">${text}</p>
191+
<script nonce="${nonce}" src="${scriptUri}"></script>
192+
</body>
193+
</html>
194+
`;
195+
}
196+
}

0 commit comments

Comments
 (0)