Breaking change 53863: Add lineTerminator field to Stdout

52 views
Skip to first unread message

Brian Quinlan

unread,
Oct 25, 2023, 7:09:09 PM10/25/23
to anno...@dartlang.org
See discussion on breaking change: https://github.com/dart-lang/sdk/issues/53863

Change Intent

To make it possible for stdout/stderr to correctly output Windows line endings ('\r\n') when write/writeln by adding a new field:

class _StdSink implements IOSink {
  ...
  /// The line ending used by [writeln] and to translate `"\n"` written by
  /// the [write], [writeln] and [writeAll] and [writeCharCode] methods.
  ///
  /// If a string containing `"\n"`s is written using one of the above
  /// "write" methods, then the embedded `"\n"`s are translated to the value
  /// set in `lineTerminator`. If the string contains Windows line endings
  /// (`"\r\n"`) then they are not translated. Carriage returns (`"\r`) are
  /// not translated.
  ///
  /// If `lineTerminator` is `"\n"` then the written strings are not modified.
  //
  /// Setting `lineTerminator` to [Platform.lineTerminator] will result in
  /// "write" methods outputting the line endings for the platform:
  ///
  /// ```dart
  /// stdout.lineTerminator = Platform.lineTerminator;
  /// stderr.lineTerminator = Platform.lineTerminator;
  /// ```
  ///
  /// The value of `lineTerminator` has no effect on byte-oriented methods
  /// such as [add].
  ///
  /// The value of `lineTerminator` does not effect the output of the [print]
  /// function.
  /// 
  /// Throws [ArgumentError] if set to a value other than `"\n"` or `"\r\n"`.
  set lineTerminator(String eol);
  ...
}

The default value of lineTerminator will be "\n" so the output will not change for existing Dart code.

Justification

To write correct terminal applications on Windows, developers currently have to write awkward code like:

stdout.write("Hello World" + Platform.lineTerminator);

Impact

Any class that implements Stdout without using Mock/Mock or overriding noSuchMethod will break.

There are 100s of files on github that implement Stdout but most them that I looked at use Fake/Mock or override noSuchMethod.

A few do not:
https://github.com/onepub-dev/minion/blob/57cda065a6fc489839d0cbf80d15f6d08432e614/lib/src/stdout.dart#L7
https://github.com/tvolkert/universal_io/blob/02f99955f2dfbc94269ddfa8d326a1bbe7787e8e/lib/src/driver_base/base_std_out.dart#L21
https://github.com/filiph/linkcheck/blob/8ab5f5b516701f98c18cb2f16a73e5f93ebf7f12/test/e2e_test.dart#L218

Mitigation

Developers will have to add:

+   String lineEnding;

to their Stdout implementations.

Change Timeline

N/A

Associated CLs

Reply all
Reply to author
Forward
0 new messages