Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

util: support array of formats in util.styleText #52040

Merged
merged 1 commit into from Mar 15, 2024

Conversation

marco-ippolito
Copy link
Member

Fixes: #52035

@nodejs-github-bot nodejs-github-bot added needs-ci PRs that need a full CI run. util Issues and PRs related to the built-in util module. labels Mar 11, 2024
@marco-ippolito marco-ippolito changed the title util: support array of formats in util.styelText util: support array of formats in util.styleText Mar 11, 2024
@atlowChemi atlowChemi added the request-ci Add this label to start a Jenkins CI on a PR. label Mar 11, 2024
@rauschma
Copy link

Looking at the code:

if (ArrayIsArray(format) && format.length > 0) {

What happens if the Array is empty? Maybe add a unit test for that.

@marco-ippolito
Copy link
Member Author

Looking at the code:

if (ArrayIsArray(format) && format.length > 0) {

What happens if the Array is empty? Maybe add a unit test for that.

it's already present before:

@github-actions github-actions bot removed the request-ci Add this label to start a Jenkins CI on a PR. label Mar 11, 2024
@nodejs-github-bot
Copy link
Collaborator

@marco-ippolito
Copy link
Member Author

I'm only not sure of the order in which we should add/remove styles:

For:

util.styleText(['red', 'bold'], 'test')

\u001b[31m: color to red.
\u001b[1m: style to bold.
test: The actual text content.
\u001b[39m: resets color.
\u001b[22m: removes bold.

OR

\u001b[1m: style to bold.
\u001b[31m: color to red.
test: The actual text content.
\u001b[39m: resets color.
\u001b[22m: removes bold.

Probably second one is more correct?

@rauschma
Copy link

I was asking because of this (I don’t know if that is intended or not):

if (ArrayIsArray(format) && format.length > 0) {
  // ···
  return `${formatCodes}${text}${append}`;
}
// ❌ `format` might be the empty Array here
const formatCodes = inspect.colors[format];
if (formatCodes == null) {
  validateOneOf(format, 'format', ObjectKeys(inspect.colors));
  // ···
}

@marco-ippolito
Copy link
Member Author

marco-ippolito commented Mar 11, 2024

I was asking because of this (I don’t know if that is intended or not):

if (ArrayIsArray(format) && format.length > 0) {
  // ···
  return `${formatCodes}${text}${append}`;
}
// ❌ `format` might be the empty Array here
const formatCodes = inspect.colors[format];
if (formatCodes == null) {
  validateOneOf(format, 'format', ObjectKeys(inspect.colors));
  // ···
}

If the array is empty it will throw ERR_INVALID_ARG_VALUE, it was already covered before my implementation and test

@rauschma
Copy link

rauschma commented Mar 11, 2024

Probably second one is more correct?

I’d say the following two invocations should produce the same result:

util.styleText('bold', util.styleText('red', 'Bold and red!'))
util.styleText(['bold', 'red'], 'Bold and red!')

@marco-ippolito
Copy link
Member Author

marco-ippolito commented Mar 11, 2024

Probably second one is more correct?

I’d say the following two invocations should produce the same result:

util.styleText('bold', util.styleText('red', 'Bold and red!')),
util.styleText(['bold', 'red'], 'Bold and red!'),

agreed, added a test to verify

@rauschma
Copy link

Another option is that an empty Array simply does nothing. Use case:

const styles = [];
if (warning) {
  styles.push('red');
}
console.log(util.styleText(styles, message));

@marco-ippolito marco-ippolito force-pushed the feat/text-style-array branch 2 times, most recently from e79791f to 6b37f31 Compare March 11, 2024 12:36
lib/util.js Outdated Show resolved Hide resolved
@targos targos added the semver-minor PRs that contain new features and should be released in the next minor version. label Mar 11, 2024
@marco-ippolito marco-ippolito added the request-ci Add this label to start a Jenkins CI on a PR. label Mar 11, 2024
@github-actions github-actions bot removed the request-ci Add this label to start a Jenkins CI on a PR. label Mar 11, 2024
@nodejs-github-bot
Copy link
Collaborator

@IlyasShabi
Copy link
Contributor

LGTM

@rauschma
Copy link

Just in case: You can chain multiple codes via ; – which saves you a few characters in the Array case. But that may be too much effort for something that’s less frequently used.

This could look as follows (code may contain bugs – I haven’t tested it and am a bit tired):

/**
 * @param {number[]} codes
 * @returns {string}
 */
function escapeStyleCodes(codes) {
  return `\x1B[` + codes.join(';') + `m`;
}

/**
 * @param {string | string[]} format
 * @param {string} text
 * @returns {string}
 */
function styleText(format, text) {
  validateString(text, 'text');
  if (ArrayIsArray(format)) {
    const startCodes = [];
    const endCodes = [];
    for (const key of format) {
      const formatCodes = inspect.colors[key];
      if (formatCodes == null) {
        validateOneOf(key, 'format', ObjectKeys(inspect.colors));
      }
      startCodes.push(formatCodes[0]);
      endCodes.unshift(formatCodes[1]);
    }
    return escapeStyleCodes(startCodes) + text + escapeStyleCodes(endCodes);
  }

  const formatCodes = inspect.colors[format];
  if (formatCodes == null) {
    validateOneOf(format, 'format', ObjectKeys(inspect.colors));
  }
  return escapeStyleCodes([formatCodes[0]]) + text + escapeStyleCodes([formatCodes[1]]);
}

lib/util.js Show resolved Hide resolved
@nodejs-github-bot
Copy link
Collaborator

@nodejs-github-bot
Copy link
Collaborator

@nodejs-github-bot
Copy link
Collaborator

@nodejs-github-bot
Copy link
Collaborator

@atlowChemi atlowChemi added the author ready PRs that have at least one approval, no pending requests for changes, and a CI started. label Mar 12, 2024
@marco-ippolito marco-ippolito added the commit-queue Add this label to land a pull request using GitHub Actions. label Mar 15, 2024
@nodejs-github-bot nodejs-github-bot removed the commit-queue Add this label to land a pull request using GitHub Actions. label Mar 15, 2024
@nodejs-github-bot nodejs-github-bot merged commit 9a1e01c into nodejs:main Mar 15, 2024
58 checks passed
@nodejs-github-bot
Copy link
Collaborator

Landed in 9a1e01c

rdw-msft pushed a commit to rdw-msft/node that referenced this pull request Mar 26, 2024
PR-URL: nodejs#52040
Fixes: nodejs#52035
Reviewed-By: Chemi Atlow <chemi@atlow.co.il>
Reviewed-By: Paolo Insogna <paolo@cowtech.it>
marco-ippolito added a commit that referenced this pull request May 2, 2024
PR-URL: #52040
Fixes: #52035
Reviewed-By: Chemi Atlow <chemi@atlow.co.il>
Reviewed-By: Paolo Insogna <paolo@cowtech.it>
marco-ippolito added a commit that referenced this pull request May 2, 2024
Notable changes:

benchmark:
  * add AbortSignal.abort benchmarks (Raz Luvaton) #52408
buffer:
  * improve `base64` and `base64url` performance (Yagiz Nizipli) #52428
crypto:
  * deprecate implicitly shortened GCM tags (Tobias Nießen) #52345
deps:
  * (SEMVER-MINOR) update simdutf to 5.0.0 (Daniel Lemire) #52138
  * (SEMVER-MINOR) update undici to 6.3.0 (Node.js GitHub Bot) #51462
  * (SEMVER-MINOR) update undici to 6.2.1 (Node.js GitHub Bot) #51278
dns:
  * (SEMVER-MINOR) add order option and support ipv6first (Paolo Insogna) #52492
doc:
  * update release gpg keyserver (marco-ippolito) #52257
  * add release key for marco-ippolito (marco-ippolito) #52257
  * add UlisesGascon as a collaborator (Ulises Gascón) #51991
  * (SEMVER-MINOR) deprecate fs.Stats public constructor (Marco Ippolito) #51879
events,doc:
  * mark CustomEvent as stable (Daeyeon Jeong) #52618
fs:
  * add stacktrace to fs/promises (翠 / green) #49849
lib, url:
  * (SEMVER-MINOR) add a `windows` option to path parsing (Aviv Keller) #52509
net:
  * (SEMVER-MINOR) add CLI option for autoSelectFamilyAttemptTimeout (Paolo Insogna) #52474
report:
  * (SEMVER-MINOR) add `--report-exclude-network` option (Ethan Arrowood) #51645
src:
  * (SEMVER-MINOR) add `string_view` overload to snapshot FromBlob (Anna Henningsen) #52595
  * (SEMVER-MINOR) add C++ ProcessEmitWarningSync() (Joyee Cheung) #51977
  * (SEMVER-MINOR) add uv_get_available_memory to report and process (theanarkh) #52023
  * (SEMVER-MINOR) preload function for Environment (Cheng Zhao) #51539
stream:
  * (SEMVER-MINOR) support typed arrays (IlyasShabi) #51866
test_runner:
  * (SEMVER-MINOR) add suite() (Colin Ihrig) #52127
  * (SEMVER-MINOR) support forced exit (Colin Ihrig) #52038
  * (SEMVER-MINOR) add `test:complete` event to reflect execution order (Moshe Atlow) #51909
util:
  * (SEMVER-MINOR) support array of formats in util.styleText (Marco Ippolito) #52040
v8:
  * (SEMVER-MINOR) implement v8.queryObjects() for memory leak regression testing (Joyee Cheung) #51927
watch:
  * mark as stable (Moshe Atlow) #52074

PR-URL: TODO
marco-ippolito added a commit that referenced this pull request May 2, 2024
Notable changes:

benchmark:
  * add AbortSignal.abort benchmarks (Raz Luvaton) #52408
buffer:
  * improve `base64` and `base64url` performance (Yagiz Nizipli) #52428
crypto:
  * deprecate implicitly shortened GCM tags (Tobias Nießen) #52345
deps:
  * (SEMVER-MINOR) update simdutf to 5.0.0 (Daniel Lemire) #52138
  * (SEMVER-MINOR) update undici to 6.3.0 (Node.js GitHub Bot) #51462
  * (SEMVER-MINOR) update undici to 6.2.1 (Node.js GitHub Bot) #51278
dns:
  * (SEMVER-MINOR) add order option and support ipv6first (Paolo Insogna) #52492
doc:
  * update release gpg keyserver (marco-ippolito) #52257
  * add release key for marco-ippolito (marco-ippolito) #52257
  * add UlisesGascon as a collaborator (Ulises Gascón) #51991
  * (SEMVER-MINOR) deprecate fs.Stats public constructor (Marco Ippolito) #51879
events,doc:
  * mark CustomEvent as stable (Daeyeon Jeong) #52618
fs:
  * add stacktrace to fs/promises (翠 / green) #49849
lib, url:
  * (SEMVER-MINOR) add a `windows` option to path parsing (Aviv Keller) #52509
net:
  * (SEMVER-MINOR) add CLI option for autoSelectFamilyAttemptTimeout (Paolo Insogna) #52474
report:
  * (SEMVER-MINOR) add `--report-exclude-network` option (Ethan Arrowood) #51645
src:
  * (SEMVER-MINOR) add `string_view` overload to snapshot FromBlob (Anna Henningsen) #52595
  * (SEMVER-MINOR) add C++ ProcessEmitWarningSync() (Joyee Cheung) #51977
  * (SEMVER-MINOR) add uv_get_available_memory to report and process (theanarkh) #52023
  * (SEMVER-MINOR) preload function for Environment (Cheng Zhao) #51539
stream:
  * (SEMVER-MINOR) support typed arrays (IlyasShabi) #51866
test_runner:
  * (SEMVER-MINOR) add suite() (Colin Ihrig) #52127
  * (SEMVER-MINOR) support forced exit (Colin Ihrig) #52038
  * (SEMVER-MINOR) add `test:complete` event to reflect execution order (Moshe Atlow) #51909
util:
  * (SEMVER-MINOR) support array of formats in util.styleText (Marco Ippolito) #52040
v8:
  * (SEMVER-MINOR) implement v8.queryObjects() for memory leak regression testing (Joyee Cheung) #51927
watch:
  * mark as stable (Moshe Atlow) #52074

PR-URL: TODO
marco-ippolito added a commit that referenced this pull request May 2, 2024
Notable changes:

benchmark:
  * add AbortSignal.abort benchmarks (Raz Luvaton) #52408
buffer:
  * improve `base64` and `base64url` performance (Yagiz Nizipli) #52428
crypto:
  * deprecate implicitly shortened GCM tags (Tobias Nießen) #52345
deps:
  * (SEMVER-MINOR) update simdutf to 5.0.0 (Daniel Lemire) #52138
  * (SEMVER-MINOR) update undici to 6.3.0 (Node.js GitHub Bot) #51462
  * (SEMVER-MINOR) update undici to 6.2.1 (Node.js GitHub Bot) #51278
dns:
  * (SEMVER-MINOR) add order option and support ipv6first (Paolo Insogna) #52492
doc:
  * update release gpg keyserver (marco-ippolito) #52257
  * add release key for marco-ippolito (marco-ippolito) #52257
  * add UlisesGascon as a collaborator (Ulises Gascón) #51991
  * (SEMVER-MINOR) deprecate fs.Stats public constructor (Marco Ippolito) #51879
events,doc:
  * mark CustomEvent as stable (Daeyeon Jeong) #52618
fs:
  * add stacktrace to fs/promises (翠 / green) #49849
lib, url:
  * (SEMVER-MINOR) add a `windows` option to path parsing (Aviv Keller) #52509
net:
  * (SEMVER-MINOR) add CLI option for autoSelectFamilyAttemptTimeout (Paolo Insogna) #52474
report:
  * (SEMVER-MINOR) add `--report-exclude-network` option (Ethan Arrowood) #51645
src:
  * (SEMVER-MINOR) add `string_view` overload to snapshot FromBlob (Anna Henningsen) #52595
  * (SEMVER-MINOR) add C++ ProcessEmitWarningSync() (Joyee Cheung) #51977
  * (SEMVER-MINOR) add uv_get_available_memory to report and process (theanarkh) #52023
  * (SEMVER-MINOR) preload function for Environment (Cheng Zhao) #51539
stream:
  * (SEMVER-MINOR) support typed arrays (IlyasShabi) #51866
test_runner:
  * (SEMVER-MINOR) add suite() (Colin Ihrig) #52127
  * (SEMVER-MINOR) support forced exit (Colin Ihrig) #52038
  * (SEMVER-MINOR) add `test:complete` event to reflect execution order (Moshe Atlow) #51909
util:
  * (SEMVER-MINOR) support array of formats in util.styleText (Marco Ippolito) #52040
v8:
  * (SEMVER-MINOR) implement v8.queryObjects() for memory leak regression testing (Joyee Cheung) #51927
watch:
  * mark as stable (Moshe Atlow) #52074

PR-URL: #52793
marco-ippolito added a commit that referenced this pull request May 2, 2024
Notable changes:

benchmark:
  * add AbortSignal.abort benchmarks (Raz Luvaton) #52408
buffer:
  * improve `base64` and `base64url` performance (Yagiz Nizipli) #52428
crypto:
  * deprecate implicitly shortened GCM tags (Tobias Nießen) #52345
deps:
  * (SEMVER-MINOR) update simdutf to 5.0.0 (Daniel Lemire) #52138
  * (SEMVER-MINOR) update undici to 6.3.0 (Node.js GitHub Bot) #51462
  * (SEMVER-MINOR) update undici to 6.2.1 (Node.js GitHub Bot) #51278
dns:
  * (SEMVER-MINOR) add order option and support ipv6first (Paolo Insogna) #52492
doc:
  * update release gpg keyserver (marco-ippolito) #52257
  * add release key for marco-ippolito (marco-ippolito) #52257
  * add UlisesGascon as a collaborator (Ulises Gascón) #51991
  * (SEMVER-MINOR) deprecate fs.Stats public constructor (Marco Ippolito) #51879
events,doc:
  * mark CustomEvent as stable (Daeyeon Jeong) #52618
fs:
  * add stacktrace to fs/promises (翠 / green) #49849
lib, url:
  * (SEMVER-MINOR) add a `windows` option to path parsing (Aviv Keller) #52509
net:
  * (SEMVER-MINOR) add CLI option for autoSelectFamilyAttemptTimeout (Paolo Insogna) #52474
report:
  * (SEMVER-MINOR) add `--report-exclude-network` option (Ethan Arrowood) #51645
src:
  * (SEMVER-MINOR) add `string_view` overload to snapshot FromBlob (Anna Henningsen) #52595
  * (SEMVER-MINOR) add C++ ProcessEmitWarningSync() (Joyee Cheung) #51977
  * (SEMVER-MINOR) add uv_get_available_memory to report and process (theanarkh) #52023
  * (SEMVER-MINOR) preload function for Environment (Cheng Zhao) #51539
stream:
  * (SEMVER-MINOR) support typed arrays (IlyasShabi) #51866
test_runner:
  * (SEMVER-MINOR) add suite() (Colin Ihrig) #52127
  * (SEMVER-MINOR) support forced exit (Colin Ihrig) #52038
  * (SEMVER-MINOR) add `test:complete` event to reflect execution order (Moshe Atlow) #51909
util:
  * (SEMVER-MINOR) support array of formats in util.styleText (Marco Ippolito) #52040
v8:
  * (SEMVER-MINOR) implement v8.queryObjects() for memory leak regression testing (Joyee Cheung) #51927
watch:
  * mark as stable (Moshe Atlow) #52074

PR-URL: #52793
marco-ippolito added a commit that referenced this pull request May 3, 2024
PR-URL: #52040
Fixes: #52035
Reviewed-By: Chemi Atlow <chemi@atlow.co.il>
Reviewed-By: Paolo Insogna <paolo@cowtech.it>
marco-ippolito added a commit that referenced this pull request May 3, 2024
Notable changes:

benchmark:
  * add AbortSignal.abort benchmarks (Raz Luvaton) #52408
buffer:
  * improve `base64` and `base64url` performance (Yagiz Nizipli) #52428
crypto:
  * deprecate implicitly shortened GCM tags (Tobias Nießen) #52345
deps:
  * (SEMVER-MINOR) update simdutf to 5.0.0 (Daniel Lemire) #52138
  * (SEMVER-MINOR) update undici to 6.3.0 (Node.js GitHub Bot) #51462
  * (SEMVER-MINOR) update undici to 6.2.1 (Node.js GitHub Bot) #51278
dns:
  * (SEMVER-MINOR) add order option and support ipv6first (Paolo Insogna) #52492
doc:
  * update release gpg keyserver (marco-ippolito) #52257
  * add release key for marco-ippolito (marco-ippolito) #52257
  * add UlisesGascon as a collaborator (Ulises Gascón) #51991
  * (SEMVER-MINOR) deprecate fs.Stats public constructor (Marco Ippolito) #51879
events,doc:
  * mark CustomEvent as stable (Daeyeon Jeong) #52618
fs:
  * add stacktrace to fs/promises (翠 / green) #49849
lib, url:
  * (SEMVER-MINOR) add a `windows` option to path parsing (Aviv Keller) #52509
net:
  * (SEMVER-MINOR) add CLI option for autoSelectFamilyAttemptTimeout (Paolo Insogna) #52474
report:
  * (SEMVER-MINOR) add `--report-exclude-network` option (Ethan Arrowood) #51645
src:
  * (SEMVER-MINOR) add `string_view` overload to snapshot FromBlob (Anna Henningsen) #52595
  * (SEMVER-MINOR) add C++ ProcessEmitWarningSync() (Joyee Cheung) #51977
  * (SEMVER-MINOR) add uv_get_available_memory to report and process (theanarkh) #52023
  * (SEMVER-MINOR) preload function for Environment (Cheng Zhao) #51539
stream:
  * (SEMVER-MINOR) support typed arrays (IlyasShabi) #51866
test_runner:
  * (SEMVER-MINOR) add suite() (Colin Ihrig) #52127
  * (SEMVER-MINOR) add `test:complete` event to reflect execution order (Moshe Atlow) #51909
util:
  * (SEMVER-MINOR) support array of formats in util.styleText (Marco Ippolito) #52040
v8:
  * (SEMVER-MINOR) implement v8.queryObjects() for memory leak regression testing (Joyee Cheung) #51927
watch:
  * mark as stable (Moshe Atlow) #52074

PR-URL: #52793
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
author ready PRs that have at least one approval, no pending requests for changes, and a CI started. needs-ci PRs that need a full CI run. semver-minor PRs that contain new features and should be released in the next minor version. util Issues and PRs related to the built-in util module.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

util.styleText(): Combining multiple styles in a single string?
10 participants