mirror of
https://github.com/denoland/deno.git
synced 2024-11-21 15:04:11 -05:00
fix(node): support tty.hasColors()
and tty.getColorDepth()
(#24619)
This PR adds support for [`tty.WriteStream.prototype.hasColors()`](https://nodejs.org/api/tty.html#writestreamhascolorscount-env) and [`tty.WriteStream.prototype.getColorDepth()`](https://nodejs.org/api/tty.html#writestreamgetcolordepthenv). I couldn't find any usage on GitHub which passes parameters to it. Therefore I've skipped adding support for the `env` parameter to keep our snapshot size small. Based on https://github.com/denoland/deno_terminal/pull/3 Fixes https://github.com/denoland/deno/issues/24616
This commit is contained in:
parent
76b8ecbb6d
commit
ee2e693340
7 changed files with 70 additions and 7 deletions
22
Cargo.lock
generated
22
Cargo.lock
generated
|
@ -729,7 +729,7 @@ dependencies = [
|
||||||
"deno_core",
|
"deno_core",
|
||||||
"deno_fetch",
|
"deno_fetch",
|
||||||
"deno_lockfile",
|
"deno_lockfile",
|
||||||
"deno_terminal",
|
"deno_terminal 0.2.0",
|
||||||
"deno_tls",
|
"deno_tls",
|
||||||
"fastwebsockets",
|
"fastwebsockets",
|
||||||
"file_test_runner",
|
"file_test_runner",
|
||||||
|
@ -1134,7 +1134,7 @@ dependencies = [
|
||||||
"deno_runtime",
|
"deno_runtime",
|
||||||
"deno_semver",
|
"deno_semver",
|
||||||
"deno_task_shell",
|
"deno_task_shell",
|
||||||
"deno_terminal",
|
"deno_terminal 0.2.0",
|
||||||
"dissimilar",
|
"dissimilar",
|
||||||
"dotenvy",
|
"dotenvy",
|
||||||
"dprint-plugin-json",
|
"dprint-plugin-json",
|
||||||
|
@ -1216,7 +1216,7 @@ dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"base64 0.21.7",
|
"base64 0.21.7",
|
||||||
"deno_media_type",
|
"deno_media_type",
|
||||||
"deno_terminal",
|
"deno_terminal 0.1.1",
|
||||||
"dprint-swc-ext",
|
"dprint-swc-ext",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"percent-encoding",
|
"percent-encoding",
|
||||||
|
@ -1836,7 +1836,7 @@ name = "deno_permissions"
|
||||||
version = "0.21.0"
|
version = "0.21.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"deno_core",
|
"deno_core",
|
||||||
"deno_terminal",
|
"deno_terminal 0.2.0",
|
||||||
"fqdn",
|
"fqdn",
|
||||||
"libc",
|
"libc",
|
||||||
"log",
|
"log",
|
||||||
|
@ -1868,7 +1868,7 @@ dependencies = [
|
||||||
"deno_net",
|
"deno_net",
|
||||||
"deno_node",
|
"deno_node",
|
||||||
"deno_permissions",
|
"deno_permissions",
|
||||||
"deno_terminal",
|
"deno_terminal 0.2.0",
|
||||||
"deno_tls",
|
"deno_tls",
|
||||||
"deno_url",
|
"deno_url",
|
||||||
"deno_web",
|
"deno_web",
|
||||||
|
@ -1948,6 +1948,16 @@ dependencies = [
|
||||||
"termcolor",
|
"termcolor",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "deno_terminal"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "daef12499e89ee99e51ad6000a91f600d3937fb028ad4918af76810c5bc9e0d5"
|
||||||
|
dependencies = [
|
||||||
|
"once_cell",
|
||||||
|
"termcolor",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "deno_tls"
|
name = "deno_tls"
|
||||||
version = "0.148.0"
|
version = "0.148.0"
|
||||||
|
@ -2734,7 +2744,7 @@ checksum = "05b23dcc1b671771c6f59fdace6da685735c925f859733e8fd07fba6cae6462a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"crossbeam-channel",
|
"crossbeam-channel",
|
||||||
"deno_terminal",
|
"deno_terminal 0.1.1",
|
||||||
"parking_lot 0.12.3",
|
"parking_lot 0.12.3",
|
||||||
"regex",
|
"regex",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
|
|
|
@ -51,7 +51,7 @@ deno_lockfile = "0.20.0"
|
||||||
deno_media_type = { version = "0.1.4", features = ["module_specifier"] }
|
deno_media_type = { version = "0.1.4", features = ["module_specifier"] }
|
||||||
deno_permissions = { version = "0.21.0", path = "./runtime/permissions" }
|
deno_permissions = { version = "0.21.0", path = "./runtime/permissions" }
|
||||||
deno_runtime = { version = "0.169.0", path = "./runtime" }
|
deno_runtime = { version = "0.169.0", path = "./runtime" }
|
||||||
deno_terminal = "0.1.1"
|
deno_terminal = "0.2.0"
|
||||||
napi_sym = { version = "0.91.0", path = "./cli/napi/sym" }
|
napi_sym = { version = "0.91.0", path = "./cli/napi/sym" }
|
||||||
test_util = { package = "test_server", path = "./tests/util/server" }
|
test_util = { package = "test_server", path = "./tests/util/server" }
|
||||||
|
|
||||||
|
|
|
@ -571,6 +571,7 @@ impl CliMainWorkerFactory {
|
||||||
no_color: !colors::use_color(),
|
no_color: !colors::use_color(),
|
||||||
is_stdout_tty: deno_terminal::is_stdout_tty(),
|
is_stdout_tty: deno_terminal::is_stdout_tty(),
|
||||||
is_stderr_tty: deno_terminal::is_stderr_tty(),
|
is_stderr_tty: deno_terminal::is_stderr_tty(),
|
||||||
|
color_level: colors::get_color_level(),
|
||||||
unstable: shared.options.unstable,
|
unstable: shared.options.unstable,
|
||||||
unstable_features,
|
unstable_features,
|
||||||
user_agent: version::get_user_agent().to_string(),
|
user_agent: version::get_user_agent().to_string(),
|
||||||
|
@ -773,6 +774,7 @@ fn create_web_worker_callback(
|
||||||
locale: deno_core::v8::icu::get_language_tag(),
|
locale: deno_core::v8::icu::get_language_tag(),
|
||||||
location: Some(args.main_module.clone()),
|
location: Some(args.main_module.clone()),
|
||||||
no_color: !colors::use_color(),
|
no_color: !colors::use_color(),
|
||||||
|
color_level: colors::get_color_level(),
|
||||||
is_stdout_tty: deno_terminal::is_stdout_tty(),
|
is_stdout_tty: deno_terminal::is_stdout_tty(),
|
||||||
is_stderr_tty: deno_terminal::is_stderr_tty(),
|
is_stderr_tty: deno_terminal::is_stderr_tty(),
|
||||||
unstable: shared.options.unstable,
|
unstable: shared.options.unstable,
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||||
|
|
||||||
|
import { op_bootstrap_color_depth } from "ext:core/ops";
|
||||||
import { core, primordials } from "ext:core/mod.js";
|
import { core, primordials } from "ext:core/mod.js";
|
||||||
const {
|
const {
|
||||||
Error,
|
Error,
|
||||||
|
@ -105,6 +106,32 @@ export class WriteStream extends Socket {
|
||||||
this.rows = rows;
|
this.rows = rows;
|
||||||
this.isTTY = true;
|
this.isTTY = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {number | Record<string, string>} [count]
|
||||||
|
* @param {Record<string, string>} [env]
|
||||||
|
* @returns {boolean}
|
||||||
|
*/
|
||||||
|
hasColors(count, env) {
|
||||||
|
if (env === undefined && typeof count === "object") {
|
||||||
|
env = count;
|
||||||
|
count = 16;
|
||||||
|
}
|
||||||
|
|
||||||
|
const depth = this.getColorDepth(env);
|
||||||
|
return count <= 2 ** depth;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {Record<string, string} [env]
|
||||||
|
* @returns {1 | 4 | 8 | 24}
|
||||||
|
*/
|
||||||
|
getColorDepth(_env) {
|
||||||
|
// TODO(@marvinhagemeister): Ignore env parameter.
|
||||||
|
// Haven't seen it used anywhere, seems more done
|
||||||
|
// to make testing easier in Node
|
||||||
|
return op_bootstrap_color_depth();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export { isatty };
|
export { isatty };
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
use deno_core::op2;
|
use deno_core::op2;
|
||||||
use deno_core::OpState;
|
use deno_core::OpState;
|
||||||
|
use deno_terminal::colors::ColorLevel;
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
|
|
||||||
use crate::BootstrapOptions;
|
use crate::BootstrapOptions;
|
||||||
|
@ -16,6 +17,7 @@ deno_core::extension!(
|
||||||
op_bootstrap_language,
|
op_bootstrap_language,
|
||||||
op_bootstrap_log_level,
|
op_bootstrap_log_level,
|
||||||
op_bootstrap_no_color,
|
op_bootstrap_no_color,
|
||||||
|
op_bootstrap_color_depth,
|
||||||
op_bootstrap_is_stdout_tty,
|
op_bootstrap_is_stdout_tty,
|
||||||
op_bootstrap_is_stderr_tty,
|
op_bootstrap_is_stderr_tty,
|
||||||
op_bootstrap_unstable_args,
|
op_bootstrap_unstable_args,
|
||||||
|
@ -126,6 +128,17 @@ pub fn op_bootstrap_no_color(state: &mut OpState) -> bool {
|
||||||
options.no_color
|
options.no_color
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[op2(fast)]
|
||||||
|
pub fn op_bootstrap_color_depth(state: &mut OpState) -> i32 {
|
||||||
|
let options = state.borrow::<BootstrapOptions>();
|
||||||
|
match options.color_level {
|
||||||
|
ColorLevel::None => 1,
|
||||||
|
ColorLevel::Ansi => 4,
|
||||||
|
ColorLevel::Ansi256 => 8,
|
||||||
|
ColorLevel::TrueColor => 24,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[op2(fast)]
|
#[op2(fast)]
|
||||||
pub fn op_bootstrap_is_stdout_tty(state: &mut OpState) -> bool {
|
pub fn op_bootstrap_is_stdout_tty(state: &mut OpState) -> bool {
|
||||||
let options = state.borrow::<BootstrapOptions>();
|
let options = state.borrow::<BootstrapOptions>();
|
||||||
|
|
|
@ -77,6 +77,7 @@ pub struct BootstrapOptions {
|
||||||
pub no_color: bool,
|
pub no_color: bool,
|
||||||
pub is_stdout_tty: bool,
|
pub is_stdout_tty: bool,
|
||||||
pub is_stderr_tty: bool,
|
pub is_stderr_tty: bool,
|
||||||
|
pub color_level: deno_terminal::colors::ColorLevel,
|
||||||
// --unstable flag, deprecated
|
// --unstable flag, deprecated
|
||||||
pub unstable: bool,
|
pub unstable: bool,
|
||||||
// --unstable-* flags
|
// --unstable-* flags
|
||||||
|
@ -111,6 +112,7 @@ impl Default for BootstrapOptions {
|
||||||
no_color: !colors::use_color(),
|
no_color: !colors::use_color(),
|
||||||
is_stdout_tty: deno_terminal::is_stdout_tty(),
|
is_stdout_tty: deno_terminal::is_stdout_tty(),
|
||||||
is_stderr_tty: deno_terminal::is_stderr_tty(),
|
is_stderr_tty: deno_terminal::is_stderr_tty(),
|
||||||
|
color_level: colors::get_color_level(),
|
||||||
enable_op_summary_metrics: Default::default(),
|
enable_op_summary_metrics: Default::default(),
|
||||||
enable_testing_features: Default::default(),
|
enable_testing_features: Default::default(),
|
||||||
log_level: Default::default(),
|
log_level: Default::default(),
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
import { assert } from "@std/assert/mod.ts";
|
import { assert } from "@std/assert/mod.ts";
|
||||||
import { isatty } from "node:tty";
|
import { isatty } from "node:tty";
|
||||||
|
import tty from "node:tty";
|
||||||
import process from "node:process";
|
import process from "node:process";
|
||||||
|
|
||||||
Deno.test("[node/tty isatty] returns true when fd is a tty, false otherwise", () => {
|
Deno.test("[node/tty isatty] returns true when fd is a tty, false otherwise", () => {
|
||||||
|
@ -34,3 +35,11 @@ Deno.test("[node/tty WriteStream.isTTY] returns true when fd is a tty", () => {
|
||||||
assert(Deno.stdin.isTerminal() === process.stdin.isTTY);
|
assert(Deno.stdin.isTerminal() === process.stdin.isTTY);
|
||||||
assert(Deno.stdout.isTerminal() === process.stdout.isTTY);
|
assert(Deno.stdout.isTerminal() === process.stdout.isTTY);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Deno.test("[node/tty WriteStream.hasColors] returns true when colors are supported", () => {
|
||||||
|
assert(tty.WriteStream.prototype.hasColors() === !Deno.noColor);
|
||||||
|
});
|
||||||
|
|
||||||
|
Deno.test("[node/tty WriteStream.getColorDepth] returns current terminal color depth", () => {
|
||||||
|
assert([1, 4, 8, 24].includes(tty.WriteStream.prototype.getColorDepth()));
|
||||||
|
});
|
||||||
|
|
Loading…
Reference in a new issue