Skip to content

Commit 797efe7

Browse files
committed
Fix loading within the CLI (#27)
* Fix loading within the CLI * Remove app * Remove promise handle * Fix requested changes
1 parent a85af49 commit 797efe7

28 files changed

+477
-105
lines changed

packages/logger/src/logger.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -272,8 +272,9 @@ export class Logger {
272272
if (name) {
273273
this.nameColor = hashStringToColor(name);
274274
}
275-
if (process.env.LOG_LEVEL) {
276-
switch (process.env.LOG_LEVEL) {
275+
const envLevel = typeof global !== "undefined" && typeof global.process !== "undefined" ? global.process.env.LOG_LEVEL : process.env.LOG_LEVEL;
276+
if (envLevel) {
277+
switch (envLevel) {
277278
case "debug": this.level = Level.Debug; break;
278279
case "info": this.level = Level.Info; break;
279280
case "warn": this.level = Level.Warn; break;

packages/protocol/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@
44
"dependencies": {
55
"express": "^4.16.4",
66
"google-protobuf": "^3.6.1",
7-
"node-pty": "^0.8.0",
7+
"node-pty": "^0.8.1",
8+
"tslib": "^1.9.3",
89
"ws": "^6.1.2"
910
},
1011
"devDependencies": {

packages/protocol/src/browser/client.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -327,6 +327,7 @@ export class Client {
327327
workingDirectory: init.getWorkingDirectory(),
328328
os: opSys,
329329
shell: init.getShell(),
330+
builtInExtensionsDirectory: init.getBuiltinExtensionsDir(),
330331
};
331332
this.initDataEmitter.emit(this._initData);
332333
} else if (message.hasEvalDone()) {

packages/protocol/src/browser/modules/fs.ts

Lines changed: 32 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { Client } from "../client";
88
// Use this to get around Webpack inserting our fills.
99
// TODO: is there a better way?
1010
declare var _require: typeof require;
11+
declare var _Buffer: typeof Buffer;
1112

1213
/**
1314
* Implements the native fs module
@@ -121,7 +122,7 @@ export class FS {
121122
const ae = this.client.run((ae, path, options) => {
122123
const fs = _require("fs") as typeof import("fs");
123124
const str = fs.createWriteStream(path, options);
124-
ae.on("write", (d, e) => str.write(Buffer.from(d, e)));
125+
ae.on("write", (d, e) => str.write(_Buffer.from(d, "utf8")));
125126
ae.on("close", () => str.close());
126127
str.on("close", () => ae.emit("close"));
127128
str.on("open", (fd) => ae.emit("open", fd));
@@ -216,18 +217,18 @@ export class FS {
216217
this.client.evaluate((fd) => {
217218
const fs = _require("fs") as typeof import("fs");
218219
const util = _require("util") as typeof import("util");
220+
const tslib = _require("tslib") as typeof import("tslib");
219221

220222
return util.promisify(fs.fstat)(fd).then((stats) => {
221-
return {
222-
...stats,
223-
_isBlockDevice: stats.isBlockDevice(),
224-
_isCharacterDevice: stats.isCharacterDevice(),
223+
return tslib.__assign(stats, {
224+
_isBlockDevice: stats.isBlockDevice ? stats.isBlockDevice() : false,
225+
_isCharacterDevice: stats.isCharacterDevice ? stats.isCharacterDevice() : false,
225226
_isDirectory: stats.isDirectory(),
226-
_isFIFO: stats.isFIFO(),
227+
_isFIFO: stats.isFIFO ? stats.isFIFO() : false,
227228
_isFile: stats.isFile(),
228-
_isSocket: stats.isSocket(),
229-
_isSymbolicLink: stats.isSymbolicLink(),
230-
};
229+
_isSocket: stats.isSocket ? stats.isSocket() : false,
230+
_isSymbolicLink: stats.isSymbolicLink ? stats.isSymbolicLink() : false,
231+
});
231232
});
232233
}, fd).then((stats) => {
233234
callback(undefined!, new Stats(stats));
@@ -322,18 +323,18 @@ export class FS {
322323
this.client.evaluate((path) => {
323324
const fs = _require("fs") as typeof import("fs");
324325
const util = _require("util") as typeof import("util");
326+
const tslib = _require("tslib") as typeof import("tslib");
325327

326328
return util.promisify(fs.lstat)(path).then((stats) => {
327-
return {
328-
...stats,
329-
_isBlockDevice: stats.isBlockDevice(),
330-
_isCharacterDevice: stats.isCharacterDevice(),
329+
return tslib.__assign(stats, {
330+
_isBlockDevice: stats.isBlockDevice ? stats.isBlockDevice() : false,
331+
_isCharacterDevice: stats.isCharacterDevice ? stats.isCharacterDevice() : false,
331332
_isDirectory: stats.isDirectory(),
332-
_isFIFO: stats.isFIFO(),
333+
_isFIFO: stats.isFIFO ? stats.isFIFO() : false,
333334
_isFile: stats.isFile(),
334-
_isSocket: stats.isSocket(),
335-
_isSymbolicLink: stats.isSymbolicLink(),
336-
};
335+
_isSocket: stats.isSocket ? stats.isSocket() : false,
336+
_isSymbolicLink: stats.isSymbolicLink ? stats.isSymbolicLink() : false,
337+
});
337338
});
338339
}, path).then((stats) => {
339340
callback(undefined!, new Stats(stats));
@@ -397,7 +398,7 @@ export class FS {
397398
this.client.evaluate((fd, length, position) => {
398399
const fs = _require("fs") as typeof import("fs");
399400
const util = _require("util") as typeof import("util");
400-
const buffer = new Buffer(length);
401+
const buffer = new _Buffer(length);
401402

402403
return util.promisify(fs.read)(fd, buffer, 0, length, position).then((resp) => {
403404
return {
@@ -513,18 +514,22 @@ export class FS {
513514
this.client.evaluate((path) => {
514515
const fs = _require("fs") as typeof import("fs");
515516
const util = _require("util") as typeof import("util");
517+
const tslib = _require("tslib") as typeof import("tslib");
516518

517519
return util.promisify(fs.stat)(path).then((stats) => {
518-
return {
519-
...stats,
520-
_isBlockDevice: stats.isBlockDevice(),
521-
_isCharacterDevice: stats.isCharacterDevice(),
520+
return tslib.__assign(stats, {
521+
/**
522+
* We need to check if functions exist because nexe's implemented FS
523+
* lib doesnt implement fs.stats properly
524+
*/
525+
_isBlockDevice: stats.isBlockDevice ? stats.isBlockDevice() : false,
526+
_isCharacterDevice: stats.isCharacterDevice ? stats.isCharacterDevice() : false,
522527
_isDirectory: stats.isDirectory(),
523-
_isFIFO: stats.isFIFO(),
528+
_isFIFO: stats.isFIFO ? stats.isFIFO() : false,
524529
_isFile: stats.isFile(),
525-
_isSocket: stats.isSocket(),
526-
_isSymbolicLink: stats.isSymbolicLink(),
527-
};
530+
_isSocket: stats.isSocket ? stats.isSocket() : false,
531+
_isSymbolicLink: stats.isSymbolicLink ? stats.isSymbolicLink() : false,
532+
});
528533
});
529534
}, path).then((stats) => {
530535
callback(undefined!, new Stats(stats));
@@ -602,7 +607,7 @@ export class FS {
602607
const fs = _require("fs") as typeof import("fs");
603608
const util = _require("util") as typeof import("util");
604609

605-
return util.promisify(fs.write)(fd, Buffer.from(buffer, "utf8"), offset, length, position).then((resp) => {
610+
return util.promisify(fs.write)(fd, _Buffer.from(buffer, "utf8"), offset, length, position).then((resp) => {
606611
return {
607612
bytesWritten: resp.bytesWritten,
608613
content: resp.buffer.toString("utf8"),

packages/protocol/src/common/connection.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ export interface InitData {
2121
readonly homeDirectory: string;
2222
readonly tmpDirectory: string;
2323
readonly shell: string;
24+
readonly builtInExtensionsDirectory: string;
2425
}
2526

2627
export interface ISharedProcessData {

packages/protocol/src/node/command.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import * as cp from "child_process";
22
import * as net from "net";
3-
import * as nodePty from "node-pty";
43
import * as stream from "stream";
54
import { TextEncoder } from "text-encoding";
65
import { Logger, logger, field } from "@coder/logger";
@@ -44,6 +43,7 @@ export const handleNewSession = (connection: SendableConnection, newSession: New
4443
});
4544
if (newSession.getTtyDimensions()) {
4645
// Spawn with node-pty
46+
const nodePty = require("node-pty") as typeof import("node-pty");
4747
const ptyProc = nodePty.spawn(newSession.getCommand(), newSession.getArgsList(), {
4848
cols: newSession.getTtyDimensions()!.getWidth(),
4949
rows: newSession.getTtyDimensions()!.getHeight(),
@@ -56,7 +56,7 @@ export const handleNewSession = (connection: SendableConnection, newSession: New
5656
processTitle = ptyProc.process;
5757
const id = new IdentifySessionMessage();
5858
id.setId(newSession.getId());
59-
id.setTitle(processTitle);
59+
id.setTitle(processTitle!);
6060
const sm = new ServerMessage();
6161
sm.setIdentifySession(id);
6262
connection.send(sm.serializeBinary());

packages/protocol/src/node/evaluate.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ export const evaluate = (connection: SendableConnection, message: NewEvalMessage
7676
connection.send(serverMsg.serializeBinary());
7777
},
7878
} : undefined,
79-
Buffer,
79+
_Buffer: Buffer,
8080
require: typeof __non_webpack_require__ !== "undefined" ? __non_webpack_require__ : require,
8181
_require: typeof __non_webpack_require__ !== "undefined" ? __non_webpack_require__ : require,
8282
tslib_1: require("tslib"), // TODO: is there a better way to do this?
@@ -98,7 +98,7 @@ export const evaluate = (connection: SendableConnection, message: NewEvalMessage
9898
onDispose();
9999
}
100100
} catch (ex) {
101-
sendErr(EvalFailedMessage.Reason.EXCEPTION, ex.toString());
101+
sendErr(EvalFailedMessage.Reason.EXCEPTION, ex.toString() + " " + ex.stack);
102102
}
103103

104104
return eventEmitter ? {

packages/protocol/src/node/server.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import * as net from "net";
1414
export interface ServerOptions {
1515
readonly workingDirectory: string;
1616
readonly dataDirectory: string;
17+
readonly builtInExtensionsDirectory: string;
1718

1819
forkProvider?(message: NewSessionMessage): cp.ChildProcess;
1920
}
@@ -35,7 +36,10 @@ export class Server {
3536
try {
3637
this.handleMessage(ClientMessage.deserializeBinary(data));
3738
} catch (ex) {
38-
logger.error("Failed to handle client message", field("length", data.byteLength), field("exception", ex));
39+
logger.error("Failed to handle client message", field("length", data.byteLength), field("exception", {
40+
message: ex.message,
41+
stack: ex.stack,
42+
}));
3943
}
4044
});
4145
connection.onClose(() => {
@@ -80,6 +84,7 @@ export class Server {
8084
const initMsg = new WorkingInitMessage();
8185
initMsg.setDataDirectory(options.dataDirectory);
8286
initMsg.setWorkingDirectory(options.workingDirectory);
87+
initMsg.setBuiltinExtensionsDir(options.builtInExtensionsDirectory);
8388
initMsg.setHomeDirectory(os.homedir());
8489
initMsg.setTmpDirectory(os.tmpdir());
8590
const platform = os.platform();
@@ -98,8 +103,8 @@ export class Server {
98103
throw new Error(`unrecognized platform "${platform}"`);
99104
}
100105
initMsg.setOperatingSystem(operatingSystem);
101-
if (process.env.SHELL) {
102-
initMsg.setShell(process.env.SHELL);
106+
if (global.process.env.SHELL) {
107+
initMsg.setShell(global.process.env.SHELL);
103108
}
104109
const srvMsg = new ServerMessage();
105110
srvMsg.setInit(initMsg);

packages/protocol/src/proto/client.proto

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,4 +63,5 @@ message WorkingInitMessage {
6363
}
6464
OperatingSystem operating_system = 5;
6565
string shell = 6;
66+
string builtin_extensions_dir = 7;
6667
}

packages/protocol/src/proto/client_pb.d.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,9 @@ export class WorkingInitMessage extends jspb.Message {
270270
getShell(): string;
271271
setShell(value: string): void;
272272

273+
getBuiltinExtensionsDir(): string;
274+
setBuiltinExtensionsDir(value: string): void;
275+
273276
serializeBinary(): Uint8Array;
274277
toObject(includeInstance?: boolean): WorkingInitMessage.AsObject;
275278
static toObject(includeInstance: boolean, msg: WorkingInitMessage): WorkingInitMessage.AsObject;
@@ -288,6 +291,7 @@ export namespace WorkingInitMessage {
288291
workingDirectory: string,
289292
operatingSystem: WorkingInitMessage.OperatingSystem,
290293
shell: string,
294+
builtinExtensionsDir: string,
291295
}
292296

293297
export enum OperatingSystem {

packages/protocol/src/proto/client_pb.js

Lines changed: 28 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/protocol/test/modules/fs.test.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -536,7 +536,7 @@ describe("fs", () => {
536536
});
537537

538538
describe("stat", () => {
539-
it("should stat", (done) => {
539+
it("should stat file", (done) => {
540540
fs.stat(testFile, (err, stats) => {
541541
expect(err).toBeUndefined();
542542
expect(stats.size).toBeGreaterThan(0);
@@ -546,6 +546,17 @@ describe("fs", () => {
546546
});
547547
});
548548

549+
it("should stat folder", (done) => {
550+
const dir = tmpFile();
551+
nativeFs.mkdirSync(dir);
552+
553+
fs.stat(dir, (err, stats) => {
554+
expect(err).toBeUndefined();
555+
expect(stats.isDirectory()).toBeTruthy();
556+
done();
557+
});
558+
});
559+
549560
it("should fail to stat", (done) => {
550561
fs.stat(path.join(__dirname, "no-exist"), (err, stats) => {
551562
expect(err).toBeDefined();

packages/protocol/yarn.lock

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -236,22 +236,22 @@ [email protected]:
236236
resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
237237
integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=
238238

239-
nan@2.10.0:
240-
version "2.10.0"
241-
resolved "https://registry.yarnpkg.com/nan/-/nan-2.10.0.tgz#96d0cd610ebd58d4b4de9cc0c6828cda99c7548f"
242-
integrity sha512-bAdJv7fBLhWC+/Bls0Oza+mvTaNQtP+1RyhhhvD95pgUJz6XM5IzgmxOkItJ9tkoCiplvAnXI1tNmmUD/eScyA==
239+
nan@2.12.1:
240+
version "2.12.1"
241+
resolved "https://registry.yarnpkg.com/nan/-/nan-2.12.1.tgz#7b1aa193e9aa86057e3c7bbd0ac448e770925552"
242+
integrity sha512-JY7V6lRkStKcKTvHO5NVSQRv+RV+FIL5pvDoLiAtSL9pKlC5x9PKQcZDsq7m4FO4d57mkhC6Z+QhAh3Jdk5JFw==
243243

244244
245245
version "0.6.1"
246246
resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.1.tgz#2b327184e8992101177b28563fb5e7102acd0ca9"
247247
integrity sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=
248248

249-
node-pty@^0.8.0:
250-
version "0.8.0"
251-
resolved "https://registry.yarnpkg.com/node-pty/-/node-pty-0.8.0.tgz#08bccb633f49e2e3f7245eb56ea6b40f37ccd64f"
252-
integrity sha512-g5ggk3gN4gLrDmAllee5ScFyX3YzpOC/U8VJafha4pE7do0TIE1voiIxEbHSRUOPD1xYqmY+uHhOKAd3avbxGQ==
249+
node-pty@^0.8.1:
250+
version "0.8.1"
251+
resolved "https://registry.yarnpkg.com/node-pty/-/node-pty-0.8.1.tgz#94b457bec013e7a09b8d9141f63b0787fa25c23f"
252+
integrity sha512-j+/g0Q5dR+vkELclpJpz32HcS3O/3EdPSGPvDXJZVJQLCvgG0toEbfmymxAEyQyZEpaoKHAcoL+PvKM+4N9nlw==
253253
dependencies:
254-
nan "2.10.0"
254+
nan "2.12.1"
255255

256256
on-finished@~2.3.0:
257257
version "2.3.0"
@@ -364,6 +364,11 @@ ts-protoc-gen@^0.8.0:
364364
dependencies:
365365
google-protobuf "^3.6.1"
366366

367+
tslib@^1.9.3:
368+
version "1.9.3"
369+
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.3.tgz#d7e4dd79245d85428c4d7e4822a79917954ca286"
370+
integrity sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==
371+
367372
type-is@~1.6.16:
368373
version "1.6.16"
369374
resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.16.tgz#f89ce341541c672b25ee7ae3c73dee3b2be50194"

packages/server/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
out
22
cli*
33
build
4+
resources
45

56
# This file is generated when the binary is created.
67
# We want to use the parent tsconfig so we can ignore it.

0 commit comments

Comments
 (0)