Skip to content

Commit

Permalink
support for custom address in isfs
Browse files Browse the repository at this point in the history
  • Loading branch information
daimor committed Mar 4, 2020
1 parent d8a2547 commit 39fd781
Show file tree
Hide file tree
Showing 11 changed files with 1,734 additions and 444 deletions.
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -479,7 +479,8 @@
},
"objectscript.conn.docker-compose": {
"description": "Connect to server running in docker-compose",
"type": "object"
"type": "object",
"scope": "resource"
},
"objectscript.conn.docker-compose.service": {
"description": "Name of service in docker-compose",
Expand Down
41 changes: 14 additions & 27 deletions src/api/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,18 +20,6 @@ export class AtelierAPI {
return this.namespace || this.config.ns;
}

private get apiVersion(): number {
return workspaceState.get(this.workspaceFolder + ":apiVersion", DEFAULT_API_VERSION);
}

private get port(): number {
return workspaceState.get(this.workspaceFolder + ":port", this.config.port);
}

private get password(): string {
return workspaceState.get(this.workspaceFolder + ":password", this.config.password);
}

private get iris(): boolean {
return workspaceState.get(this.workspaceFolder + ":iris", false);
}
Expand Down Expand Up @@ -74,14 +62,12 @@ export class AtelierAPI {
}

public xdebugUrl(): string {
const { host, username, https } = this.config;
const port = this.port;
const password = this.password;
const { host, username, https, port, password, apiVersion } = this.config;
const proto = https ? "wss" : "ws";
const auth = this.iris
? `IRISUsername=${username}&IRISPassword=${password}`
: `CacheUserName=${username}&CachePassword=${password}`;
return `${proto}://${host}:${port}/api/atelier/v${this.apiVersion}/%25SYS/debug?${auth}`;
return `${proto}://${host}:${port}/api/atelier/v${apiVersion}/%25SYS/debug?${auth}`;
}

public updateCookies(newCookies: string[]): Promise<any> {
Expand All @@ -102,8 +88,11 @@ export class AtelierAPI {
this.workspaceFolder = workspaceFolderName;
const conn = config("conn", workspaceFolderName);
this.config = conn;
const { name, host } = this.config;
const port = this.port;
this.config.port = workspaceState.get(this.workspaceFolder + ":port", this.config.port);
this.config.password = workspaceState.get(this.workspaceFolder + ":password", this.config.password);
this.config.apiVersion = workspaceState.get(this.workspaceFolder + ":apiVersion", DEFAULT_API_VERSION);

const { name, host, port } = this.config;
this.cache = new Cache(extensionContext, `API:${name}:${host}:${port}`);
}

Expand All @@ -115,14 +104,15 @@ export class AtelierAPI {
params?: any,
headers?: any
): Promise<any> {
if (minVersion > this.apiVersion) {
return Promise.reject(`${path} not supported by API version ${this.apiVersion}`);
const { active, apiVersion, host, username, https, port, password } = this.config;
if (!active) {
return Promise.reject();
}
if (minVersion && minVersion > 0) {
path = `v${this.apiVersion}/${path}`;
if (minVersion > apiVersion) {
return Promise.reject(`${path} not supported by API version ${apiVersion}`);
}
if (!this.config.active) {
return Promise.reject();
if (minVersion && minVersion > 0) {
path = `v${apiVersion}/${path}`;
}
headers = {
...headers,
Expand All @@ -149,9 +139,6 @@ export class AtelierAPI {
}
headers["Cache-Control"] = "no-cache";

const { host, username, https } = this.config;
const port = this.port;
const password = this.password;
const proto = this.config.https ? "https" : "http";
const http: any = this.config.https ? httpsModule : httpModule;
const agent = new http.Agent({
Expand Down
5 changes: 4 additions & 1 deletion src/commands/compile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,10 @@ async function compile(docs: CurrentFile[], flags?: string): Promise<any> {
},
() =>
api
.actionCompile(docs.map(el => el.name), flags)
.actionCompile(
docs.map(el => el.name),
flags
)
.then(data => {
const info = docs.length > 1 ? "" : `${docs[0].name}: `;
if (data.status && data.status.errors && data.status.errors.length) {
Expand Down
2 changes: 1 addition & 1 deletion src/debug/debugSession.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ export class ObjectScriptDebugSession extends LoggingDebugSession {
private _evalResultProperties = new Map<number, xdebug.EvalResultProperty>();

public constructor() {
super("mock-debug.txt");
super();

const api = new AtelierAPI();
this._namespace = api.ns;
Expand Down
33 changes: 29 additions & 4 deletions src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export const OBJECTSCRIPTXML_FILE_SCHEMA = "objectscriptxml";
export const FILESYSTEM_SCHEMA = "isfs";
export const schemas = [OBJECTSCRIPT_FILE_SCHEMA, OBJECTSCRIPTXML_FILE_SCHEMA, FILESYSTEM_SCHEMA];

import * as url from "url";
import WebSocket = require("ws");
import {
importAndCompile,
Expand Down Expand Up @@ -76,6 +77,25 @@ export const config = (setting?: string, workspaceFolderName?: string): any => {

if (["conn", "export"].includes(setting)) {
if (workspaceFolderName && workspaceFolderName !== "") {
if (workspaceFolderName.match(/.+:\d+$/)) {
const { port, hostname: host, auth, query } = url.parse("http://" + workspaceFolderName, true);
const { ns = "USER", https = false } = query;
const [username, password] = (auth || "_SYSTEM:SYS").split(":");
if (setting == "conn") {
return {
active: true,
https,
ns,
host,
port,
username,
password,
};
} else if (setting == "export") {
return {};
}
}

const workspaceFolder = vscode.workspace.workspaceFolders.find(
el => el.name.toLowerCase() === workspaceFolderName.toLowerCase()
);
Expand All @@ -101,6 +121,8 @@ export function getXmlUri(uri: vscode.Uri): vscode.Uri {
}
let reporter: TelemetryReporter;

let connectionSocket: WebSocket;

export const checkConnection = (clearCookies = false): void => {
const conn = config("conn");
let connInfo = `${conn.host}:${conn.port}[${conn.ns}]`;
Expand All @@ -112,7 +134,7 @@ export const checkConnection = (clearCookies = false): void => {
return;
}
workspaceState.update(currentWorkspaceFolder() + ":port", undefined);
const { port: dockerPort, docker: withDocker } = portFromDockerCompose(config("conn.docker-compose"), conn.port);
const { port: dockerPort, docker: withDocker } = portFromDockerCompose();
workspaceState.update(currentWorkspaceFolder() + ":docker", withDocker);
if (withDocker) {
terminalWithDocker();
Expand All @@ -126,6 +148,9 @@ export const checkConnection = (clearCookies = false): void => {
if (clearCookies) {
api.clearCookies();
}
if (connectionSocket && connectionSocket.url == api.xdebugUrl() && connectionSocket.OPEN) {
return;
}
api
.serverInfo()
.then(info => {
Expand All @@ -135,11 +160,11 @@ export const checkConnection = (clearCookies = false): void => {
healthshare: hasHS ? "yes" : "no",
});
/// Use xdebug's websocket, to catch when server disconnected
const socket = new WebSocket(api.xdebugUrl());
socket.onopen = () => {
connectionSocket = new WebSocket(api.xdebugUrl());
connectionSocket.onopen = () => {
panel.text = `${connInfo} - Connected`;
};
socket.onclose = event => {
connectionSocket.onclose = event => {
panel.text = `${connInfo} - Disconnected`;
};
})
Expand Down
7 changes: 7 additions & 0 deletions src/providers/DocumentContentProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,16 @@ export class DocumentContentProvider implements vscode.TextDocumentContentProvid
const wFolderUri = workspaceFolderUri(workspaceFolder);
let uri: vscode.Uri;
if (wFolderUri.scheme === FILESYSTEM_SCHEMA) {
const fileExt = name.split(".").pop();
const fileName = name
.split(".")
.slice(0, -1)
.join(fileExt.match(/cls/i) ? "/" : ".");
name = fileName + "." + fileExt;
uri = wFolderUri.with({
path: `/${name}`,
});
vfs = true;
} else {
const found = this.getAsFile(name, workspaceFolder);
if (found) {
Expand Down
10 changes: 6 additions & 4 deletions src/providers/ObjectScriptDiagnosticProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ export class ObjectScriptDiagnosticProvider {
}

const memberMatch = text.match(
/^(Class|Property|Relationship|Index|ClassMethod|Method|XData|Query|Trigger|ForeignKey|Projection|Parameter)\s(\b[^ (]+\b)/i
/^(Class|Property|Relationship|Index|(?:(?:Client)?(?:Class)?Method)|ClientClassMethod|Method|XData|Query|Trigger|ForeignKey|Projection|Parameter)\s(\b[^ (]+\b)/i
);
if (memberMatch) {
const [fullMatch, type, name] = memberMatch;
Expand Down Expand Up @@ -222,9 +222,11 @@ export class ObjectScriptDiagnosticProvider {
const [, found] = functionsMatch;
const pos = functionsMatch.index;
const range = new vscode.Range(new vscode.Position(i, pos), new vscode.Position(i, pos + found.length));
const systemFunction = [...systemFunctions, ...systemVariables, ...structuredSystemVariables].find(el =>
el.alias.includes(found.toUpperCase())
);
const systemFunction: CompletionModel = [
...systemFunctions,
...systemVariables,
...structuredSystemVariables,
].find(el => el.alias.includes(found.toUpperCase()));
if (!systemFunction) {
result.push({
range,
Expand Down
8 changes: 5 additions & 3 deletions src/providers/WorkspaceSymbolProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,11 @@ export class WorkspaceSymbolProvider implements vscode.WorkspaceSymbolProvider {
if (query.length < 3) {
return null;
}
return Promise.all([this.byClasses(query), this.byRoutines(query), this.byMethods(query)]).then(
([classes, routines, methods]) => [...classes, ...routines, ...methods]
);
return Promise.all([
this.byClasses(query),
this.byRoutines(query),
this.byMethods(query),
]).then(([classes, routines, methods]) => [...classes, ...routines, ...methods]);
}

public async byClasses(query: string): Promise<vscode.SymbolInformation[]> {
Expand Down
8 changes: 8 additions & 0 deletions src/providers/completion/model.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
interface CompletionModel {
label: string;
alias: string[];
deprecated?: boolean;
documentation: string[];
link?: string;
code?: string;
}
33 changes: 18 additions & 15 deletions src/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,10 @@ export function currentFile(document?: vscode.TextDocument): CurrentFile {
const uri = document.uri;
const fileName = document.fileName;
const content = document.getText();
const fileExt = fileName.match(/\.(\w+)$/)[1].toLowerCase();
const fileExt = fileName
.split(".")
.pop()
.toLowerCase();
let name = "";
let ext = "";
const { query } = url.parse(decodeURIComponent(uri.toString()), true);
Expand All @@ -42,13 +45,11 @@ export function currentFile(document?: vscode.TextDocument): CurrentFile {
} else if (fileExt === "cls") {
const match = content.match(/^Class (%?\w+(?:\.\w+)+)/im);
if (match) {
name = match[1];
ext = "cls";
[, name, ext = "cls"] = match;
}
} else {
const match = content.match(/^ROUTINE ([^\s]+)(?:\s+\[.*Type=([a-z]{3,}))?/i);
name = match[1];
ext = match[2] || "mac";
[, name, ext = "mac"] = match;
}
if (!name) {
return null;
Expand Down Expand Up @@ -107,8 +108,9 @@ export function currentWorkspaceFolder(document?: vscode.TextDocument): string {
}

export function workspaceFolderUri(workspaceFolder: string = currentWorkspaceFolder()): vscode.Uri {
return vscode.workspace.workspaceFolders.find(
(el): boolean => el.name.toLowerCase() === workspaceFolder.toLowerCase()
return (
vscode.workspace.workspaceFolders.find((el): boolean => el.name.toLowerCase() === workspaceFolder.toLowerCase()) ||
vscode.workspace.workspaceFolders.find((el): boolean => el.uri.authority == workspaceFolder)
).uri;
}

Expand All @@ -123,12 +125,10 @@ export function notNull(el: any): boolean {
return el !== null;
}

export function portFromDockerCompose(options, defaultPort: number): { port: number; docker: boolean } {
export function portFromDockerCompose(): { port: number; docker: boolean } {
const { "docker-compose": dockerCompose, port: defaultPort } = config("conn");
const result = { port: defaultPort, docker: false };
if (!options) {
return result;
}
const { file = "docker-compose.yml", service, internalPort = 52773 } = options;
const { service, file = "docker-compose.yml", internalPort = 52773 } = dockerCompose;
if (!internalPort || !file || !service || service === "") {
return result;
}
Expand All @@ -155,13 +155,16 @@ export function portFromDockerCompose(options, defaultPort: number): { port: num
}

export function terminalWithDocker() {
const { ns } = config("conn");
const { service } = config("conn.docker-compose");
const { ns, "docker-compose": dockerCompose } = config("conn");
const { service, file = "docker-compose.yml" } = dockerCompose;
const workspace = currentWorkspaceFolder();

const terminalName = `ObjectScript:${service}`;
const terminalName = `ObjectScript:${workspace}`;
let terminal = vscode.window.terminals.find(el => el.name === terminalName);
if (!terminal) {
terminal = vscode.window.createTerminal(terminalName, "docker-compose", [
"-f",
file,
"exec",
service,
"/bin/bash",
Expand Down
Loading

0 comments on commit 39fd781

Please sign in to comment.