summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--js/deno.ts2
-rw-r--r--js/os.ts17
-rw-r--r--js/os_test.ts5
-rw-r--r--src/msg.fbs12
-rw-r--r--src/ops.rs28
-rw-r--r--tests/is_tty.ts2
-rwxr-xr-xtools/is_tty_test.py24
-rwxr-xr-xtools/test.py4
8 files changed, 91 insertions, 3 deletions
diff --git a/js/deno.ts b/js/deno.ts
index 1cc0a33d1..42bd38013 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 61b6ed974..3122830cf 100644
--- a/js/os.ts
+++ b/js/os.ts
@@ -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();
diff --git a/js/os_test.ts b/js/os_test.ts
index 21ec5e69d..0784fd5e4 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/is_tty_test.py
+test(function osIsTTYSmoke() {
+ console.log(deno.isTTY());
+});
diff --git a/src/msg.fbs b/src/msg.fbs
index 0bbc18b1d..d7e71ab14 100644
--- a/src/msg.fbs
+++ b/src/msg.fbs
@@ -61,7 +61,9 @@ union Any {
RunStatus,
RunStatusRes,
Now,
- NowRes
+ NowRes,
+ IsTTY,
+ IsTTYRes
}
enum ErrorKind: byte {
@@ -483,4 +485,12 @@ table NowRes {
time: uint64;
}
+table IsTTY {}
+
+table IsTTYRes {
+ stdin: bool;
+ stdout: bool;
+ stderr: bool;
+}
+
root_type Base;
diff --git a/src/ops.rs b/src/ops.rs
index b17db87b2..b30473eb6 100644
--- a/src/ops.rs
+++ b/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;
@@ -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;
@@ -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)
@@ -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<'_>,
diff --git a/tests/is_tty.ts b/tests/is_tty.ts
new file mode 100644
index 000000000..a571aee18
--- /dev/null
+++ b/tests/is_tty.ts
@@ -0,0 +1,2 @@
+import { isTTY } from "deno";
+console.log(isTTY().stdin);
diff --git a/tools/is_tty_test.py b/tools/is_tty_test.py
new file mode 100755
index 000000000..218e7f620
--- /dev/null
+++ b/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()
diff --git a/tools/test.py b/tools/test.py
index 8da13b01a..246b094b7 100755
--- a/tools/test.py
+++ b/tools/test.py
@@ -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)