Skip to content

Fix coping and moving files around using the file tree #568

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Apr 24, 2019
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 12 additions & 2 deletions packages/ide/src/fill/electron.ts
Original file line number Diff line number Diff line change
Expand Up @@ -171,8 +171,10 @@ const newCreateElement = <K extends keyof HTMLElementTagNameMap>(tagName: K): HT
document.createElement = newCreateElement;

class Clipboard {
public has(): boolean {
return false;
private readonly buffers = new Map<string, Buffer>();

public has(format: string): boolean {
return this.buffers.has(format);
}

public readFindText(): string {
Expand All @@ -190,6 +192,14 @@ class Clipboard {
public readText(): Promise<string> {
return clipboard.readText();
}

public writeBuffer(format: string, buffer: Buffer): void {
this.buffers.set(format, buffer);
}

public readBuffer(format: string): Buffer | undefined {
return this.buffers.get(format);
}
}

class Shell {
Expand Down
12 changes: 8 additions & 4 deletions packages/protocol/src/browser/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { promisify } from "util";
import { Emitter } from "@coder/events";
import { logger, field } from "@coder/logger";
import { ReadWriteConnection, InitData, SharedProcessData } from "../common/connection";
import { Module, ServerProxy } from "../common/proxy";
import { ClientServerProxy, Module, ServerProxy } from "../common/proxy";
import { argumentToProto, protoToArgument, moduleToProto, protoToModule, protoToOperatingSystem } from "../common/util";
import { Argument, Ping, ServerMessage, ClientMessage, Method, Event, Callback } from "../proto";
import { FsModule, ChildProcessModule, NetModule, NodePtyModule, SpdlogModule, TrashModule } from "./modules";
Expand Down Expand Up @@ -224,7 +224,11 @@ export class Client {
field("method", method),
]);

proxyMessage.setArgsList(args.map((a) => argumentToProto(a, storeCallback)));
proxyMessage.setArgsList(args.map((a) => argumentToProto<ClientServerProxy>(
a,
storeCallback,
(p) => p.proxyId,
)));

const clientMessage = new ClientMessage();
clientMessage.setMethod(message);
Expand Down Expand Up @@ -429,7 +433,7 @@ export class Client {
/**
* Return a proxy that makes remote calls.
*/
private createProxy<T>(proxyId: number | Module, promise: Promise<any> = Promise.resolve()): T {
private createProxy<T extends ClientServerProxy>(proxyId: number | Module, promise: Promise<any> = Promise.resolve()): T {
logger.trace(() => [
"creating proxy",
field("proxyId", proxyId),
Expand All @@ -449,7 +453,7 @@ export class Client {
cb(event.event, ...event.args);
});
},
}, {
} as ClientServerProxy, {
get: (target: any, name: string): any => {
// When resolving a promise with a proxy, it will check for "then".
if (name === "then") {
Expand Down
27 changes: 21 additions & 6 deletions packages/protocol/src/browser/modules/child_process.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,22 @@ import * as cp from "child_process";
import * as net from "net";
import * as stream from "stream";
import { callbackify } from "util";
import { ClientProxy } from "../../common/proxy";
import { ChildProcessModuleProxy, ChildProcessProxy, ChildProcessProxies } from "../../node/modules/child_process";
import { Readable, Writable } from "./stream";
import { ClientProxy, ClientServerProxy } from "../../common/proxy";
import { ChildProcessModuleProxy, ChildProcessProxy } from "../../node/modules/child_process";
import { ClientWritableProxy, ClientReadableProxy, Readable, Writable } from "./stream";

// tslint:disable completed-docs

export class ChildProcess extends ClientProxy<ChildProcessProxy> implements cp.ChildProcess {
export interface ClientChildProcessProxy extends ChildProcessProxy, ClientServerProxy<cp.ChildProcess> {}

export interface ClientChildProcessProxies {
childProcess: ClientChildProcessProxy;
stdin?: ClientWritableProxy | null;
stdout?: ClientReadableProxy | null;
stderr?: ClientReadableProxy | null;
}

export class ChildProcess extends ClientProxy<ClientChildProcessProxy> implements cp.ChildProcess {
public readonly stdin: stream.Writable;
public readonly stdout: stream.Readable;
public readonly stderr: stream.Readable;
Expand All @@ -18,7 +27,7 @@ export class ChildProcess extends ClientProxy<ChildProcessProxy> implements cp.C
private _killed: boolean = false;
private _pid = -1;

public constructor(proxyPromises: Promise<ChildProcessProxies>) {
public constructor(proxyPromises: Promise<ClientChildProcessProxies>) {
super(proxyPromises.then((p) => p.childProcess));
this.stdin = new Writable(proxyPromises.then((p) => p.stdin!));
this.stdout = new Readable(proxyPromises.then((p) => p.stdout!));
Expand Down Expand Up @@ -99,8 +108,14 @@ export class ChildProcess extends ClientProxy<ChildProcessProxy> implements cp.C
}
}

interface ClientChildProcessModuleProxy extends ChildProcessModuleProxy, ClientServerProxy {
exec(command: string, options?: { encoding?: string | null } & cp.ExecOptions | null, callback?: ((error: cp.ExecException | null, stdin: string | Buffer, stdout: string | Buffer) => void)): Promise<ClientChildProcessProxies>;
fork(modulePath: string, args?: string[], options?: cp.ForkOptions): Promise<ClientChildProcessProxies>;
spawn(command: string, args?: string[], options?: cp.SpawnOptions): Promise<ClientChildProcessProxies>;
}

export class ChildProcessModule {
public constructor(private readonly proxy: ChildProcessModuleProxy) {}
public constructor(private readonly proxy: ClientChildProcessModuleProxy) {}

public exec = (
command: string,
Expand Down
45 changes: 37 additions & 8 deletions packages/protocol/src/browser/modules/fs.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import * as fs from "fs";
import { callbackify } from "util";
import { ClientProxy, Batch } from "../../common/proxy";
import { Batch, ClientProxy, ClientServerProxy } from "../../common/proxy";
import { IEncodingOptions, IEncodingOptionsCallback } from "../../common/util";
import { FsModuleProxy, Stats as IStats, WatcherProxy, WriteStreamProxy } from "../../node/modules/fs";
import { Writable } from "./stream";
import { FsModuleProxy, ReadStreamProxy, Stats as IStats, WatcherProxy, WriteStreamProxy } from "../../node/modules/fs";
import { Readable, Writable } from "./stream";

// tslint:disable no-any
// tslint:disable completed-docs
// tslint:disable completed-docs no-any

class StatBatch extends Batch<IStats, { path: fs.PathLike }> {
public constructor(private readonly proxy: FsModuleProxy) {
Expand Down Expand Up @@ -38,7 +37,9 @@ class ReaddirBatch extends Batch<Buffer[] | fs.Dirent[] | string[], { path: fs.P
}
}

class Watcher extends ClientProxy<WatcherProxy> implements fs.FSWatcher {
interface ClientWatcherProxy extends WatcherProxy, ClientServerProxy<fs.FSWatcher> {}

class Watcher extends ClientProxy<ClientWatcherProxy> implements fs.FSWatcher {
public close(): void {
this.catch(this.proxy.close());
}
Expand All @@ -48,7 +49,25 @@ class Watcher extends ClientProxy<WatcherProxy> implements fs.FSWatcher {
}
}

class WriteStream extends Writable<WriteStreamProxy> implements fs.WriteStream {
interface ClientReadStreamProxy extends ReadStreamProxy, ClientServerProxy<fs.ReadStream> {}

class ReadStream extends Readable<ClientReadStreamProxy> implements fs.ReadStream {
public get bytesRead(): number {
throw new Error("not implemented");
}

public get path(): string | Buffer {
throw new Error("not implemented");
}

public close(): void {
this.catch(this.proxy.close());
}
}

interface ClientWriteStreamProxy extends WriteStreamProxy, ClientServerProxy<fs.WriteStream> {}

class WriteStream extends Writable<ClientWriteStreamProxy> implements fs.WriteStream {
public get bytesWritten(): number {
throw new Error("not implemented");
}
Expand All @@ -62,12 +81,18 @@ class WriteStream extends Writable<WriteStreamProxy> implements fs.WriteStream {
}
}

interface ClientFsModuleProxy extends FsModuleProxy, ClientServerProxy {
createReadStream(path: fs.PathLike, options?: any): Promise<ClientReadStreamProxy>;
createWriteStream(path: fs.PathLike, options?: any): Promise<ClientWriteStreamProxy>;
watch(filename: fs.PathLike, options?: IEncodingOptions): Promise<ClientWatcherProxy>;
}

export class FsModule {
private readonly statBatch: StatBatch;
private readonly lstatBatch: LstatBatch;
private readonly readdirBatch: ReaddirBatch;

public constructor(private readonly proxy: FsModuleProxy) {
public constructor(private readonly proxy: ClientFsModuleProxy) {
this.statBatch = new StatBatch(this.proxy);
this.lstatBatch = new LstatBatch(this.proxy);
this.readdirBatch = new ReaddirBatch(this.proxy);
Expand Down Expand Up @@ -110,6 +135,10 @@ export class FsModule {
);
}

public createReadStream = (path: fs.PathLike, options?: any): fs.ReadStream => {
return new ReadStream(this.proxy.createReadStream(path, options));
}

public createWriteStream = (path: fs.PathLike, options?: any): fs.WriteStream => {
return new WriteStream(this.proxy.createWriteStream(path, options));
}
Expand Down
24 changes: 18 additions & 6 deletions packages/protocol/src/browser/modules/net.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
import * as net from "net";
import { callbackify } from "util";
import { ClientProxy } from "../../common/proxy";
import { ClientProxy, ClientServerProxy } from "../../common/proxy";
import { NetModuleProxy, NetServerProxy, NetSocketProxy } from "../../node/modules/net";
import { Duplex } from "./stream";

// tslint:disable completed-docs

export class Socket extends Duplex<NetSocketProxy> implements net.Socket {
interface ClientNetSocketProxy extends NetSocketProxy, ClientServerProxy<net.Socket> {}

export class Socket extends Duplex<ClientNetSocketProxy> implements net.Socket {
private _connecting: boolean = false;
private _destroyed: boolean = false;

public constructor(proxyPromise: Promise<NetSocketProxy> | NetSocketProxy, connecting?: boolean) {
public constructor(proxyPromise: Promise<ClientNetSocketProxy> | ClientNetSocketProxy, connecting?: boolean) {
super(proxyPromise);
if (connecting) {
this._connecting = connecting;
Expand Down Expand Up @@ -126,12 +128,16 @@ export class Socket extends Duplex<NetSocketProxy> implements net.Socket {
}
}

export class Server extends ClientProxy<NetServerProxy> implements net.Server {
interface ClientNetServerProxy extends NetServerProxy, ClientServerProxy<net.Server> {
onConnection(cb: (proxy: ClientNetSocketProxy) => void): Promise<void>;
}

export class Server extends ClientProxy<ClientNetServerProxy> implements net.Server {
private socketId = 0;
private readonly sockets = new Map<number, net.Socket>();
private _listening: boolean = false;

public constructor(proxyPromise: Promise<NetServerProxy> | NetServerProxy) {
public constructor(proxyPromise: Promise<ClientNetServerProxy> | ClientNetServerProxy) {
super(proxyPromise);

this.catch(this.proxy.onConnection((socketProxy) => {
Expand Down Expand Up @@ -208,11 +214,17 @@ export class Server extends ClientProxy<NetServerProxy> implements net.Server {

type NodeNet = typeof net;

interface ClientNetModuleProxy extends NetModuleProxy, ClientServerProxy {
createSocket(options?: net.SocketConstructorOpts): Promise<ClientNetSocketProxy>;
createConnection(target: string | number | net.NetConnectOpts, host?: string): Promise<ClientNetSocketProxy>;
createServer(options?: { allowHalfOpen?: boolean, pauseOnConnect?: boolean }): Promise<ClientNetServerProxy>;
}

export class NetModule implements NodeNet {
public readonly Socket: typeof net.Socket;
public readonly Server: typeof net.Server;

public constructor(private readonly proxy: NetModuleProxy) {
public constructor(private readonly proxy: ClientNetModuleProxy) {
// @ts-ignore this is because Socket is missing things from the Stream
// namespace but I'm unsure how best to provide them (finished,
// finished.__promisify__, pipeline, and some others) or if it even matters.
Expand Down
20 changes: 14 additions & 6 deletions packages/protocol/src/browser/modules/node-pty.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
import * as pty from "node-pty";
import { ClientProxy } from "../../common/proxy";
import { ClientProxy, ClientServerProxy } from "../../common/proxy";
import { NodePtyModuleProxy, NodePtyProcessProxy } from "../../node/modules/node-pty";

// tslint:disable completed-docs

export class NodePtyProcess extends ClientProxy<NodePtyProcessProxy> implements pty.IPty {
interface ClientNodePtyProcessProxy extends NodePtyProcessProxy, ClientServerProxy {}

export class NodePtyProcess extends ClientProxy<ClientNodePtyProcessProxy> implements pty.IPty {
private _pid = -1;
private _process = "";

public constructor(
private readonly moduleProxy: NodePtyModuleProxy,
private readonly moduleProxy: ClientNodePtyModuleProxy,
private readonly file: string,
private readonly args: string[] | string,
private readonly options: pty.IPtyForkOptions,
Expand All @@ -18,10 +20,12 @@ export class NodePtyProcess extends ClientProxy<NodePtyProcessProxy> implements
this.on("process", (process) => this._process = process);
}

protected initialize(proxyPromise: Promise<NodePtyProcessProxy>): void {
super.initialize(proxyPromise);
protected initialize(proxyPromise: Promise<ClientNodePtyProcessProxy>): ClientNodePtyProcessProxy {
const proxy = super.initialize(proxyPromise);
this.catch(this.proxy.getPid().then((p) => this._pid = p));
this.catch(this.proxy.getProcess().then((p) => this._process = p));

return proxy;
}

public get pid(): number {
Expand Down Expand Up @@ -53,8 +57,12 @@ export class NodePtyProcess extends ClientProxy<NodePtyProcessProxy> implements

type NodePty = typeof pty;

interface ClientNodePtyModuleProxy extends NodePtyModuleProxy, ClientServerProxy {
spawn(file: string, args: string[] | string, options: pty.IPtyForkOptions): Promise<ClientNodePtyProcessProxy>;
}

export class NodePtyModule implements NodePty {
public constructor(private readonly proxy: NodePtyModuleProxy) {}
public constructor(private readonly proxy: ClientNodePtyModuleProxy) {}

public spawn = (file: string, args: string[] | string, options: pty.IPtyForkOptions): pty.IPty => {
return new NodePtyProcess(this.proxy, file, args, options);
Expand Down
14 changes: 10 additions & 4 deletions packages/protocol/src/browser/modules/spdlog.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import * as spdlog from "spdlog";
import { ClientProxy } from "../../common/proxy";
import { ClientProxy, ClientServerProxy } from "../../common/proxy";
import { RotatingLoggerProxy, SpdlogModuleProxy } from "../../node/modules/spdlog";

// tslint:disable completed-docs

class RotatingLogger extends ClientProxy<RotatingLoggerProxy> implements spdlog.RotatingLogger {
interface ClientRotatingLoggerProxy extends RotatingLoggerProxy, ClientServerProxy {}

class RotatingLogger extends ClientProxy<ClientRotatingLoggerProxy> implements spdlog.RotatingLogger {
public constructor(
private readonly moduleProxy: SpdlogModuleProxy,
private readonly moduleProxy: ClientSpdlogModuleProxy,
private readonly name: string,
private readonly filename: string,
private readonly filesize: number,
Expand All @@ -31,10 +33,14 @@ class RotatingLogger extends ClientProxy<RotatingLoggerProxy> implements spdlog.
}
}

interface ClientSpdlogModuleProxy extends SpdlogModuleProxy, ClientServerProxy {
createLogger(name: string, filePath: string, fileSize: number, fileCount: number): Promise<ClientRotatingLoggerProxy>;
}

export class SpdlogModule {
public readonly RotatingLogger: typeof spdlog.RotatingLogger;

public constructor(private readonly proxy: SpdlogModuleProxy) {
public constructor(private readonly proxy: ClientSpdlogModuleProxy) {
this.RotatingLogger = class extends RotatingLogger {
public constructor(name: string, filename: string, filesize: number, filecount: number) {
super(proxy, name, filename, filesize, filecount);
Expand Down
Loading