secret method

String secret(
  1. String question, {
  2. bool allowEmpty = false,
})

Asks for a secret, with terminal echo disabled while typing.

Echo is restored in a finally so a Ctrl-C mid-answer cannot leave the user's terminal silently unable to display input.

Implementation

String secret(String question, {bool allowEmpty = false}) {
  while (true) {
    stdout.write('${ColorizeLogger.bold('?')} $question ');

    // Echo control is best effort. `stdin.echoMode` throws on anything that
    // is not a real terminal — a pipe, a CI runner, a test harness — and
    // `hasTerminal` does not reliably predict it, so the only way to know is
    // to try. Failing here would hide the abort that actually explains the
    // problem, so the read goes ahead either way.
    bool? hadEcho;
    try {
      hadEcho = stdin.echoMode;
      stdin.echoMode = false;
    } on StdinException {
      _logger.logWarning('cannot hide input here; what you type is visible');
    }

    String answer;
    try {
      answer = _readLine().trim();
    } finally {
      if (hadEcho != null) {
        try {
          stdin.echoMode = hadEcho;
        } on StdinException {
          // Nothing to restore if the terminal went away mid-answer.
        }
      }
      stdout.writeln();
    }

    if (answer.isNotEmpty || allowEmpty) return answer;
    _logger.logWarning('a value is required');
  }
}