From 4d129333fc4a61c70b75d1a2ad172170274e5e58 Mon Sep 17 00:00:00 2001 From: sh7dm Date: Tue, 29 Jan 2019 22:08:49 +0300 Subject: [PATCH 01/27] Add isTTY function --- js/deno.ts | 2 +- js/os.ts | 12 ++++++++++++ src/msg.fbs | 10 +++++++++- src/ops.rs | 24 ++++++++++++++++++++++++ 4 files changed, 46 insertions(+), 2 deletions(-) diff --git a/js/deno.ts b/js/deno.ts index 1cc0a33d11253..42bd38013045d 100644 --- a/js/deno.ts +++ b/js/deno.ts @@ -1,7 +1,7 @@ // Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. // Public deno module. -export { pid, env, exit } from "./os"; +export { pid, env, exit, isTTY } from "./os"; export { chdir, cwd } from "./dir"; export { File, diff --git a/js/os.ts b/js/os.ts index 36093c32cd397..55aeaf033cf0e 100644 --- a/js/os.ts +++ b/js/os.ts @@ -23,6 +23,18 @@ interface CodeInfo { sourceMap: string | undefined; } +/** Check if running in terminal. */ +export function isTTY(): boolean { + const builder = flatbuffers.createBuilder(); + msg.IsTTY.startIsTTY(builder); + const inner = msg.IsTTY.endIsTTY(builder); + const baseRes = sendSync(builder, msg.Any.IsTTY, inner)!; + assert(msg.Any.IsTTYRes === baseRes.innerType()); + const res = new msg.IsTTYRes(); + assert(baseRes.inner(res) != null); + return res.isTty(); +} + /** Exit the Deno process with optional exit code. */ export function exit(exitCode = 0): never { const builder = flatbuffers.createBuilder(); diff --git a/src/msg.fbs b/src/msg.fbs index e13b15daa76a8..e2ced67ef36ba 100644 --- a/src/msg.fbs +++ b/src/msg.fbs @@ -59,7 +59,9 @@ union Any { Run, RunRes, RunStatus, - RunStatusRes + RunStatusRes, + IsTTY, + IsTTYRes } enum ErrorKind: byte { @@ -475,4 +477,10 @@ table RunStatusRes { exit_signal: int; } +table IsTTY {} + +table IsTTYRes { + is_tty: bool; +} + root_type Base; diff --git a/src/ops.rs b/src/ops.rs index 85a731c6a3a03..9fe192a37a6b1 100644 --- a/src/ops.rs +++ b/src/ops.rs @@ -1,4 +1,6 @@ // Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. +extern crate libc; + use crate::errors; use crate::errors::{DenoError, DenoResult, ErrorKind}; use crate::fs as deno_fs; @@ -121,6 +123,7 @@ pub fn dispatch( msg::Any::WorkerPostMessage => op_worker_post_message, msg::Any::Write => op_write, msg::Any::WriteFile => op_write_file, + msg::Any::IsTTY => op_is_tty, _ => panic!(format!( "Unhandled message {}", msg::enum_name_any(inner_type) @@ -173,6 +176,27 @@ pub fn dispatch( (base.sync(), boxed_op) } +fn op_is_tty( + _state: &Arc, + base: &msg::Base<'_>, + _data: libdeno::deno_buf, +) -> Box { + let builder = &mut FlatBufferBuilder::new(); + let inner = msg::IsTTYRes::create( + builder, + &msg::IsTTYResArgs { is_tty: unsafe { libc::isatty(libc::STDIN_FILENO as i32) } != 0 }, + ); + ok_future(serialize_response( + base.cmd_id(), + builder, + msg::BaseArgs { + inner: Some(inner.as_union_value()), + inner_type: msg::Any::IsTTYRes, + ..Default::default() + }, + )) +} + fn op_exit( _config: &Arc, base: &msg::Base<'_>, From b5a3e54e77def712a5ea5b519be9dba0f595a1b5 Mon Sep 17 00:00:00 2001 From: sh7dm Date: Tue, 29 Jan 2019 22:35:00 +0300 Subject: [PATCH 02/27] Fix lint errors --- src/ops.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/ops.rs b/src/ops.rs index 9fe192a37a6b1..f4e44d27b22bd 100644 --- a/src/ops.rs +++ b/src/ops.rs @@ -184,7 +184,9 @@ fn op_is_tty( let builder = &mut FlatBufferBuilder::new(); let inner = msg::IsTTYRes::create( builder, - &msg::IsTTYResArgs { is_tty: unsafe { libc::isatty(libc::STDIN_FILENO as i32) } != 0 }, + &msg::IsTTYResArgs { + is_tty: unsafe { libc::isatty(libc::STDIN_FILENO as i32) } != 0, + }, ); ok_future(serialize_response( base.cmd_id(), From 45f83ae304da6cb2609e0e9035da6405042deca5 Mon Sep 17 00:00:00 2001 From: sh7dm Date: Wed, 30 Jan 2019 18:19:18 +0300 Subject: [PATCH 03/27] Add rid argument to IsTTY --- js/os.ts | 3 ++- src/msg.fbs | 4 +++- src/ops.rs | 19 +++++++++++++++++-- 3 files changed, 22 insertions(+), 4 deletions(-) diff --git a/js/os.ts b/js/os.ts index 55aeaf033cf0e..ab5b690b82c1f 100644 --- a/js/os.ts +++ b/js/os.ts @@ -24,9 +24,10 @@ interface CodeInfo { } /** Check if running in terminal. */ -export function isTTY(): boolean { +export function isTTY(rid = 0): boolean { const builder = flatbuffers.createBuilder(); msg.IsTTY.startIsTTY(builder); + msg.IsTTY.addRid(builder, rid); const inner = msg.IsTTY.endIsTTY(builder); const baseRes = sendSync(builder, msg.Any.IsTTY, inner)!; assert(msg.Any.IsTTYRes === baseRes.innerType()); diff --git a/src/msg.fbs b/src/msg.fbs index e2ced67ef36ba..f44a6a221d0b9 100644 --- a/src/msg.fbs +++ b/src/msg.fbs @@ -477,7 +477,9 @@ table RunStatusRes { exit_signal: int; } -table IsTTY {} +table IsTTY { + rid: uint32; +} table IsTTYRes { is_tty: bool; diff --git a/src/ops.rs b/src/ops.rs index f4e44d27b22bd..f951ac9cd5ea9 100644 --- a/src/ops.rs +++ b/src/ops.rs @@ -1,5 +1,4 @@ // Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. -extern crate libc; use crate::errors; use crate::errors::{DenoError, DenoResult, ErrorKind}; @@ -20,6 +19,7 @@ use crate::resources::Resource; use crate::tokio_util; use crate::version; +use atty; use flatbuffers::FlatBufferBuilder; use futures; use futures::Async; @@ -181,11 +181,26 @@ fn op_is_tty( base: &msg::Base<'_>, _data: libdeno::deno_buf, ) -> Box { + let rid = base.inner_as_is_tty().unwrap().rid(); + //let rid = 0; + let is_tty: bool; + + if rid < 3 { // std in/out/err -- check if is terminal + match rid { + 0 => is_tty = atty::is(atty::Stream::Stdin), + 1 => is_tty = atty::is(atty::Stream::Stdout), + 2 => is_tty = atty::is(atty::Stream::Stderr), + _ => is_tty = false, + } + } else { // file -- false + is_tty = false; + } + let builder = &mut FlatBufferBuilder::new(); let inner = msg::IsTTYRes::create( builder, &msg::IsTTYResArgs { - is_tty: unsafe { libc::isatty(libc::STDIN_FILENO as i32) } != 0, + is_tty: is_tty, }, ); ok_future(serialize_response( From 75db01faa0e6b44c476dae04f8e1ffadd5bd7cc6 Mon Sep 17 00:00:00 2001 From: sh7dm Date: Wed, 30 Jan 2019 18:19:49 +0300 Subject: [PATCH 04/27] Remove unused code --- src/ops.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/ops.rs b/src/ops.rs index f951ac9cd5ea9..ec041f44f0825 100644 --- a/src/ops.rs +++ b/src/ops.rs @@ -182,7 +182,6 @@ fn op_is_tty( _data: libdeno::deno_buf, ) -> Box { let rid = base.inner_as_is_tty().unwrap().rid(); - //let rid = 0; let is_tty: bool; if rid < 3 { // std in/out/err -- check if is terminal From b3a1bb071144e58d3c81bf4aac6410faf5a9d7ec Mon Sep 17 00:00:00 2001 From: sh7dm Date: Wed, 30 Jan 2019 18:48:56 +0300 Subject: [PATCH 05/27] Add an example for IsTTY --- js/os.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/js/os.ts b/js/os.ts index ab5b690b82c1f..209b0e51c1ce9 100644 --- a/js/os.ts +++ b/js/os.ts @@ -23,7 +23,13 @@ interface CodeInfo { sourceMap: string | undefined; } -/** Check if running in terminal. */ +/** Check if running in terminal. + * + * isTTY(0); // stdin + * isTTY(1); // stdout + * isTTY(2); // stderr + * isTTY(3); // < 2 is files by rid + */ export function isTTY(rid = 0): boolean { const builder = flatbuffers.createBuilder(); msg.IsTTY.startIsTTY(builder); From c15c4b645483e2dd3594f44a44dfadedb84972d6 Mon Sep 17 00:00:00 2001 From: sh7dm Date: Wed, 30 Jan 2019 19:33:11 +0300 Subject: [PATCH 06/27] Add a test for IsTTY --- tools/is_tty_test.py | 93 ++++++++++++++++++++++++++++++++++++++++++++ tools/is_tty_test.ts | 25 ++++++++++++ tools/test.py | 3 ++ 3 files changed, 121 insertions(+) create mode 100755 tools/is_tty_test.py create mode 100644 tools/is_tty_test.ts diff --git a/tools/is_tty_test.py b/tools/is_tty_test.py new file mode 100755 index 0000000000000..5835096b4e946 --- /dev/null +++ b/tools/is_tty_test.py @@ -0,0 +1,93 @@ +#!/usr/bin/env python +# Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. +import os +import pty +import select +import subprocess + +from util import build_path, executable_suffix + +from sys import stdin + +IS_TTY_TEST_TS = "tools/is_tty_test.ts" + + +# This function is copied from: +# https://gist.github.com/hayd/4f46a68fc697ba8888a7b517a414583e +# https://stackoverflow.com/q/52954248/1240268 +def tty_capture(cmd, bytes_input): + """Capture the output of cmd with bytes_input to stdin, + with stdin, stdout and stderr as TTYs.""" + mo, so = pty.openpty() # provide tty to enable line-buffering + me, se = pty.openpty() + mi, si = pty.openpty() + fdmap = {mo: 'stdout', me: 'stderr', mi: 'stdin'} + + p = subprocess.Popen( + cmd, bufsize=1, stdin=si, stdout=so, stderr=se, close_fds=True) + os.write(mi, bytes_input) + + timeout = .04 # seconds + res = {'stdout': b'', 'stderr': b''} + while True: + ready, _, _ = select.select([mo, me], [], [], timeout) + if ready: + for fd in ready: + data = os.read(fd, 512) + if not data: + break + res[fdmap[fd]] += data + elif p.poll() is not None: # select timed-out + break # p exited + for fd in [si, so, se, mi, mo, me]: + os.close(fd) # can't do it sooner: it leads to errno.EIO error + p.wait() + return p.returncode, res['stdout'], res['stderr'] + + +class IsTTY(object): + def __init__(self, deno_exe): + self.deno_exe = deno_exe + + def run(self, + arg): + "Returns (return_code, stdout, stderr)." + cmd = [self.deno_exe, IS_TTY_TEST_TS, arg] + return tty_capture(cmd, b'') + + def test_stdin(self): + code, stdout, stderr = self.run('stdin') + assert code == 0 + assert str(stdin.isatty()).lower() in stdout + + def test_stdout(self): + code, stdout, stderr = self.run('stdout') + assert code == 0 + assert str(stdin.isatty()).lower() in stdout + + def test_stderr(self): + code, stdout, stderr = self.run('stderr') + assert code == 0 + assert str(stdin.isatty()).lower() in stdout + + def test_file(self): + code, stdout, stderr = self.run('file') + assert code == 0 + assert b'false' in stdout + + +def is_tty_test(deno_exe): + p = IsTTY(deno_exe) + p.test_stdin() + p.test_stdout() + p.test_stderr() + p.test_file() + + +def main(): + deno_exe = os.path.join(build_path(), "deno" + executable_suffix) + is_tty_test(deno_exe) + + +if __name__ == "__main__": + main() diff --git a/tools/is_tty_test.ts b/tools/is_tty_test.ts new file mode 100644 index 0000000000000..963a9cbfd2835 --- /dev/null +++ b/tools/is_tty_test.ts @@ -0,0 +1,25 @@ +// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. +import { args, exit, isTTY } from "deno"; + +const name = args[1]; +const test = { + stdin: () => { + console.log(isTTY(0)); + }, + stdout: () => { + console.log(isTTY(1)); + }, + stderr: () => { + console.log(isTTY(2)); + }, + file: () => { + console.log(isTTY(10)); + } +}[name]; + +if (!test) { + console.log("Unknown test:", name); + exit(1); +} + +test(); diff --git a/tools/test.py b/tools/test.py index 614395b7197e4..24be5dbf1cdd1 100755 --- a/tools/test.py +++ b/tools/test.py @@ -13,6 +13,7 @@ from benchmark_test import benchmark_test from repl_test import repl_tests from prefetch_test import prefetch_test +from is_tty_test import is_tty_test import subprocess import http_server @@ -71,6 +72,8 @@ def main(argv): from permission_prompt_test import permission_prompt_test permission_prompt_test(deno_exe) + is_tty_test(deno_exe) + repl_tests(deno_exe) rmtree(deno_dir) From b81ffb3dd7b52e350db67890c469c177196540cd Mon Sep 17 00:00:00 2001 From: sh7dm Date: Wed, 30 Jan 2019 19:44:31 +0300 Subject: [PATCH 07/27] Remove unnecessary if..else --- src/ops.rs | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/src/ops.rs b/src/ops.rs index ec041f44f0825..b3dab2692f2ed 100644 --- a/src/ops.rs +++ b/src/ops.rs @@ -184,15 +184,11 @@ fn op_is_tty( let rid = base.inner_as_is_tty().unwrap().rid(); let is_tty: bool; - if rid < 3 { // std in/out/err -- check if is terminal - match rid { - 0 => is_tty = atty::is(atty::Stream::Stdin), - 1 => is_tty = atty::is(atty::Stream::Stdout), - 2 => is_tty = atty::is(atty::Stream::Stderr), - _ => is_tty = false, - } - } else { // file -- false - is_tty = false; + match rid { // if std in/out/err check if is terminal, else return false + 0 => is_tty = atty::is(atty::Stream::Stdin), + 1 => is_tty = atty::is(atty::Stream::Stdout), + 2 => is_tty = atty::is(atty::Stream::Stderr), + _ => is_tty = false, } let builder = &mut FlatBufferBuilder::new(); From d7c4b702dccf91af4261394905195a055c19fdaf Mon Sep 17 00:00:00 2001 From: sh7dm Date: Thu, 31 Jan 2019 16:01:13 +0300 Subject: [PATCH 08/27] remove unused var from test --- tools/is_tty_test.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tools/is_tty_test.py b/tools/is_tty_test.py index 5835096b4e946..ab1a99d42bdad 100755 --- a/tools/is_tty_test.py +++ b/tools/is_tty_test.py @@ -56,22 +56,22 @@ def run(self, return tty_capture(cmd, b'') def test_stdin(self): - code, stdout, stderr = self.run('stdin') + code, stdout, _ = self.run('stdin') assert code == 0 assert str(stdin.isatty()).lower() in stdout def test_stdout(self): - code, stdout, stderr = self.run('stdout') + code, stdout, _ = self.run('stdout') assert code == 0 assert str(stdin.isatty()).lower() in stdout def test_stderr(self): - code, stdout, stderr = self.run('stderr') + code, stdout, _ = self.run('stderr') assert code == 0 assert str(stdin.isatty()).lower() in stdout def test_file(self): - code, stdout, stderr = self.run('file') + code, stdout, _ = self.run('file') assert code == 0 assert b'false' in stdout From 3085dc1c6b0ea0e6250b8adc5fbfc58a1513128d Mon Sep 17 00:00:00 2001 From: sh7dm Date: Thu, 31 Jan 2019 16:13:48 +0300 Subject: [PATCH 09/27] Format code --- src/ops.rs | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/ops.rs b/src/ops.rs index b3dab2692f2ed..9432f9130dc55 100644 --- a/src/ops.rs +++ b/src/ops.rs @@ -184,7 +184,8 @@ fn op_is_tty( let rid = base.inner_as_is_tty().unwrap().rid(); let is_tty: bool; - match rid { // if std in/out/err check if is terminal, else return false + match rid { + // if std in/out/err check if is terminal, else return false 0 => is_tty = atty::is(atty::Stream::Stdin), 1 => is_tty = atty::is(atty::Stream::Stdout), 2 => is_tty = atty::is(atty::Stream::Stderr), @@ -192,12 +193,8 @@ fn op_is_tty( } let builder = &mut FlatBufferBuilder::new(); - let inner = msg::IsTTYRes::create( - builder, - &msg::IsTTYResArgs { - is_tty: is_tty, - }, - ); + let inner = + msg::IsTTYRes::create(builder, &msg::IsTTYResArgs { is_tty: is_tty }); ok_future(serialize_response( base.cmd_id(), builder, From f26ca3ac0930cbef921b787de5a000c3aeb1ea81 Mon Sep 17 00:00:00 2001 From: sh7dm Date: Fri, 1 Feb 2019 18:11:13 +0300 Subject: [PATCH 10/27] Change IsTTY output format --- js/os.ts | 30 ++++++++++++++++++++++-------- tools/is_tty_test.py | 7 ------- tools/is_tty_test.ts | 9 +++------ 3 files changed, 25 insertions(+), 21 deletions(-) diff --git a/js/os.ts b/js/os.ts index 209b0e51c1ce9..6096cdd06850e 100644 --- a/js/os.ts +++ b/js/os.ts @@ -23,14 +23,8 @@ interface CodeInfo { sourceMap: string | undefined; } -/** Check if running in terminal. - * - * isTTY(0); // stdin - * isTTY(1); // stdout - * isTTY(2); // stderr - * isTTY(3); // < 2 is files by rid - */ -export function isTTY(rid = 0): boolean { +/** @internal */ +function checkTTY(rid: number): boolean { const builder = flatbuffers.createBuilder(); msg.IsTTY.startIsTTY(builder); msg.IsTTY.addRid(builder, rid); @@ -42,6 +36,26 @@ export function isTTY(rid = 0): boolean { return res.isTty(); } +interface IsTTY { + stdin: boolean; + stdout: boolean; + stderr: boolean; +} + +/** Check if running in terminal. + * + * isTTY().stdin; // stdin + * isTTY().stdout; // stdout + * isTTY().stderr; // stderr + */ +export function isTTY(): IsTTY { + return { + stdin: checkTTY(0), + stdout: checkTTY(1), + stderr: checkTTY(2) + }; +} + /** Exit the Deno process with optional exit code. */ export function exit(exitCode = 0): never { const builder = flatbuffers.createBuilder(); diff --git a/tools/is_tty_test.py b/tools/is_tty_test.py index ab1a99d42bdad..a88c52799718b 100755 --- a/tools/is_tty_test.py +++ b/tools/is_tty_test.py @@ -70,18 +70,11 @@ def test_stderr(self): assert code == 0 assert str(stdin.isatty()).lower() in stdout - def test_file(self): - code, stdout, _ = self.run('file') - assert code == 0 - assert b'false' in stdout - - def is_tty_test(deno_exe): p = IsTTY(deno_exe) p.test_stdin() p.test_stdout() p.test_stderr() - p.test_file() def main(): diff --git a/tools/is_tty_test.ts b/tools/is_tty_test.ts index 963a9cbfd2835..f048293e32a8b 100644 --- a/tools/is_tty_test.ts +++ b/tools/is_tty_test.ts @@ -4,16 +4,13 @@ import { args, exit, isTTY } from "deno"; const name = args[1]; const test = { stdin: () => { - console.log(isTTY(0)); + console.log(isTTY().stdin); }, stdout: () => { - console.log(isTTY(1)); + console.log(isTTY().stdout); }, stderr: () => { - console.log(isTTY(2)); - }, - file: () => { - console.log(isTTY(10)); + console.log(isTTY().stderr); } }[name]; From 533907d3c255a9619217c78abe479efb6499d2bf Mon Sep 17 00:00:00 2001 From: sh7dm Date: Fri, 1 Feb 2019 20:15:11 +0300 Subject: [PATCH 11/27] Get TTY info in 1 op --- js/os.ts | 27 +++++++++++---------------- src/msg.fbs | 8 ++++---- src/ops.rs | 17 +++++------------ 3 files changed, 20 insertions(+), 32 deletions(-) diff --git a/js/os.ts b/js/os.ts index 6096cdd06850e..4aed229377baf 100644 --- a/js/os.ts +++ b/js/os.ts @@ -23,19 +23,6 @@ interface CodeInfo { sourceMap: string | undefined; } -/** @internal */ -function checkTTY(rid: number): boolean { - const builder = flatbuffers.createBuilder(); - msg.IsTTY.startIsTTY(builder); - msg.IsTTY.addRid(builder, rid); - const inner = msg.IsTTY.endIsTTY(builder); - const baseRes = sendSync(builder, msg.Any.IsTTY, inner)!; - assert(msg.Any.IsTTYRes === baseRes.innerType()); - const res = new msg.IsTTYRes(); - assert(baseRes.inner(res) != null); - return res.isTty(); -} - interface IsTTY { stdin: boolean; stdout: boolean; @@ -49,10 +36,18 @@ interface IsTTY { * isTTY().stderr; // stderr */ export function isTTY(): IsTTY { + const builder = flatbuffers.createBuilder(); + msg.IsTTY.startIsTTY(builder); + const inner = msg.IsTTY.endIsTTY(builder); + const baseRes = sendSync(builder, msg.Any.IsTTY, inner)!; + assert(msg.Any.IsTTYRes === baseRes.innerType()); + const res = new msg.IsTTYRes(); + assert(baseRes.inner(res) != null); + return { - stdin: checkTTY(0), - stdout: checkTTY(1), - stderr: checkTTY(2) + stdin: res.stdin(), + stdout: res.stdout(), + stderr: res.stderr() }; } diff --git a/src/msg.fbs b/src/msg.fbs index f44a6a221d0b9..3720d8c7984b9 100644 --- a/src/msg.fbs +++ b/src/msg.fbs @@ -477,12 +477,12 @@ table RunStatusRes { exit_signal: int; } -table IsTTY { - rid: uint32; -} +table IsTTY {} table IsTTYRes { - is_tty: bool; + stdin: bool; + stdout: bool; + stderr: bool; } root_type Base; diff --git a/src/ops.rs b/src/ops.rs index 9432f9130dc55..81a26e60cf1c9 100644 --- a/src/ops.rs +++ b/src/ops.rs @@ -181,20 +181,13 @@ fn op_is_tty( base: &msg::Base<'_>, _data: libdeno::deno_buf, ) -> Box { - let rid = base.inner_as_is_tty().unwrap().rid(); - let is_tty: bool; - - match rid { - // if std in/out/err check if is terminal, else return false - 0 => is_tty = atty::is(atty::Stream::Stdin), - 1 => is_tty = atty::is(atty::Stream::Stdout), - 2 => is_tty = atty::is(atty::Stream::Stderr), - _ => is_tty = false, - } - let builder = &mut FlatBufferBuilder::new(); let inner = - msg::IsTTYRes::create(builder, &msg::IsTTYResArgs { is_tty: is_tty }); + msg::IsTTYRes::create(builder, &msg::IsTTYResArgs { + stdin: atty::is(atty::Stream::Stdin), + stdout: atty::is(atty::Stream::Stdout), + stderr: atty::is(atty::Stream::Stderr) + }); ok_future(serialize_response( base.cmd_id(), builder, From 2c56aba9db75b23d3d40f3d8846b11fb203bb2ae Mon Sep 17 00:00:00 2001 From: sh7dm Date: Fri, 1 Feb 2019 20:29:46 +0300 Subject: [PATCH 12/27] Format code --- src/ops.rs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/ops.rs b/src/ops.rs index 81a26e60cf1c9..de513982098c4 100644 --- a/src/ops.rs +++ b/src/ops.rs @@ -182,12 +182,14 @@ fn op_is_tty( _data: libdeno::deno_buf, ) -> Box { let builder = &mut FlatBufferBuilder::new(); - let inner = - msg::IsTTYRes::create(builder, &msg::IsTTYResArgs { + let inner = msg::IsTTYRes::create( + builder, + &msg::IsTTYResArgs { stdin: atty::is(atty::Stream::Stdin), stdout: atty::is(atty::Stream::Stdout), - stderr: atty::is(atty::Stream::Stderr) - }); + stderr: atty::is(atty::Stream::Stderr), + }, + ); ok_future(serialize_response( base.cmd_id(), builder, From 16497d1387a015de85028d8d6c487cbc6938c8d8 Mon Sep 17 00:00:00 2001 From: sh7dm Date: Fri, 1 Feb 2019 21:05:37 +0300 Subject: [PATCH 13/27] Add IsTTY result caching --- js/os.ts | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/js/os.ts b/js/os.ts index 4aed229377baf..96e1ab5881337 100644 --- a/js/os.ts +++ b/js/os.ts @@ -29,6 +29,8 @@ interface IsTTY { stderr: boolean; } +let _isTTY: IsTTY; // cache + /** Check if running in terminal. * * isTTY().stdin; // stdin @@ -36,6 +38,10 @@ interface IsTTY { * isTTY().stderr; // stderr */ export function isTTY(): IsTTY { + if (_isTTY) { + return _isTTY; // return cached value if we have one + } + const builder = flatbuffers.createBuilder(); msg.IsTTY.startIsTTY(builder); const inner = msg.IsTTY.endIsTTY(builder); @@ -44,11 +50,12 @@ export function isTTY(): IsTTY { const res = new msg.IsTTYRes(); assert(baseRes.inner(res) != null); - return { + _isTTY = { stdin: res.stdin(), stdout: res.stdout(), stderr: res.stderr() }; + return _isTTY; } /** Exit the Deno process with optional exit code. */ From 9c7e56f2d8163e90b67afe92c863a9fc50c7e038 Mon Sep 17 00:00:00 2001 From: Dmitry Sharshakov Date: Fri, 1 Feb 2019 22:57:13 +0300 Subject: [PATCH 14/27] Remove IsTTY caching --- js/os.ts | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/js/os.ts b/js/os.ts index 96e1ab5881337..4aed229377baf 100644 --- a/js/os.ts +++ b/js/os.ts @@ -29,8 +29,6 @@ interface IsTTY { stderr: boolean; } -let _isTTY: IsTTY; // cache - /** Check if running in terminal. * * isTTY().stdin; // stdin @@ -38,10 +36,6 @@ let _isTTY: IsTTY; // cache * isTTY().stderr; // stderr */ export function isTTY(): IsTTY { - if (_isTTY) { - return _isTTY; // return cached value if we have one - } - const builder = flatbuffers.createBuilder(); msg.IsTTY.startIsTTY(builder); const inner = msg.IsTTY.endIsTTY(builder); @@ -50,12 +44,11 @@ export function isTTY(): IsTTY { const res = new msg.IsTTYRes(); assert(baseRes.inner(res) != null); - _isTTY = { + return { stdin: res.stdin(), stdout: res.stdout(), stderr: res.stderr() }; - return _isTTY; } /** Exit the Deno process with optional exit code. */ From 9b1d935ffffd5337912942840000ca1d8cfd1b58 Mon Sep 17 00:00:00 2001 From: Dmitry Sharshakov Date: Fri, 1 Feb 2019 23:05:46 +0300 Subject: [PATCH 15/27] Update IsTTY example --- js/os.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/js/os.ts b/js/os.ts index 4aed229377baf..9fff9aed9e734 100644 --- a/js/os.ts +++ b/js/os.ts @@ -31,9 +31,8 @@ interface IsTTY { /** Check if running in terminal. * - * isTTY().stdin; // stdin - * isTTY().stdout; // stdout - * isTTY().stderr; // stderr + * import { isTTY } from "deno"; + * console.log(isTTY.stdout); */ export function isTTY(): IsTTY { const builder = flatbuffers.createBuilder(); From e32d2db43e2053b82a41a80b60c03085c8a42eac Mon Sep 17 00:00:00 2001 From: Dmitry Sharshakov Date: Fri, 1 Feb 2019 23:07:14 +0300 Subject: [PATCH 16/27] Use inline interface for IsTTY --- js/os.ts | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/js/os.ts b/js/os.ts index 9fff9aed9e734..2ac8e22d0dc4e 100644 --- a/js/os.ts +++ b/js/os.ts @@ -23,11 +23,7 @@ interface CodeInfo { sourceMap: string | undefined; } -interface IsTTY { - stdin: boolean; - stdout: boolean; - stderr: boolean; -} +interface IsTTY { stdin: boolean, stdout: boolean, stderr: boolean } /** Check if running in terminal. * From fb9ab75f16d4bdfb8b488446ebfc3f8ecc7285c9 Mon Sep 17 00:00:00 2001 From: sh7dm Date: Fri, 1 Feb 2019 23:09:49 +0300 Subject: [PATCH 17/27] Add a simple test to os_test --- js/os_test.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/js/os_test.ts b/js/os_test.ts index 21ec5e69d0d7b..ac11bfe9dce6e 100644 --- a/js/os_test.ts +++ b/js/os_test.ts @@ -27,3 +27,8 @@ test(function osPid() { console.log("pid", deno.pid); assert(deno.pid > 0); }); + +// See complete tests in tools/tty_test.py +test(function osIsTTYSmoke() { + console.log(deno.isTTY()); +}); From 6f209772c03228d6af8c9dfb0faef19ae496cdf8 Mon Sep 17 00:00:00 2001 From: sh7dm Date: Fri, 1 Feb 2019 23:13:01 +0300 Subject: [PATCH 18/27] Fix inline interface & move unit test link --- js/os.ts | 12 ++++++------ js/os_test.ts | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/js/os.ts b/js/os.ts index 2ac8e22d0dc4e..8d74dc4d77b94 100644 --- a/js/os.ts +++ b/js/os.ts @@ -23,7 +23,11 @@ interface CodeInfo { sourceMap: string | undefined; } -interface IsTTY { stdin: boolean, stdout: boolean, stderr: boolean } +interface IsTTY { + stdin: boolean; + stdout: boolean; + stderr: boolean; +} /** Check if running in terminal. * @@ -39,11 +43,7 @@ export function isTTY(): IsTTY { const res = new msg.IsTTYRes(); assert(baseRes.inner(res) != null); - return { - stdin: res.stdin(), - stdout: res.stdout(), - stderr: res.stderr() - }; + return { stdin: res.stdin(), stdout: res.stdout(), stderr: res.stderr() }; } /** Exit the Deno process with optional exit code. */ diff --git a/js/os_test.ts b/js/os_test.ts index ac11bfe9dce6e..0784fd5e40060 100644 --- a/js/os_test.ts +++ b/js/os_test.ts @@ -28,7 +28,7 @@ test(function osPid() { assert(deno.pid > 0); }); -// See complete tests in tools/tty_test.py +// See complete tests in tools/is_tty_test.py test(function osIsTTYSmoke() { console.log(deno.isTTY()); }); From f9594033840e65d75ca7d4bbaedcece7a9ad3204 Mon Sep 17 00:00:00 2001 From: Dmitry Sharshakov Date: Sat, 2 Feb 2019 07:44:38 +0300 Subject: [PATCH 19/27] Fix IsTTY example --- js/os.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/js/os.ts b/js/os.ts index 8d74dc4d77b94..3d1479964d4f9 100644 --- a/js/os.ts +++ b/js/os.ts @@ -31,8 +31,8 @@ interface IsTTY { /** Check if running in terminal. * - * import { isTTY } from "deno"; - * console.log(isTTY.stdout); + * import { isTTY } from "deno"; + * console.log(isTTY().stdout); */ export function isTTY(): IsTTY { const builder = flatbuffers.createBuilder(); From 91250f9fdbd8cbd4ff656a281dfa22f66f7d83e3 Mon Sep 17 00:00:00 2001 From: sh7dm Date: Sat, 2 Feb 2019 08:13:25 +0300 Subject: [PATCH 20/27] Use inline interface instead of classic one --- js/os.ts | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/js/os.ts b/js/os.ts index 8d74dc4d77b94..baecf43061ca7 100644 --- a/js/os.ts +++ b/js/os.ts @@ -23,18 +23,12 @@ interface CodeInfo { sourceMap: string | undefined; } -interface IsTTY { - stdin: boolean; - stdout: boolean; - stderr: boolean; -} - /** Check if running in terminal. * * import { isTTY } from "deno"; * console.log(isTTY.stdout); */ -export function isTTY(): IsTTY { +export function isTTY(): { stdin: boolean; stdout: boolean; stderr: boolean } { const builder = flatbuffers.createBuilder(); msg.IsTTY.startIsTTY(builder); const inner = msg.IsTTY.endIsTTY(builder); From 9c8af0c48c1782eaa6a22ae39ff0fea598781e8b Mon Sep 17 00:00:00 2001 From: sh7dm Date: Sat, 2 Feb 2019 08:18:47 +0300 Subject: [PATCH 21/27] Fix some issues in IsTTY test --- tools/is_tty_test.py | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/tools/is_tty_test.py b/tools/is_tty_test.py index a88c52799718b..308adafeb53df 100755 --- a/tools/is_tty_test.py +++ b/tools/is_tty_test.py @@ -11,13 +11,9 @@ IS_TTY_TEST_TS = "tools/is_tty_test.ts" - -# This function is copied from: -# https://gist.github.com/hayd/4f46a68fc697ba8888a7b517a414583e -# https://stackoverflow.com/q/52954248/1240268 def tty_capture(cmd, bytes_input): - """Capture the output of cmd with bytes_input to stdin, - with stdin, stdout and stderr as TTYs.""" + '''Capture the output of cmd with bytes_input to stdin, + with stdin, stdout and stderr as TTYs.''' mo, so = pty.openpty() # provide tty to enable line-buffering me, se = pty.openpty() mi, si = pty.openpty() From 2ce79c11e95999524313b17e0a9d306ccbb4fb52 Mon Sep 17 00:00:00 2001 From: sh7dm Date: Sat, 2 Feb 2019 08:23:48 +0300 Subject: [PATCH 22/27] Move IsTTY test to another file --- tests/is_tty.ts | 2 ++ tools/is_tty_test.py | 2 +- tools/is_tty_test.ts | 22 ---------------------- 3 files changed, 3 insertions(+), 23 deletions(-) create mode 100644 tests/is_tty.ts delete mode 100644 tools/is_tty_test.ts diff --git a/tests/is_tty.ts b/tests/is_tty.ts new file mode 100644 index 0000000000000..48f67d4badcf4 --- /dev/null +++ b/tests/is_tty.ts @@ -0,0 +1,2 @@ +import { isTTY } from "deno"; +console.log(isTTY()); diff --git a/tools/is_tty_test.py b/tools/is_tty_test.py index 308adafeb53df..cdff700966fda 100755 --- a/tools/is_tty_test.py +++ b/tools/is_tty_test.py @@ -9,7 +9,7 @@ from sys import stdin -IS_TTY_TEST_TS = "tools/is_tty_test.ts" +IS_TTY_TEST_TS = "tests/is_tty.ts" def tty_capture(cmd, bytes_input): '''Capture the output of cmd with bytes_input to stdin, diff --git a/tools/is_tty_test.ts b/tools/is_tty_test.ts deleted file mode 100644 index f048293e32a8b..0000000000000 --- a/tools/is_tty_test.ts +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. -import { args, exit, isTTY } from "deno"; - -const name = args[1]; -const test = { - stdin: () => { - console.log(isTTY().stdin); - }, - stdout: () => { - console.log(isTTY().stdout); - }, - stderr: () => { - console.log(isTTY().stderr); - } -}[name]; - -if (!test) { - console.log("Unknown test:", name); - exit(1); -} - -test(); From 273628eeac34dd482ac66bd975fd9db5538e5b06 Mon Sep 17 00:00:00 2001 From: sh7dm Date: Sat, 2 Feb 2019 08:25:35 +0300 Subject: [PATCH 23/27] Remove tty_capture, just import it --- tools/is_tty_test.py | 30 +----------------------------- 1 file changed, 1 insertion(+), 29 deletions(-) diff --git a/tools/is_tty_test.py b/tools/is_tty_test.py index cdff700966fda..6f8f2fa84b6d0 100755 --- a/tools/is_tty_test.py +++ b/tools/is_tty_test.py @@ -11,35 +11,7 @@ IS_TTY_TEST_TS = "tests/is_tty.ts" -def tty_capture(cmd, bytes_input): - '''Capture the output of cmd with bytes_input to stdin, - with stdin, stdout and stderr as TTYs.''' - mo, so = pty.openpty() # provide tty to enable line-buffering - me, se = pty.openpty() - mi, si = pty.openpty() - fdmap = {mo: 'stdout', me: 'stderr', mi: 'stdin'} - - p = subprocess.Popen( - cmd, bufsize=1, stdin=si, stdout=so, stderr=se, close_fds=True) - os.write(mi, bytes_input) - - timeout = .04 # seconds - res = {'stdout': b'', 'stderr': b''} - while True: - ready, _, _ = select.select([mo, me], [], [], timeout) - if ready: - for fd in ready: - data = os.read(fd, 512) - if not data: - break - res[fdmap[fd]] += data - elif p.poll() is not None: # select timed-out - break # p exited - for fd in [si, so, se, mi, mo, me]: - os.close(fd) # can't do it sooner: it leads to errno.EIO error - p.wait() - return p.returncode, res['stdout'], res['stderr'] - +from permission_prompt_test import tty_capture class IsTTY(object): def __init__(self, deno_exe): From 67543de43e245340851d40c30abce28396132741 Mon Sep 17 00:00:00 2001 From: sh7dm Date: Sat, 2 Feb 2019 08:39:55 +0300 Subject: [PATCH 24/27] Clean up IsTTY test --- tests/is_tty.ts | 2 +- tools/is_tty_test.py | 27 ++++----------------------- 2 files changed, 5 insertions(+), 24 deletions(-) diff --git a/tests/is_tty.ts b/tests/is_tty.ts index 48f67d4badcf4..a571aee1862d0 100644 --- a/tests/is_tty.ts +++ b/tests/is_tty.ts @@ -1,2 +1,2 @@ import { isTTY } from "deno"; -console.log(isTTY()); +console.log(isTTY().stdin); diff --git a/tools/is_tty_test.py b/tools/is_tty_test.py index 6f8f2fa84b6d0..89a84bb534269 100755 --- a/tools/is_tty_test.py +++ b/tools/is_tty_test.py @@ -17,38 +17,19 @@ class IsTTY(object): def __init__(self, deno_exe): self.deno_exe = deno_exe - def run(self, - arg): - "Returns (return_code, stdout, stderr)." - cmd = [self.deno_exe, IS_TTY_TEST_TS, arg] - return tty_capture(cmd, b'') - - def test_stdin(self): - code, stdout, _ = self.run('stdin') - assert code == 0 - assert str(stdin.isatty()).lower() in stdout - - def test_stdout(self): - code, stdout, _ = self.run('stdout') - assert code == 0 - assert str(stdin.isatty()).lower() in stdout - - def test_stderr(self): - code, stdout, _ = self.run('stderr') + def test(self): + cmd = [self.deno_exe, IS_TTY_TEST_TS, b''] + code, stdout, _ = tty_capture(cmd, b'') assert code == 0 assert str(stdin.isatty()).lower() in stdout def is_tty_test(deno_exe): p = IsTTY(deno_exe) - p.test_stdin() - p.test_stdout() - p.test_stderr() - + p.test() def main(): deno_exe = os.path.join(build_path(), "deno" + executable_suffix) is_tty_test(deno_exe) - if __name__ == "__main__": main() From 1ef996879332ba0c7f9e335db55b238816219417 Mon Sep 17 00:00:00 2001 From: sh7dm Date: Sat, 2 Feb 2019 09:08:00 +0300 Subject: [PATCH 25/27] Clean up IsTTY test --- tools/is_tty_test.py | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/tools/is_tty_test.py b/tools/is_tty_test.py index 89a84bb534269..ceccf660d926c 100755 --- a/tools/is_tty_test.py +++ b/tools/is_tty_test.py @@ -13,19 +13,11 @@ from permission_prompt_test import tty_capture -class IsTTY(object): - def __init__(self, deno_exe): - self.deno_exe = deno_exe - - def test(self): - cmd = [self.deno_exe, IS_TTY_TEST_TS, b''] - code, stdout, _ = tty_capture(cmd, b'') - assert code == 0 - assert str(stdin.isatty()).lower() in stdout - def is_tty_test(deno_exe): - p = IsTTY(deno_exe) - p.test() + cmd = [deno_exe, IS_TTY_TEST_TS, b''] + code, stdout, _ = tty_capture(cmd, b'') + assert code == 0 + assert str(stdin.isatty()).lower() in stdout def main(): deno_exe = os.path.join(build_path(), "deno" + executable_suffix) From 7ebe4bc5f1b42bd29e0ca48e58a2ee53acd3644e Mon Sep 17 00:00:00 2001 From: sh7dm Date: Sat, 2 Feb 2019 09:33:58 +0300 Subject: [PATCH 26/27] Skip IsTTY test on Windows because it was failing --- tools/test.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/test.py b/tools/test.py index 24be5dbf1cdd1..f7dccc337bf2d 100755 --- a/tools/test.py +++ b/tools/test.py @@ -65,14 +65,14 @@ def main(argv): integration_tests(deno_exe) - # TODO We currently skip testing the prompt in Windows completely. + # TODO We currently skip testing the prompt and IsTTY in Windows completely. # Windows does not support the pty module used for testing the permission # prompt. if os.name != 'nt': from permission_prompt_test import permission_prompt_test + from is_tty_test import is_tty_test permission_prompt_test(deno_exe) - - is_tty_test(deno_exe) + is_tty_test(deno_exe) repl_tests(deno_exe) From 536b5ac0957110012dd4013d3705645e88c4765e Mon Sep 17 00:00:00 2001 From: sh7dm Date: Sat, 2 Feb 2019 09:47:43 +0300 Subject: [PATCH 27/27] Clean IsTTY test --- tools/is_tty_test.py | 7 ++----- tools/test.py | 1 - 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/tools/is_tty_test.py b/tools/is_tty_test.py index ceccf660d926c..218e7f6208215 100755 --- a/tools/is_tty_test.py +++ b/tools/is_tty_test.py @@ -4,17 +4,14 @@ import pty import select import subprocess - from util import build_path, executable_suffix - from sys import stdin +from permission_prompt_test import tty_capture IS_TTY_TEST_TS = "tests/is_tty.ts" -from permission_prompt_test import tty_capture - def is_tty_test(deno_exe): - cmd = [deno_exe, IS_TTY_TEST_TS, b''] + cmd = [deno_exe, IS_TTY_TEST_TS] code, stdout, _ = tty_capture(cmd, b'') assert code == 0 assert str(stdin.isatty()).lower() in stdout diff --git a/tools/test.py b/tools/test.py index f7dccc337bf2d..5a2a937af8a54 100755 --- a/tools/test.py +++ b/tools/test.py @@ -13,7 +13,6 @@ from benchmark_test import benchmark_test from repl_test import repl_tests from prefetch_test import prefetch_test -from is_tty_test import is_tty_test import subprocess import http_server