Fix loading within the CLI (#27)
* Fix loading within the CLI * Remove app * Remove promise handle * Fix requested changes
This commit is contained in:
@ -327,6 +327,7 @@ export class Client {
|
||||
workingDirectory: init.getWorkingDirectory(),
|
||||
os: opSys,
|
||||
shell: init.getShell(),
|
||||
builtInExtensionsDirectory: init.getBuiltinExtensionsDir(),
|
||||
};
|
||||
this.initDataEmitter.emit(this._initData);
|
||||
} else if (message.hasEvalDone()) {
|
||||
|
@ -8,6 +8,7 @@ import { Client } from "../client";
|
||||
// Use this to get around Webpack inserting our fills.
|
||||
// TODO: is there a better way?
|
||||
declare var _require: typeof require;
|
||||
declare var _Buffer: typeof Buffer;
|
||||
|
||||
/**
|
||||
* Implements the native fs module
|
||||
@ -121,7 +122,7 @@ export class FS {
|
||||
const ae = this.client.run((ae, path, options) => {
|
||||
const fs = _require("fs") as typeof import("fs");
|
||||
const str = fs.createWriteStream(path, options);
|
||||
ae.on("write", (d, e) => str.write(Buffer.from(d, e)));
|
||||
ae.on("write", (d, e) => str.write(_Buffer.from(d, "utf8")));
|
||||
ae.on("close", () => str.close());
|
||||
str.on("close", () => ae.emit("close"));
|
||||
str.on("open", (fd) => ae.emit("open", fd));
|
||||
@ -216,18 +217,18 @@ export class FS {
|
||||
this.client.evaluate((fd) => {
|
||||
const fs = _require("fs") as typeof import("fs");
|
||||
const util = _require("util") as typeof import("util");
|
||||
const tslib = _require("tslib") as typeof import("tslib");
|
||||
|
||||
return util.promisify(fs.fstat)(fd).then((stats) => {
|
||||
return {
|
||||
...stats,
|
||||
_isBlockDevice: stats.isBlockDevice(),
|
||||
_isCharacterDevice: stats.isCharacterDevice(),
|
||||
return tslib.__assign(stats, {
|
||||
_isBlockDevice: stats.isBlockDevice ? stats.isBlockDevice() : false,
|
||||
_isCharacterDevice: stats.isCharacterDevice ? stats.isCharacterDevice() : false,
|
||||
_isDirectory: stats.isDirectory(),
|
||||
_isFIFO: stats.isFIFO(),
|
||||
_isFIFO: stats.isFIFO ? stats.isFIFO() : false,
|
||||
_isFile: stats.isFile(),
|
||||
_isSocket: stats.isSocket(),
|
||||
_isSymbolicLink: stats.isSymbolicLink(),
|
||||
};
|
||||
_isSocket: stats.isSocket ? stats.isSocket() : false,
|
||||
_isSymbolicLink: stats.isSymbolicLink ? stats.isSymbolicLink() : false,
|
||||
});
|
||||
});
|
||||
}, fd).then((stats) => {
|
||||
callback(undefined!, new Stats(stats));
|
||||
@ -322,18 +323,18 @@ export class FS {
|
||||
this.client.evaluate((path) => {
|
||||
const fs = _require("fs") as typeof import("fs");
|
||||
const util = _require("util") as typeof import("util");
|
||||
const tslib = _require("tslib") as typeof import("tslib");
|
||||
|
||||
return util.promisify(fs.lstat)(path).then((stats) => {
|
||||
return {
|
||||
...stats,
|
||||
_isBlockDevice: stats.isBlockDevice(),
|
||||
_isCharacterDevice: stats.isCharacterDevice(),
|
||||
return tslib.__assign(stats, {
|
||||
_isBlockDevice: stats.isBlockDevice ? stats.isBlockDevice() : false,
|
||||
_isCharacterDevice: stats.isCharacterDevice ? stats.isCharacterDevice() : false,
|
||||
_isDirectory: stats.isDirectory(),
|
||||
_isFIFO: stats.isFIFO(),
|
||||
_isFIFO: stats.isFIFO ? stats.isFIFO() : false,
|
||||
_isFile: stats.isFile(),
|
||||
_isSocket: stats.isSocket(),
|
||||
_isSymbolicLink: stats.isSymbolicLink(),
|
||||
};
|
||||
_isSocket: stats.isSocket ? stats.isSocket() : false,
|
||||
_isSymbolicLink: stats.isSymbolicLink ? stats.isSymbolicLink() : false,
|
||||
});
|
||||
});
|
||||
}, path).then((stats) => {
|
||||
callback(undefined!, new Stats(stats));
|
||||
@ -397,7 +398,7 @@ export class FS {
|
||||
this.client.evaluate((fd, length, position) => {
|
||||
const fs = _require("fs") as typeof import("fs");
|
||||
const util = _require("util") as typeof import("util");
|
||||
const buffer = new Buffer(length);
|
||||
const buffer = new _Buffer(length);
|
||||
|
||||
return util.promisify(fs.read)(fd, buffer, 0, length, position).then((resp) => {
|
||||
return {
|
||||
@ -513,18 +514,22 @@ export class FS {
|
||||
this.client.evaluate((path) => {
|
||||
const fs = _require("fs") as typeof import("fs");
|
||||
const util = _require("util") as typeof import("util");
|
||||
const tslib = _require("tslib") as typeof import("tslib");
|
||||
|
||||
return util.promisify(fs.stat)(path).then((stats) => {
|
||||
return {
|
||||
...stats,
|
||||
_isBlockDevice: stats.isBlockDevice(),
|
||||
_isCharacterDevice: stats.isCharacterDevice(),
|
||||
return tslib.__assign(stats, {
|
||||
/**
|
||||
* We need to check if functions exist because nexe's implemented FS
|
||||
* lib doesnt implement fs.stats properly
|
||||
*/
|
||||
_isBlockDevice: stats.isBlockDevice ? stats.isBlockDevice() : false,
|
||||
_isCharacterDevice: stats.isCharacterDevice ? stats.isCharacterDevice() : false,
|
||||
_isDirectory: stats.isDirectory(),
|
||||
_isFIFO: stats.isFIFO(),
|
||||
_isFIFO: stats.isFIFO ? stats.isFIFO() : false,
|
||||
_isFile: stats.isFile(),
|
||||
_isSocket: stats.isSocket(),
|
||||
_isSymbolicLink: stats.isSymbolicLink(),
|
||||
};
|
||||
_isSocket: stats.isSocket ? stats.isSocket() : false,
|
||||
_isSymbolicLink: stats.isSymbolicLink ? stats.isSymbolicLink() : false,
|
||||
});
|
||||
});
|
||||
}, path).then((stats) => {
|
||||
callback(undefined!, new Stats(stats));
|
||||
@ -602,7 +607,7 @@ export class FS {
|
||||
const fs = _require("fs") as typeof import("fs");
|
||||
const util = _require("util") as typeof import("util");
|
||||
|
||||
return util.promisify(fs.write)(fd, Buffer.from(buffer, "utf8"), offset, length, position).then((resp) => {
|
||||
return util.promisify(fs.write)(fd, _Buffer.from(buffer, "utf8"), offset, length, position).then((resp) => {
|
||||
return {
|
||||
bytesWritten: resp.bytesWritten,
|
||||
content: resp.buffer.toString("utf8"),
|
||||
|
@ -21,6 +21,7 @@ export interface InitData {
|
||||
readonly homeDirectory: string;
|
||||
readonly tmpDirectory: string;
|
||||
readonly shell: string;
|
||||
readonly builtInExtensionsDirectory: string;
|
||||
}
|
||||
|
||||
export interface ISharedProcessData {
|
||||
|
@ -1,6 +1,5 @@
|
||||
import * as cp from "child_process";
|
||||
import * as net from "net";
|
||||
import * as nodePty from "node-pty";
|
||||
import * as stream from "stream";
|
||||
import { TextEncoder } from "text-encoding";
|
||||
import { Logger, logger, field } from "@coder/logger";
|
||||
@ -44,6 +43,7 @@ export const handleNewSession = (connection: SendableConnection, newSession: New
|
||||
});
|
||||
if (newSession.getTtyDimensions()) {
|
||||
// Spawn with node-pty
|
||||
const nodePty = require("node-pty") as typeof import("node-pty");
|
||||
const ptyProc = nodePty.spawn(newSession.getCommand(), newSession.getArgsList(), {
|
||||
cols: newSession.getTtyDimensions()!.getWidth(),
|
||||
rows: newSession.getTtyDimensions()!.getHeight(),
|
||||
@ -56,7 +56,7 @@ export const handleNewSession = (connection: SendableConnection, newSession: New
|
||||
processTitle = ptyProc.process;
|
||||
const id = new IdentifySessionMessage();
|
||||
id.setId(newSession.getId());
|
||||
id.setTitle(processTitle);
|
||||
id.setTitle(processTitle!);
|
||||
const sm = new ServerMessage();
|
||||
sm.setIdentifySession(id);
|
||||
connection.send(sm.serializeBinary());
|
||||
|
@ -76,7 +76,7 @@ export const evaluate = (connection: SendableConnection, message: NewEvalMessage
|
||||
connection.send(serverMsg.serializeBinary());
|
||||
},
|
||||
} : undefined,
|
||||
Buffer,
|
||||
_Buffer: Buffer,
|
||||
require: typeof __non_webpack_require__ !== "undefined" ? __non_webpack_require__ : require,
|
||||
_require: typeof __non_webpack_require__ !== "undefined" ? __non_webpack_require__ : require,
|
||||
tslib_1: require("tslib"), // TODO: is there a better way to do this?
|
||||
@ -98,7 +98,7 @@ export const evaluate = (connection: SendableConnection, message: NewEvalMessage
|
||||
onDispose();
|
||||
}
|
||||
} catch (ex) {
|
||||
sendErr(EvalFailedMessage.Reason.EXCEPTION, ex.toString());
|
||||
sendErr(EvalFailedMessage.Reason.EXCEPTION, ex.toString() + " " + ex.stack);
|
||||
}
|
||||
|
||||
return eventEmitter ? {
|
||||
|
@ -14,6 +14,7 @@ import * as net from "net";
|
||||
export interface ServerOptions {
|
||||
readonly workingDirectory: string;
|
||||
readonly dataDirectory: string;
|
||||
readonly builtInExtensionsDirectory: string;
|
||||
|
||||
forkProvider?(message: NewSessionMessage): cp.ChildProcess;
|
||||
}
|
||||
@ -35,7 +36,10 @@ export class Server {
|
||||
try {
|
||||
this.handleMessage(ClientMessage.deserializeBinary(data));
|
||||
} catch (ex) {
|
||||
logger.error("Failed to handle client message", field("length", data.byteLength), field("exception", ex));
|
||||
logger.error("Failed to handle client message", field("length", data.byteLength), field("exception", {
|
||||
message: ex.message,
|
||||
stack: ex.stack,
|
||||
}));
|
||||
}
|
||||
});
|
||||
connection.onClose(() => {
|
||||
@ -80,6 +84,7 @@ export class Server {
|
||||
const initMsg = new WorkingInitMessage();
|
||||
initMsg.setDataDirectory(options.dataDirectory);
|
||||
initMsg.setWorkingDirectory(options.workingDirectory);
|
||||
initMsg.setBuiltinExtensionsDir(options.builtInExtensionsDirectory);
|
||||
initMsg.setHomeDirectory(os.homedir());
|
||||
initMsg.setTmpDirectory(os.tmpdir());
|
||||
const platform = os.platform();
|
||||
@ -98,8 +103,8 @@ export class Server {
|
||||
throw new Error(`unrecognized platform "${platform}"`);
|
||||
}
|
||||
initMsg.setOperatingSystem(operatingSystem);
|
||||
if (process.env.SHELL) {
|
||||
initMsg.setShell(process.env.SHELL);
|
||||
if (global.process.env.SHELL) {
|
||||
initMsg.setShell(global.process.env.SHELL);
|
||||
}
|
||||
const srvMsg = new ServerMessage();
|
||||
srvMsg.setInit(initMsg);
|
||||
|
@ -63,4 +63,5 @@ message WorkingInitMessage {
|
||||
}
|
||||
OperatingSystem operating_system = 5;
|
||||
string shell = 6;
|
||||
string builtin_extensions_dir = 7;
|
||||
}
|
||||
|
4
packages/protocol/src/proto/client_pb.d.ts
vendored
4
packages/protocol/src/proto/client_pb.d.ts
vendored
@ -270,6 +270,9 @@ export class WorkingInitMessage extends jspb.Message {
|
||||
getShell(): string;
|
||||
setShell(value: string): void;
|
||||
|
||||
getBuiltinExtensionsDir(): string;
|
||||
setBuiltinExtensionsDir(value: string): void;
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): WorkingInitMessage.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: WorkingInitMessage): WorkingInitMessage.AsObject;
|
||||
@ -288,6 +291,7 @@ export namespace WorkingInitMessage {
|
||||
workingDirectory: string,
|
||||
operatingSystem: WorkingInitMessage.OperatingSystem,
|
||||
shell: string,
|
||||
builtinExtensionsDir: string,
|
||||
}
|
||||
|
||||
export enum OperatingSystem {
|
||||
|
@ -1684,7 +1684,8 @@ proto.WorkingInitMessage.toObject = function(includeInstance, msg) {
|
||||
dataDirectory: msg.getDataDirectory(),
|
||||
workingDirectory: msg.getWorkingDirectory(),
|
||||
operatingSystem: msg.getOperatingSystem(),
|
||||
shell: msg.getShell()
|
||||
shell: msg.getShell(),
|
||||
builtinExtensionsDir: msg.getBuiltinExtensionsDir()
|
||||
};
|
||||
|
||||
if (includeInstance) {
|
||||
@ -1745,6 +1746,10 @@ proto.WorkingInitMessage.deserializeBinaryFromReader = function(msg, reader) {
|
||||
var value = /** @type {string} */ (reader.readString());
|
||||
msg.setShell(value);
|
||||
break;
|
||||
case 7:
|
||||
var value = /** @type {string} */ (reader.readString());
|
||||
msg.setBuiltinExtensionsDir(value);
|
||||
break;
|
||||
default:
|
||||
reader.skipField();
|
||||
break;
|
||||
@ -1825,6 +1830,13 @@ proto.WorkingInitMessage.prototype.serializeBinaryToWriter = function (writer) {
|
||||
f
|
||||
);
|
||||
}
|
||||
f = this.getBuiltinExtensionsDir();
|
||||
if (f.length > 0) {
|
||||
writer.writeString(
|
||||
7,
|
||||
f
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@ -1927,6 +1939,21 @@ proto.WorkingInitMessage.prototype.setShell = function(value) {
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* optional string builtin_extensions_dir = 7;
|
||||
* @return {string}
|
||||
*/
|
||||
proto.WorkingInitMessage.prototype.getBuiltinExtensionsDir = function() {
|
||||
return /** @type {string} */ (jspb.Message.getFieldProto3(this, 7, ""));
|
||||
};
|
||||
|
||||
|
||||
/** @param {string} value */
|
||||
proto.WorkingInitMessage.prototype.setBuiltinExtensionsDir = function(value) {
|
||||
jspb.Message.setField(this, 7, value);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @enum {number}
|
||||
*/
|
||||
|
Reference in New Issue
Block a user