Skip to content

Commit

Permalink
Add isTTY function (denoland#1622)
Browse files Browse the repository at this point in the history
  • Loading branch information
Dmitry Sharshakov authored and ry committed Feb 3, 2019
1 parent 1d48e02 commit 181b032
Show file tree
Hide file tree
Showing 8 changed files with 91 additions and 3 deletions.
2 changes: 1 addition & 1 deletion 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,
Expand Down
17 changes: 17 additions & 0 deletions js/os.ts
Expand Up @@ -21,6 +21,23 @@ interface CodeInfo {
sourceCode: string | undefined;
}

/** Check if running in terminal.
*
* import { isTTY } from "deno";
* console.log(isTTY().stdout);
*/
export function isTTY(): { stdin: boolean; stdout: boolean; stderr: 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 { stdin: res.stdin(), stdout: res.stdout(), stderr: res.stderr() };
}

/** Exit the Deno process with optional exit code. */
export function exit(exitCode = 0): never {
const builder = flatbuffers.createBuilder();
Expand Down
5 changes: 5 additions & 0 deletions js/os_test.ts
Expand Up @@ -27,3 +27,8 @@ test(function osPid() {
console.log("pid", deno.pid);
assert(deno.pid > 0);
});

// See complete tests in tools/is_tty_test.py
test(function osIsTTYSmoke() {
console.log(deno.isTTY());
});
12 changes: 11 additions & 1 deletion src/msg.fbs
Expand Up @@ -61,7 +61,9 @@ union Any {
RunStatus,
RunStatusRes,
Now,
NowRes
NowRes,
IsTTY,
IsTTYRes
}

enum ErrorKind: byte {
Expand Down Expand Up @@ -483,4 +485,12 @@ table NowRes {
time: uint64;
}

table IsTTY {}

table IsTTYRes {
stdin: bool;
stdout: bool;
stderr: bool;
}

root_type Base;
28 changes: 28 additions & 0 deletions src/ops.rs
@@ -1,4 +1,5 @@
// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.

use crate::errors;
use crate::errors::{DenoError, DenoResult, ErrorKind};
use crate::fs as deno_fs;
Expand All @@ -18,6 +19,7 @@ use crate::resources::Resource;
use crate::tokio_util;
use crate::version;

use atty;
use flatbuffers::FlatBufferBuilder;
use futures;
use futures::Async;
Expand Down Expand Up @@ -121,6 +123,7 @@ pub fn dispatch(
msg::Any::Write => op_write,
msg::Any::WriteFile => op_write_file,
msg::Any::Now => op_now,
msg::Any::IsTTY => op_is_tty,
_ => panic!(format!(
"Unhandled message {}",
msg::enum_name_any(inner_type)
Expand Down Expand Up @@ -197,6 +200,31 @@ fn op_now(
))
}

fn op_is_tty(
_state: &Arc<IsolateState>,
base: &msg::Base<'_>,
_data: libdeno::deno_buf,
) -> Box<Op> {
let builder = &mut FlatBufferBuilder::new();
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),
},
);
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<IsolateState>,
base: &msg::Base<'_>,
Expand Down
2 changes: 2 additions & 0 deletions tests/is_tty.ts
@@ -0,0 +1,2 @@
import { isTTY } from "deno";
console.log(isTTY().stdin);
24 changes: 24 additions & 0 deletions tools/is_tty_test.py
@@ -0,0 +1,24 @@
#!/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
from permission_prompt_test import tty_capture

IS_TTY_TEST_TS = "tests/is_tty.ts"

def is_tty_test(deno_exe):
cmd = [deno_exe, IS_TTY_TEST_TS]
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)
is_tty_test(deno_exe)

if __name__ == "__main__":
main()
4 changes: 3 additions & 1 deletion tools/test.py
Expand Up @@ -66,12 +66,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)

repl_tests(deno_exe)

Expand Down

0 comments on commit 181b032

Please sign in to comment.