Skip to content

Conversation

@lrhn
Copy link
Member

@lrhn lrhn commented Jan 6, 2026

Makes AnsiCode.toString() return AnsiCode.escape, so the code can be embedded in strings directly like "a ${red}red${resetAll} word".
(This is a potentially breaking change, if anyone relies on the exact toString output.
The text does not appear to be designed to be used for anything but debugging.)

Makes AnsiCodeType an enum.
_Potentially a breaking change if anyone is doing an non-exhaustive switch over AnsiCodeType.
This also changes the toString of the enum values from AnsiCode.<name> to AnsiCodeType.<name>.
(There was no reason for the original name.)

Makes the wrapWith use the reset codes for the Ansi style codes used, instead of always using resetAll.
If any color is included (or any custom AnsiCode that has resetAll as reset code), it still uses a single resetAll.
May affect code that combines Ansi codes used directly with wrapWith, if it expects a later wrapWith
to reset more than its own styles.

@lrhn lrhn requested a review from a team as a code owner January 6, 2026 11:25
Makes `AnsiCode.toString()` return `AnsiCode.escape`, so the code
can be embedded in strings directly like `"a ${red}red${resetAll} word"`.

Makes `AnsiCodeType` an `enum`. _May affect code that has an non-exhaustive
switch over `AnsiCodeType`._
This changes the `toString` of the enum values from `AnsiCode.<name>` to
`AnsiCodeType.<name>`.

Makes the `wrapWith` use the reset codes for the Ansi _style_ codes used,
instead of always using `resetAll`. If any color is included, it still uses
`resetAll`.
_May affect code that relied on `wrapWith` resetting more than its own
styles._
@github-actions
Copy link

github-actions bot commented Jan 6, 2026

Package publishing

Package Version Status Publish tag (post-merge)
package:bazel_worker 1.1.5 already published at pub.dev
package:benchmark_harness 2.4.0 already published at pub.dev
package:boolean_selector 2.1.2 already published at pub.dev
package:browser_launcher 1.1.3 already published at pub.dev
package:cli_config 0.2.1-wip WIP (no publish necessary)
package:cli_util 0.5.0-wip WIP (no publish necessary)
package:clock 1.1.3-wip WIP (no publish necessary)
package:code_builder 4.11.1 already published at pub.dev
package:coverage 1.15.0 already published at pub.dev
package:csslib 1.0.2 already published at pub.dev
package:extension_discovery 2.1.0 already published at pub.dev
package:file 7.0.2-wip WIP (no publish necessary)
package:file_testing 3.1.0-wip WIP (no publish necessary)
package:glob 2.1.3 already published at pub.dev
package:graphs 2.3.3-wip WIP (no publish necessary)
package:html 0.15.7-wip WIP (no publish necessary)
package:io 1.1.0-wip WIP (no publish necessary)
package:json_rpc_2 4.1.0-wip WIP (no publish necessary)
package:markdown 7.3.1-wip WIP (no publish necessary)
package:mime 2.1.0-wip WIP (no publish necessary)
package:oauth2 2.0.5 already published at pub.dev
package:package_config 2.3.0-wip WIP (no publish necessary)
package:pool 1.5.2 already published at pub.dev
package:process 5.0.5 already published at pub.dev
package:pub_semver 2.2.0 already published at pub.dev
package:pubspec_parse 1.5.1-wip WIP (no publish necessary)
package:source_map_stack_trace 2.1.3-wip WIP (no publish necessary)
package:source_maps 0.10.14-wip WIP (no publish necessary)
package:source_span 1.10.1 already published at pub.dev
package:sse 4.1.8 already published at pub.dev
package:stack_trace 1.12.2-wip (error) pubspec version (1.12.2-wip) and changelog (1.12.2-dev) don't agree
package:stream_channel 2.1.4 already published at pub.dev
package:stream_transform 2.1.2-wip WIP (no publish necessary)
package:string_scanner 1.4.1 already published at pub.dev
package:term_glyph 1.2.3-wip WIP (no publish necessary)
package:test_reflective_loader 0.5.0 ready to publish test_reflective_loader-v0.5.0
package:timing 1.0.2 already published at pub.dev
package:unified_analytics 8.0.12 ready to publish unified_analytics-v8.0.12
package:watcher 1.2.1 ready to publish watcher-v1.2.1
package:yaml 3.1.3 already published at pub.dev
package:yaml_edit 2.2.3 already published at pub.dev

Documentation at https://github.com/dart-lang/ecosystem/wiki/Publishing-automation.

@github-actions
Copy link

github-actions bot commented Jan 6, 2026

PR Health

License Headers ✔️
// Copyright (c) 2026, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
Files
no missing headers

All source files should start with a license header.

Unrelated files missing license headers
Files
pkgs/bazel_worker/benchmark/benchmark.dart
pkgs/benchmark_harness/integration_test/perf_benchmark_test.dart
pkgs/boolean_selector/example/example.dart
pkgs/clock/lib/clock.dart
pkgs/clock/lib/src/clock.dart
pkgs/clock/lib/src/default.dart
pkgs/clock/lib/src/stopwatch.dart
pkgs/clock/lib/src/utils.dart
pkgs/clock/test/clock_test.dart
pkgs/clock/test/default_test.dart
pkgs/clock/test/stopwatch_test.dart
pkgs/clock/test/utils.dart
pkgs/coverage/lib/src/coverage_options.dart
pkgs/html/example/main.dart
pkgs/html/lib/dom.dart
pkgs/html/lib/dom_parsing.dart
pkgs/html/lib/html_escape.dart
pkgs/html/lib/parser.dart
pkgs/html/lib/src/constants.dart
pkgs/html/lib/src/encoding_parser.dart
pkgs/html/lib/src/html_input_stream.dart
pkgs/html/lib/src/list_proxy.dart
pkgs/html/lib/src/query_selector.dart
pkgs/html/lib/src/token.dart
pkgs/html/lib/src/tokenizer.dart
pkgs/html/lib/src/treebuilder.dart
pkgs/html/lib/src/utils.dart
pkgs/html/test/dom_test.dart
pkgs/html/test/parser_feature_test.dart
pkgs/html/test/parser_test.dart
pkgs/html/test/query_selector_test.dart
pkgs/html/test/selectors/level1_baseline_test.dart
pkgs/html/test/selectors/level1_lib.dart
pkgs/html/test/selectors/selectors.dart
pkgs/html/test/support.dart
pkgs/html/test/tokenizer_test.dart
pkgs/html/test/trie_test.dart
pkgs/html/tool/generate_trie.dart
pkgs/pubspec_parse/test/git_uri_test.dart
pkgs/stack_trace/example/example.dart
pkgs/watcher/test/custom_watcher_factory_test.dart
pkgs/yaml_edit/example/example.dart

This check can be disabled by tagging the PR with skip-license-check.

API leaks ✔️

The following packages contain symbols visible in the public API, but not exported by the library. Export these symbols or remove them from your publicly visible API.

Package Leaked API symbol Leaking sources

This check can be disabled by tagging the PR with skip-leaking-check.

Breaking changes ✔️
Package Change Current Version New Version Needed Version Looking good?
io Non-Breaking 1.0.5 1.1.0-wip 1.1.0 ✔️

This check can be disabled by tagging the PR with skip-breaking-check.

Coverage ✔️
File Coverage
pkgs/io/lib/src/ansi_code.dart 💚 93 % ⬆️ 9 %

This check for test coverage is informational (issues shown here will not fail the PR).

This check can be disabled by tagging the PR with skip-coverage-check.

Changelog Entry ✔️
Package Changed Files

Changes to files need to be accounted for in their respective changelogs.

This check can be disabled by tagging the PR with skip-changelog-check.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces several valuable changes to the ANSI code handling, including making AnsiCodeType an enum, changing AnsiCode.toString() to return the escape sequence for easier string embedding, and refining wrapWith to use specific reset codes for styles. These are great improvements for usability and correctness. The code is well-structured, and the accompanying test changes are thorough. I have one suggestion to simplify the logic for collecting reset codes in wrapWith, which could make the implementation more declarative and easier to read.

Comment on lines +160 to +171
final resets = <AnsiCode>{}; // Include each reset only once.
for (var code in sortedCodes.reversed) {
final resetCode = code.reset!;
if (!identical(resetCode, resetAll)) {
resets.add(resetCode);
} else {
resets
..clear()
..add(resetAll);
break;
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This logic for determining the set of reset codes can be expressed more concisely and declaratively. The current loop is a bit complex. You can achieve the same result by first checking if any code requires a full reset, and then collecting the appropriate reset codes based on that condition.

  final resets = myCodes.any((c) => identical(c.reset, resetAll))
      ? {resetAll}
      : myCodes.map((c) => c.reset!).toSet();

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi Gemini code assist.
That would iterate the codes twice, this only iterates it once.
(I'll admit the code is not built for efficiency, and the list is likely to be very short to begin with, but there is no need to do double work.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant