Repository navigation
Expand file tree
/
Copy pathConsoleService.cs
More file actions
68 lines (54 loc) · 2.59 KB
/
Copy pathConsoleService.cs
File metadata and controls
68 lines (54 loc) · 2.59 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
using System;
using System.Threading;
using System.Threading.Tasks;
using GitCredentialManager.Tty;
using Spectre.Console;
namespace GitCredentialManager;
/// <summary>
/// The user-facing console. Routes output-only messages (diagnostics, QR codes) to
/// standard error, and interactive prompts — which need to read input — to the
/// controlling terminal.
/// </summary>
/// <remarks>
/// Git's stdin/stdout are reserved for the credential protocol, so neither sink may use
/// them. Standard error is always available and capturable, so messages survive even
/// when no terminal is attached; only prompts require a TTY, since only they read input.
/// </remarks>
public interface IConsoleService
{
void WriteInfo(string message);
void WriteWarning(string message);
void WriteError(string message);
void WriteFatal(string message);
void WriteLine(string message);
/// <summary>
/// Prompt the user for a selection on the controlling terminal.
/// </summary>
T ShowPrompt<T>(IPrompt<T> prompt);
/// <summary>
/// Prompt the user for a selection on the controlling terminal.
/// </summary>
Task<T> ShowPromptAsync<T>(IPrompt<T> prompt, CancellationToken ct = default);
}
public class ConsoleService : IConsoleService
{
private readonly Lazy<IAnsiConsole> _ttyConsole;
private readonly Lazy<IAnsiConsole> _stderrConsole;
public ConsoleService(IStandardStreams streams)
: this(AnsiConsoleFactory.CreateForTty, () => AnsiConsoleFactory.CreateForWriter(streams.Error, streams.IsErrorRedirected))
{ }
public ConsoleService(Func<IAnsiConsole> ttyConsoleFunc, Func<IAnsiConsole> stderrConsoleFunc)
{
_ttyConsole = new Lazy<IAnsiConsole>(ttyConsoleFunc);
_stderrConsole = new Lazy<IAnsiConsole>(stderrConsoleFunc);
}
public void WriteInfo(string message) => _stderrConsole.Value.MarkupLine($"[blue]info:[/] {Markup.Escape(message)}");
public void WriteWarning(string message) => _stderrConsole.Value.MarkupLine($"[yellow]warning:[/] {Markup.Escape(message)}");
public void WriteError(string message) => _stderrConsole.Value.MarkupLine($"[red]error:[/] {Markup.Escape(message)}");
public void WriteFatal(string message) => _stderrConsole.Value.MarkupLine($"[red]fatal:[/] {Markup.Escape(message)}");
public void WriteLine(string message) => _stderrConsole.Value.WriteLine(message);
public T ShowPrompt<T>(IPrompt<T> prompt) =>
prompt.Show(_ttyConsole.Value);
public Task<T> ShowPromptAsync<T>(IPrompt<T> prompt, CancellationToken ct = default) =>
prompt.ShowAsync(_ttyConsole.Value, ct);
}