1
0
Fork 0
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:
Marvin Hagemeister 2024-07-19 12:39:05 +02:00 committed by GitHub
parent 76b8ecbb6d
commit ee2e693340
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 70 additions and 7 deletions

22
Cargo.lock generated
View file

@ -729,7 +729,7 @@ dependencies = [
"deno_core",
"deno_fetch",
"deno_lockfile",
"deno_terminal",
"deno_terminal 0.2.0",
"deno_tls",
"fastwebsockets",
"file_test_runner",
@ -1134,7 +1134,7 @@ dependencies = [
"deno_runtime",
"deno_semver",
"deno_task_shell",
"deno_terminal",
"deno_terminal 0.2.0",
"dissimilar",
"dotenvy",
"dprint-plugin-json",
@ -1216,7 +1216,7 @@ dependencies = [
"anyhow",
"base64 0.21.7",
"deno_media_type",
"deno_terminal",
"deno_terminal 0.1.1",
"dprint-swc-ext",
"once_cell",
"percent-encoding",
@ -1836,7 +1836,7 @@ name = "deno_permissions"
version = "0.21.0"
dependencies = [
"deno_core",
"deno_terminal",
"deno_terminal 0.2.0",
"fqdn",
"libc",
"log",
@ -1868,7 +1868,7 @@ dependencies = [
"deno_net",
"deno_node",
"deno_permissions",
"deno_terminal",
"deno_terminal 0.2.0",
"deno_tls",
"deno_url",
"deno_web",
@ -1948,6 +1948,16 @@ dependencies = [
"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]]
name = "deno_tls"
version = "0.148.0"
@ -2734,7 +2744,7 @@ checksum = "05b23dcc1b671771c6f59fdace6da685735c925f859733e8fd07fba6cae6462a"
dependencies = [
"anyhow",
"crossbeam-channel",
"deno_terminal",
"deno_terminal 0.1.1",
"parking_lot 0.12.3",
"regex",
"thiserror",

View file

@ -51,7 +51,7 @@ deno_lockfile = "0.20.0"
deno_media_type = { version = "0.1.4", features = ["module_specifier"] }
deno_permissions = { version = "0.21.0", path = "./runtime/permissions" }
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" }
test_util = { package = "test_server", path = "./tests/util/server" }

View file

@ -571,6 +571,7 @@ impl CliMainWorkerFactory {
no_color: !colors::use_color(),
is_stdout_tty: deno_terminal::is_stdout_tty(),
is_stderr_tty: deno_terminal::is_stderr_tty(),
color_level: colors::get_color_level(),
unstable: shared.options.unstable,
unstable_features,
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(),
location: Some(args.main_module.clone()),
no_color: !colors::use_color(),
color_level: colors::get_color_level(),
is_stdout_tty: deno_terminal::is_stdout_tty(),
is_stderr_tty: deno_terminal::is_stderr_tty(),
unstable: shared.options.unstable,

View file

@ -1,5 +1,6 @@
// 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";
const {
Error,
@ -105,6 +106,32 @@ export class WriteStream extends Socket {
this.rows = rows;
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 };

View file

@ -2,6 +2,7 @@
use deno_core::op2;
use deno_core::OpState;
use deno_terminal::colors::ColorLevel;
use serde::Serialize;
use crate::BootstrapOptions;
@ -16,6 +17,7 @@ deno_core::extension!(
op_bootstrap_language,
op_bootstrap_log_level,
op_bootstrap_no_color,
op_bootstrap_color_depth,
op_bootstrap_is_stdout_tty,
op_bootstrap_is_stderr_tty,
op_bootstrap_unstable_args,
@ -126,6 +128,17 @@ pub fn op_bootstrap_no_color(state: &mut OpState) -> bool {
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)]
pub fn op_bootstrap_is_stdout_tty(state: &mut OpState) -> bool {
let options = state.borrow::<BootstrapOptions>();

View file

@ -77,6 +77,7 @@ pub struct BootstrapOptions {
pub no_color: bool,
pub is_stdout_tty: bool,
pub is_stderr_tty: bool,
pub color_level: deno_terminal::colors::ColorLevel,
// --unstable flag, deprecated
pub unstable: bool,
// --unstable-* flags
@ -111,6 +112,7 @@ impl Default for BootstrapOptions {
no_color: !colors::use_color(),
is_stdout_tty: deno_terminal::is_stdout_tty(),
is_stderr_tty: deno_terminal::is_stderr_tty(),
color_level: colors::get_color_level(),
enable_op_summary_metrics: Default::default(),
enable_testing_features: Default::default(),
log_level: Default::default(),

View file

@ -3,6 +3,7 @@
import { assert } from "@std/assert/mod.ts";
import { isatty } from "node:tty";
import tty from "node:tty";
import process from "node:process";
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.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()));
});